冲突的处理,也是分布式系统中一个重要的议题。今天咱们继续以 Riak 为案例,看看 Riak 是怎么作冲突处理的。数据库
Riak 经过一种叫作 Vector Clock
的机制来处理冲突问题。简单来讲,Vector Clock
是一段 token
,
像 Riak
这样的分布式系统经过这样的 token
来追踪数据更新操做的前后顺序。服务器
在冲突处理中,可以知道冲突操做(eg. 建立操做,更改操做)的顺序,是很是重要的。
由于对于分布式系统来讲,不一样的客户端链接到的是不一样的服务器节点,
当一个客户端更新了一个服务器节点上的数据,也许另外一个客户端也同时更新了另外一个服务器节点上的数据。分布式
这时候,也许你会想到:记录每一个操做的时间戳,而后依照时间戳靠后的操做来。然而要这么作的话,这里有个隐含的前提:
在这个分布式系统中的每一个服务器节点,时钟都必须是彻底同步的。
然而事实上,一方面这是很是困难的:须要很是大的财力物力的投入;另外一方面,整个系统又是单点故障的。版本控制
因此,Riak 使用 Vector Clocks
来处理冲突。Vector Clocks
给每一个写操做(建立,更改,删除) 打上一个标签,标签表明了是哪一个客户端以什么样的顺序执行的操做。
这样一来,客户端或者开发者就能决定面对冲突,该怎么决定。
若是你熟悉像 Git
, Subversion
这样的版本控制系统,
这就和两我的同时修改了同一个文件产生的冲突解决思路是类似的。code
Vector Clock
小故事 —— Vector Clock
相关理论暴走大事件的编辑部每周都要整理下一期里要播报的新闻段子。token
假设负责整理新闻段子有3我的:王尼玛(A), 张全蛋(B), 纸巾(C)。他们须要肯定最终的新闻段子的列表。新闻段子的列表存储在分布式的服务器中。事件
每一个人用本身的终端链接数据库。这些终端都有着惟一的标识,用来构建 vector clock。下面就让咱们模拟一下,vector clock 是如何工做的。开发
首先,王尼玛用本身的终端更新了列表同步
vclock: A[0] value: ['news xx']
而后,张全蛋先下载了这个列表,而后更新了这个列表it
vclock: A[0], B[0] value: ['news xx', 'news xyy']
张全蛋更新的同时(王尼玛作更新以后),纸巾一样的下载了已有的列表,作了更新。
vclock: A[0], C[0] value: ['news xx', 'news yyz']
次日,张全蛋复查列表,因为纸巾的更新操做并非在他以后的(而是和他同时的),
这时候就产生了一个冲突,须要处理。
他拿到两个值:
vclock: A[0], B[0] value: ['news xx', 'news xyy'] -- vclock: A[0], C[0] value: ['news xx', 'news yyz']
他须要解决这个冲突:因而他选择合并这两个值:
vclock: A[0], C[0], B[1] value: ['news xx', 'news xyy', 'news yyz']
这样一来,任何人以后获取到的就是这个最新的合并后的值了。