向量时钟Vector Clock in Riak
Riak 是以 Erlang 编写的一个高度可扩展的分布式数据存储,Riak的实现是基于Amazon的Dynamo论文,Riak的设计目标之一就是高可用。Riak支持多节点构建的系统,每次读写请求不需要集群内所有节点参与也能胜任。像这样的系统,我们需要版本机制来确定哪个值是最新的。所以就引入了向量时钟(Vector Clock)
当存储一个对象到Riak时,都被打上向量时钟标签。通过向量空间祖先继承的关系比较,Riak可以自动的修复不同步的值,使数据保持最终一致性。
向量时钟的作用
有个比较经典的例子,说明向量时钟的作用。假设有如下场景:
Alice、Ben、Catby和Dave四人约定下周一起聚餐,四个人通过邮件商量聚餐的时间。 Alice首先建议周三聚餐。 之后Dave和Catby商量觉得周四更合适。 后来Dave又和Ben商量之后觉得周二也行。 最后Alice要汇总大家的意见,得到的反馈如下: Cathy说,他和Dave商量的时间是周四 Ben说,他和Dave商量的时间是周三此时恰好联系不上Dave,而且不知道Cathy和Ben分别与Dave确定时间的先后顺序,Alice就不能确定到底该定在哪天了。
Vector Clock就是为了解决这种问题而设计的,简单来说,就是为每个商议结果加上一个时间戳,当结果改变时,更新时间戳。所以加上时间戳之后,我们再一次描述上面的场景,如下:
当Alice第一次提议将时间定为周三时,可以这样描述信息 date = Wednesday vclock = Alice:1其他三个人都收到了信息,Dave和Ben开始交流,Ben建议改成周二,把Alice的初试向量加进去标识Ben看到Alice的消息了 date = Tuesday vclock = Alice:1, Ben:1Dave回复Ben,确定周二可以 date = Tuesday vclock = Alice:1, Ben:1, Dave:1然后Cathy开始说话,也和Dave说建议周四,此时在Dave看来就收到了两个数据如下: date = Tuesday vclock = Alice:1, Ben:1, Dave:1date = Thursday vclock = Alice:1, Cathy:1 这两份数据,各自都不是互相的祖先,所以就产生了冲突,Dave要自动解决这个冲突,他选择了周四,然后将消息改成如下,继承来自Dave现在收到的两条消息,这个消息发回给Cathy date = Thursday vclock = Alice:1, Ben:1, Cathy:1, Dave:2最后来了,Alice只问Ben和Cathy最后的决定: Ben说 date = Tuesday vclock = Alice:1, Ben:1, Dave:1Cathy说 date = Thursday vclock = Alice:1, Ben:1, Cathy:1, Dave:2Alice就明白了,因为第二个Cathy说的是完全继承于Ben说的,所以最后采纳Cathy说的决定,周四去。
以上这个决策用到了向量时钟,有个图还比较清晰了说明整个过程:
向量时钟的空间无限增长问题
以上的做法还比较完美的解决了问题,这里只列举了四个决策者的向量时钟,不过在现实生活中,如果有很多的决策者,相当于有很多的客户端,整个向量时钟的长度就无限制增长了,这对于存储系统来说,不是一个好消息。我们需要想办法解决。
一个直接的想法是,不要用client来标识向量空间,用server来标识向量空间,因为server的数量是可控的,这里用X,Y两台server来重现以上决策的过程,只是标签不再用客户端,而是用server标识,决策过程如下
此时Dave收到两个消息
Tue X:2,Y:1 with Ben
Thu X:1,Y1 from Cathy (这个消息比较新)
发现后者是前者的祖先,所以自然抛弃祖先,最终最新的,这样就悄无声息的把Cathy给他的消息给丢了。
所以尝试用server来做标识,以期减少向量时钟的空间是不可取的,因为会丢数据。实际情况还是需要用客户端的标识来做向量时钟。
向量时钟的剪枝
所以为了解决向量时钟空间的无限增长问题,引入了向量时钟的剪枝。
Riak用四个参数来避免向量时钟空间的无限增长:
small_vclock
big_vclock
young_vclock
old_vclock
small_vclock和big_vclock参数标识向量时钟的长度,如果长度小于small_vclock就不会被剪枝掉,如果长度大于big_vclock就会被剪枝掉
young_vclock和old_vclock参数标识存储这个向量时钟时的时间戳,剪枝策略同理,大于old_vclock的才会被剪枝掉,剪枝策略如下图
这样只会丢掉一些向量时钟的信息,即数据更新过程的信息,但是不会丢掉实实在在的数据。只有当一种情况会有问题,就是一个客户端保持了一个很久之前的向量时钟,然后继承于这个向量时钟提交了一个数据,此时就会有冲突,因为服务器这边已经没有这个很久之前的向量时钟信息了,已经被剪枝掉了可能,所以客户端提交的此次数据,在服务端无法找到一个祖先,此时就会创建一个sibling。
所以这个剪枝的策略是一个权衡tradeoff,一方面是无限增长的向量时钟的空间,另一方面是偶尔的会有"false merge",对,但肯定的是,不会悄无声息的丢数据。综上,为了防止向量时钟空间的无限增长,剪枝还是比用server标识向量时钟工作的更好。
参考:
http://docs.basho.com/riak/latest/theory/concepts/Vector-Clocks/
http://basho.com/why-vector-clocks-are-easy/
http://basho.com/why-vector-clocks-are-hard/
《大型网站系统与Java中间件实践》
向量时钟Vector Clock in Riak相关推荐
- Dynamo分布式系统——「RWN」协议解决多备份数据如何读写来保证数据一致性,而「向量时钟」来保证当读取到多个备份数据的时候,如何判断哪些数据是最新的这种情况...
转自:http://blog.jqian.net/post/dynamo.html Dynamo是Amazon开发的一款高可用的分布式KV系统,已经在Amazon商店的后端存储有很成熟的应用.它的特点 ...
- 分布式系统:向量时钟
Lamport时钟存在的问题 使用Lamport时间戳,只是比较事件 a a a和 b b b各自的时钟值 C { a } C\{a\} C{a}和 C { b } C\{b\} C{b},无法说明它 ...
- NoSQL生态系统——一致性RWN协议,向量时钟,gossip协议监测故障
13.5 一致性 在NoSQL中,通常有两个层次的一致性:第一种是强一致性,既集群中的所有机器状态同步保持一致.第二种是最终一致性,既可以允许短暂的数据不一致,但数据最终会保持一致.我们先来讲一下,在 ...
- Dynamo涉及的算法和协议——p2p架构,一致性hash容错+gossip协议获取集群状态+向量时钟同步数据...
转自:http://www.letiantian.me/2014-06-16-dynamo-algorithm-protocol/ Dynamo是Amazon的一个分布式的键值系统,P2P架构,没有主 ...
- Vector Clock理解
背景 近期在重读"Dynamo: Amazon's Highly Available Key-value Store"(经典好文,推荐!).文章4.4 中聊到了Data Versi ...
- 批处理编程的异类——时钟(Clock)
批处理编程的异类--时钟(Clock) 1.暂停(Pause).延迟(Delay).等待(Wait).睡眠(Sleep) 1)for+set+if,时间精度为0.01秒,适用平台为WinNT/2K/X ...
- 【 Vivado 】时钟组(Clock Groups)
Vivado会分析所有XDC约束时钟间的时序路径.通过set_clock_groups约束不同的时钟组(clock group),Vivado在时序分析时,当source clock和destinat ...
- 向量时钟算法简介——本质类似MVCC
转自:http://blog.chinaunix.net/uid-27105712-id-5612512.html 一.使用背景 先说一下需要用到向量时钟的场景.我们在写数据时候,经常希望数据不要存储 ...
- Why Vector Clock are Easy or Hard?
通过实际例子来阐述vector clock其实是容易理解的, easy 同样通过实际例子来描述在使用vector clock时会遇到哪些难以解决的问题, hard Why Vector Clocks ...
最新文章
- yii2 mysql gone away,yii2 console MySQL server
- [.net]webform 版本冲突
- Java SE 7 Update 25 –发行说明进行了解释。
- NDoc修改版,支持中文注释及中文界面。
- libsvm java 实例_LibSVM Java API调用示例程序
- 某少儿不宜网站图片拍摄位置分析,Python批量读取图片GPS位置!
- apache的tomcat负载均衡和集群配置
- 设计模式01-模板设计模式
- 64 位下,dsoframer.ocx 注册时失败,错误代码为 0x80070005
- 深度学习-各类数据集汇总
- PowerPoint储存此文件时发生错误 出现错误的问题解决方法
- 大学计算机第四讲答案,大学职业生涯规划课第四讲答案
- jquery获取第一个子元素
- 耳机驱动调试(插拔检测与按键检测)
- 什么是交叉检验(K-fold cross-validation)
- 您为什么要加入CSDN个人空间
- python云盘搭建教程_超简单!基于Python搭建个人“云盘”,目前最好用的个人云盘...
- 通过token窃取实现降权或者提权
- [软件需求]软件需求规格说明书样例
- 2020低压电工考试题库及低压电工复审模拟考试
热门文章
- Shell编程之条件语句(if语句,case分支语句)
- CAN波形解析实例(1)
- 组装电脑最容易犯的五大错误
- android 观察者更新ui,android通过观察者模式实现更新UI
- python自动化报表定时跑_POINTer分享:Python如何做报表自动化
- android intent 跳转卡顿_Intent七大属性
- python反转列表_Python实现list反转实例汇总
- spring下连接mysql_使用Spring连接mysql数据库
- 计算机网络及公文写作知识,计算机网络期末复习题
- (11) Hibernate 缓存机制