分布式时钟同步二:向量时钟
逻辑时钟的问题->向量时钟的思想
首先让我们回顾一下逻辑时钟的一些问题。因为在进程A中(如下图1所示),我们无法知道进程B中的数据X的时钟已经高过了3,所以并不会主动让最后发生的数据更新事件A3有高于3的时间。
所以,可以认为,因为进程无法记录其他进程内数据的时间版本,所以会造成这样的数据冲突。
假设进程B在完成B2事件后通知进程A:“进程B的数据X时钟变为了4”。那么进程A在完成A3之后就能感受到冲突。
向量时钟基于此思想,在一个进程内存储了所有其他进程的时钟备份,用于感受数据冲突。
向量时钟更新方式
假设系统中共有N个进程,用 V i [ j ] V_i[j] Vi[j]表示第 i 个进程内存储的第 j 个进程的逻辑时钟信息,那么按照如下方式更新:
- 初始时,所有时钟及其分量都设置为0
- 每当要进行一个进程内部事件时,将本进程对应的逻辑时钟(即 V i [ i ] V_i[i] Vi[i])加一
- 发送消息时,将自己的向量时钟附在消息中一起发送
- 接收消息时,将自己的逻辑时钟加一,同时更新其他分量,规则为 max { 本 地 向 量 时 钟 分 量 , 收 到 的 向 量 时 钟 分 量 } \max\{本地向量时钟分量,收到的向量时钟分量\} max{本地向量时钟分量,收到的向量时钟分量}
定义如何比较两个向量时钟的大小:
- 另 V A ( P ) V_A(P) VA(P)表示进程A中的事件P, V B ( Q ) V_B(Q) VB(Q)表示进程B中的事件Q
- V A ( P ) < V B ( Q ) V_A(P)<V_B(Q) VA(P)<VB(Q),当且仅当在每一维, V A ( P ) V_A(P) VA(P)的分量都小于等于 V B ( Q ) V_B(Q) VB(Q)的对应分量。
如果 V A ( P ) V_A(P) VA(P)和 V B ( Q ) V_B(Q) VB(Q)不可比较,即在某些维度存在大于关系,而另一些维度存在小于关系,则表示事件P和事件Q存在冲突。
举例
如图2所示,这是将图1中的数据更新过程转化为向量时钟后,各个事件所拥有的向量时钟
如图3所示,可以看出,其实
V
A
3
V_{A3}
VA3和
V
B
2
V_{B2}
VB2是有冲突的。为什么这么说呢?因为A3中时间的第一维分量大于B2,而第二维分量却小于B2的第二维分量。也就是说,进程A和进程B在完成最近的一次对数据X的同步后,又分别对数据X进行了更新,所以产生了冲突。于是,数据库收到A3和B2两个事件提交时,就能察觉到数据冲突。
那么怎么解决这样的数据冲突呢?其实只要再进行一次同步,即消息传递就可以了(如图4)。这样,事件A4和B3的时间就没有冲突了。
总结:向量时钟是用于分布式数据系统里面感知数据冲突用的。至于数据冲突如何解决并不管。