转自:http://blog.chinaunix.net/uid-27105712-id-5612512.html

一、使用背景

先说一下需要用到向量时钟的场景。我们在写数据时候,经常希望数据不要存储在单点。如db1,db2都可以同时提供写服务,并且都存有全量数据。而client不管是写哪一个db都不用担心数据写乱问题。但是现实场景中往往会碰到并行同时修改。导致db1和db2数据不一致。于是乎就有人想出一些解决策略。向量时钟算是其中一种。简单易懂。但是并没有彻底解决冲突问题,现实分布式存储补充了很多额外技巧。

这里反向叙述方式, 介绍向量时钟。先举实际例子让读者有个感性认识,然后再说算法规则。

二、举个例子

向量时钟实际是一组版本号(版本号=逻辑时钟),假设数据需要存放3份,需要3台db存储(用A,B,C表示),那么向量维度就是3,每个db有一个版本号,从0开始,这样就形成了一个向量版本 [A:0, B:0, C:0];
Step 1: 初始状态下,所有机器都是 [A:0, B:0, C:0]

DB_A——> [A:0, B:0, C:0]

DB_B——> [A:0, B:0, C:0]

DB_C——> [A:0, B:0, C:0]

Step 2:  假设现在应用是一个商场,现在录入一个肾6的价格 iphone6 price 5888; 客户端随机选择一个db机器写入。现假设选择了A,数据大概是这样 :
{key=iphone_price; value=5888; vclk=[A:1,B:0,C:0]}

Step 3:  接下来A会把数据同步给BC;于是最终同步结果如下

DB_A——> {key=iphone_price; value=5888; vclk=[ A:1,B:0,C:0]}

DB_B——> {key=iphone_price; value=6888; vclk=[ A:1, B:0,C:0]}

DB_C——> {key=iphone_price; value=5888; vclk=[ A:1,B:0,C:0]}

Step 4:过了分钟,价格出现波动,升值到6888;于是某个业务员更新价格。这时候系统随机选择了B做为写入存储,于是结果看起来是这样:

DB_A——> {key=iphone_price; value=5888; vclk=[A:1,B:0,C:0]}

DB_B——> {key=iphone_price; value=6888; vclk=[A:1,B:1,C:0]}

DB_C——> {key=iphone_price; value=5888; vclk=[A:1,B:0,C:0]}

Step 5:于是B就把更新同步给其他几个存储

DB_A——> {key=iphone_price; value=6888; vclk=[A:1, B:1,C:0]}

DB_B——> {key=iphone_price; value=6888; vclk=[A:1,B:1,C:0]}

DB_C——> {key=iphone_price; value=6888; vclk=[A:1, B:1,C:0]}

到目前为止都是正常同步,下面开始演示一下不正常的情况。

Step 6:价格再次发生波动,变成4000,这次选择C写入:

DB_A——> {key=iphone_price; value=6888; vclk=[A:1, B:1,C:0]}

DB_B——> {key=iphone_price; value=6888; vclk=[A:1,B:1,C:0]}

DB_C——> {key=iphone_price; value=4000; vclk=[A:1, B:1,C:1]}

Step 7:  C把更新同步给AB,因为某些问题,只同步到A,结果如下:

DB_A——> {key=iphone_price; value=4000; vclk=[A:1, B:1, C:1]}

DB_B——> {key=iphone_price; value=6888; vclk=[A:1,B:1,C:0]}

DB_C——> {key=iphone_price; value=4000; vclk=[A:1, B:1,C:1]}

Step 8:价格再次波动,变成6000元,系统选择B写入

DB_A——> {key=iphone_price; value=6888; vclk=[A:1, B:1, C:1]}

DB_B——> {key=iphone_price; value=6000; vclk=[A:1,B:2, C:0]}

DB_C——> {key=iphone_price; value=4000; vclk=[A:1, B:1,C:1]}

Step 9: 当B同步更新给A和C时候就出现问题了,A自己的向量时钟是 [A:1, B:1, C:1], 而收到更新消息携带过来的向量时钟是 [A:1,B:2, C:0], B:2 比 B:1新,但是C:0却比C1旧。这时候发生不一致冲突。不一致问题如何解决?向量时钟策略并没有给出解决版本,留给用户自己去解决,只是告诉你目前数据存在冲突

三、规则介绍

版本号变更规则其实就2条,比较简单

1、   每次修改数据,本节点的版本号 加1,例如上述 step 8中 向B写入,于是从B:1 变成 B:2, 其他节点的版本号不发生变更。

2、   每次同步数据(这里需要注意,同步和修改是不一样的写操作哦), 会有三种情况:

a: 本节点的向量版本都要比消息携带过来的向量版本低(小于或等于) 如本节点为 [A:1, B:2,C:3]}, 消息携带过来为  [A:1, B:2,C:4] 或  [A:2, B:3,C:4]等。 这时候合并规则取每个分量的最大值。

b:   本节点的向量版本都要比比消息携带过来的向量版本高,这时候可以认为本地数据比同步过来的数据要新,直接丢弃要同步的版本。

c:   出现冲突,如上述step 9中,有的分量版本大,有的分量版本小,无法判断出来到底谁是最新版本。就要进行冲突仲裁。

四、冲突解决

