冲突的处理 - 分布式数据库相关理论 Part5

冲突的处理,也是分布式系统中一个重要的议题。今天我们继续以 Riak 为案例,看看 Riak 是怎么做冲突处理的。

Vector Clock(向量钟)

Riak 通过一种叫做 Vector Clock 的机制来处理冲突问题。简单来说,Vector Clock 是一段 token
Riak 这样的分布式系统通过这样的 token 来追踪数据更新操作的先后顺序。

在冲突处理中,能够知道冲突操作(eg. 创建操作,更改操作)的顺序,是非常重要的。
因为对于分布式系统来说,不同的客户端连接到的是不同的服务器节点,
当一个客户端更新了一个服务器节点上的数据,也许另一个客户端也同时更新了另一个服务器节点上的数据。

这时候,也许你会想到:记录每个操作的时间戳,然后依照时间戳靠后的操作来。然而要这么做的话,这里有个隐含的前提:
在这个分布式系统中的每个服务器节点,时钟都必须是完全同步的。
然而事实上,一方面这是非常困难的:需要非常大的财力物力的投入;另一方面,整个系统又是单点故障的。

所以,Riak 使用 Vector Clocks 来处理冲突。Vector Clocks 给每个写操作(创建,更改,删除) 打上一个标签,标签代表了是哪个客户端以什么样的顺序执行的操作。
这样一来,客户端或者开发者就能决定面对冲突,该怎么决定。
如果你熟悉像 Git, Subversion这样的版本控制系统,
这就和两个人同时修改了同一个文件产生的冲突解决思路是相似的。

Vector Clock 小故事 —— Vector Clock 相关理论

暴走大事件的编辑部每周都要整理下一期里要播报的新闻段子。

假设负责整理新闻段子有3个人:王尼玛(A), 张全蛋(B), 纸巾(C)。他们需要确定最终的新闻段子的列表。新闻段子的列表存储在分布式的服务器中。

每个人用自己的终端连接数据库。这些终端都有着唯一的标识,用来构建 vector clock。下面就让我们模拟一下,vector clock 是如何工作的。

首先,王尼玛用自己的终端更新了列表

vclock: A[0]
value: ['news xx']

然后,张全蛋先下载了这个列表,然后更新了这个列表

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']

这样一来,任何人之后获取到的就是这个最新的合并后的值了。

    原文作者:Michael_Ding
    原文地址: https://segmentfault.com/a/1190000002802822
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