其实没有一个比较好的解决冲突的版本:就笔者目前所了解,加上时间戳算是一个策略。具体方法是再加一个维度信息:数据更新的时间戳(timestamp)。[A:1, B:2,C:4,ts:123434354] ,如果发生冲突,再比较一下两个数据的ts,大的数值说明比较后更新,选择它作为最终数据。并对向量时钟进行订正。

向量时钟算法简介——本质类似MVCC的更多相关文章

  1. Dynamo涉及的算法和协议——p2p架构,一致性hash容错+gossip协议获取集群状态+向量时钟同步数据

    转自:http://www.letiantian.me/2014-06-16-dynamo-algorithm-protocol/ Dynamo是Amazon的一个分布式的键值系统,P2P架构,没有主 ...

  2. NoSQL生态系统——一致性RWN协议,向量时钟,gossip协议监测故障

    13.5 一致性 在NoSQL中,通常有两个层次的一致性:第一种是强一致性,既集群中的所有机器状态同步保持一致.第二种是最终一致性,既可以允许短暂的数据不一致,但数据最终会保持一致.我们先来讲一下,在 ...

  3. Dynamo分布式系统——「RWN」协议解决多备份数据如何读写来保证数据一致性,而「向量时钟」来保证当读取到多个备份数据的时候,如何判断哪些数据是最新的这种情况

    转自:http://blog.jqian.net/post/dynamo.html Dynamo是Amazon开发的一款高可用的分布式KV系统,已经在Amazon商店的后端存储有很成熟的应用.它的特点 ...

  4. AES算法简介

    AES算法简介 一. AES的结构 1.总体结构 明文分组的长度为128位即16字节,密钥长度可以为16,24或者32字节(128,192,256位).根据密钥的长度,算法被称为AES-128,AES ...

  5. 排列熵算法简介及c#实现

    一.   排列熵算法简介: 排列熵算法(Permutation Entroy)为度量时间序列复杂性的一种方法,算法描述如下: 设一维时间序列: 采用相空间重构延迟坐标法对X中任一元素x(i)进行相空间 ...

  6. STL所有算法简介 (转) http://www.cnblogs.com/yuehui/archive/2012/06/19/2554300.html

    STL所有算法简介 STL中的所有算法(70个) 参考自:http://www.cppblog.com/mzty/archive/2007/03/14/19819.htmlhttp://hi.baid ...

  7. PageRank 算法简介

    有两篇文章一篇讲解(下面copy)< PageRank算法简介及Map-Reduce实现>来源:http://www.cnblogs.com/fengfenggirl/p/pagerank ...

  8. Gradient Boosting算法简介

    最近项目中涉及基于Gradient Boosting Regression 算法拟合时间序列曲线的内容,利用python机器学习包 scikit-learn 中的GradientBoostingReg ...

  9. 向量时钟Vector Clock in Riak

    Riak 是以 Erlang 编写的一个高度可扩展的分布式数据存储,Riak的实现是基于Amazon的Dynamo论文,Riak的设计目标之一就是高可用.Riak支持多节点构建的系统,每次读写请求不需 ...

随机推荐

  1. DuiLib学习bug整理——某些png不能显示

    今天下午遇到用ps导出的png显示不出来的情况.而从其他来源的png有的可以显示.到群里问了下也有人遇到过,但是都没想明白具体原因.后来经人指点说png保存时存在深度位不同.最后经过测试 8位深度.3 ...

  2. Nginx安装注意事项

    因为nginx需要依赖pcre库.zlib库.openssl库,所以需要下载这三个库以及nginx源码.       下载以上文件到/usr/local/src/目录下     使用tar -zxvf ...

  3. jvm基础笔记

    名词解释: 三类参数:标准参数(可能不会变的,java -help列出来的就是这类的),X参数(非标准化参数),XX参数(扩展参数). 所有XX 参数都以-XX开始,但后面出现的+-就不同了.+代表激 ...

  4. ftp 530 This FTP serveris anonymous only,

    引用:http://blog.sina.com.cn/s/blog_7e16680c01018ox1.html 三.遇到的问题 1.只允许匿名用户登录 现象:ftp连接过程中,提示输入用户名,输入本机 ...

  5. boost源码剖析----boost::any

    boost源码剖析----boost::any 有的时候我们需要有一个万能类型来进行一些操作,这时候boost::any就派上用场了. boost::Any testInt(10); int val ...

  6. Egret引擎随学随机

    1.纹理集实际上就是将一些零碎的小图放到一张大图当中.游戏中也经常使用到纹理集.使用纹理集的好处很多,我们通过将大量的图片拼合为一张图片从而减少网络请求,原先加载数次的图片资源现在加载一次即可.同时, ...

  7. Dynamics AX 2012 R2 为运行失败的批处理任务设置预警

    我们主要有两种类型的系统监视:环境健康监视和性能监视. 环境健康监视一般对系统性能影响非常小,是为了提醒潜在的问题. 性能监视通常更有侵入性.监视期间,添加一个负载到环境.因此,它可以回答特定的问题或 ...

  8. python学习之while语句

    while循环 1.简单的while循环while True: ")#这是一个简单的while循环,当等于True时会一直打印1 2.while执行多少次后退出 coun=0while Tr ...

  9. c++11中的for简化用法

    1.序列for循环 map<string,int> m{{"a",1},{"b",2},{"c",3}} for(auto p: ...

  10. USB port 如何识别不同的Charger类型

    基于Qualcom 8960/8921平台 一,软件分析 1.  USB charger types & Power supply types USB_INVALID_CHARGER      ...