浅析时钟向量算法

算法的目的

在使用分布式数据库的时候,不一样节点中数据的一致性一贯是一个经典且难以解决的问题,而这个问题的根源是难以实现一个全局统一的时钟。下面就描述了这种问题的一种状况:mysql

这里写图片描述

如上图所示:A,B,C 表示分布式系统中的三个数据库,纵轴表示时间。在 TA1 时刻 A 作出了更改  Key=Value1 ,此次更改在 TC2 时刻传输到了 C;在 TB1 时刻 B 作出了更改  Key=Value2 ,此次更改在 TC1 时刻传输到了 C。那么问题来了:C 数据库中的  Key  应该等于  Value1  仍是  Value2  呢?算法

天然地,咱们能够想到: Key  的取值应该和最新的更改保持一致。可是,因为很难实现一个全部节点都一致的全局时钟,因此不一样节点各自的时钟实际上并不具备可比性,即 TA1 < TB1 也不能说明 B 对  Key  的更改是在 A 以后发生的。sql

接下来要介绍的向 量时钟算法 就可以部分解决上面的问题。数据库

算法的内容

在一个有 N 个节点的分布式数据库中,用一个 N 维的向量来表征时间,其中的某一个维表示一个节点的时间,这个时间向量按照如下规则进行处理:分布式

  • 全部节点的初始时间向量都是 0;
  • 每一次经历一个时间间隔,都要在各自的时间维度上加 1;
  • 每次发送数据,都要将这个向量时间做为时间戳和数据一块儿发出去;
  • 每次节点收到了时间向量,都要比较该时间向量和自身时间向量,并取二者中每一维中的最大值,做为自身新的时间向量;
  • 当收到有冲突的更改时,比较这两次更改的时间向量:若存在偏序关系,则取偏序关系中时间向量较大的对应的值,并以此做为本节点新的时间向量;若不存在偏序关系,则不能合并;

其中的偏序关系是指: 若A向量中的每一维都大于等于B向量,那么就说A,B向量之间存在偏序关系,不然不存在偏序关系  。ui

举个例子:spa

A,B,C 三个节点的初始时间向量都是  (0,0,0) ,该向量的一,二,三维分别对应 A,B,C 三个节点各自的时间。.net

这里写图片描述

  • A 做出更改  (0,0,0) ,时间向量变为  (1,0,0) ;
  • A 的更改传输到了 B 处,B 处  Key=Value1 , 且时间向量变为  (1,0,0) ;
  • B 做出更改  Key=Value2 , 将时间向量中本身对应的那一维加 1 变为  (1,1,0) ;
  • B 和 A 的更改都同步到了 C 处。C 比较二者的时间向量  (1,0,0)  和  (1,1,0) ,发现存在偏序关系,因而 C 的时间向量更新为  (1,1,0)  且  Key=Value2 ;

算法的本质

虽然咱们已经学会了怎么使用时钟向量算法,可是彷佛还和算法的本质隔着一层雾:咱们其实并无解决“不一样节点之间统一的时钟”这一个客观的问题,可是经过向量时钟算法,咱们却能够肯定一些更改的前后顺序,而这些是在以前没法肯定。那多出来的信息是从哪里得到的?code

结合前面给出的两张图中的两个例子,对比传统的方法和时间向量算法的差别:blog

其实客观上是能够得知 B 对  Key  的更改是在 A 以后的,由于 B 是在收到 A 的更改以后才进行的下一步更改。传统的方法丢失了这部分信息,而向量时钟算法将这个信息保存了起来,用于后面对更改的前后顺序的断定。用数学表达就是:

由于 TB0 > TA1, TB1 > TB0,因此 TB1 > TA1;而传统的方法丢失了“TB1 > TB0”这条信息。

那么,既然向量时钟的惟一目的是传输“TB1 > TB0”这条信息,那么其余任何方法,只要可以将这类信息包含进去,也拥有和向量时钟算法相同的效果。好比  Git  中冲突合并的思想和向量时钟算法的本质实际上是同样的: Git  中不一样的本地仓库拥有不一样的时间维度,每一次  commit  对应一个时间维度上值的增长,能够快速合并的两个仓库对应的时间向量是具备偏序关系的。

总结以下:

  •  给不一样的节点设置不一样的时间维度  体现了  不一样节点之间没有一个统一的时钟,所以不一样节点之间的时间就不具备可比性 ;
  •  每一个节点的更新会在本身的时间维度上加 1  体现了  同一个节点上的时间是能够比较的 ;
  •  时钟向量 A,B 具备偏序关系且 A>B  体现了  A 是在同一节点上,在 B 的基础上增长的获得的;同一节点上发生的事件能够判断前后顺序,那么能够得知 A 发生在 B 以后 ;
  •  时钟向量 A,B 不具备偏序关系  体现了  A,B 之间不存在可以将某一个向量的尾端顺着同一个节点连到另外一个向量中间的事件 ;

因此向量时钟算法的实质是:

  • 将逻辑上能够合并的冲突成功合并;
  • 逻辑上没法合并的冲突依旧冲突;

拓展:和狭义相对论时空观念的比较

上面算法中的这种  A,B 之间不存在可以将某一个向量的尾端顺着同一个节点连到另外一个向量中间的事件  和  用一个多维的时间来代替一维的时间  的时空观,和狭义相对论中的时空观很是相似。

在狭义相对论中,同一事件从不一样的惯性参考系中观察是不同的,而两次事件能够创建因果关系的前提是:两个事件之间能够用等于或小于光速的速度传递信息(或者说一事件位于另外一事件的光锥内部)。

联系:

在狭义相对论中的描述 在向量时钟算法中的描述
不一样的惯性参考系有不一样的时间 不一样的节点有不一样的时钟向量维度
两件事件具备因果关系(事件 2 位于事件 1 的光锥内部) 两次更改可肯定前后顺序(两个向量具备偏序,相似光锥内部)
两件事件不具备因果关系(事件 2 位于事件 1 的光锥外部) 两件事件不具备因果关系(事件 2 位于事件 1 的光锥外部)

更详细的关于时钟向量算法和狭义相对论时空观的比较能够阅读参考文献 3。

区别:

狭义相对论能够用洛伦兹变换将不一样的参考系中的时间进行变换(利用到不一样参考系之间的相对速度),可是向量时钟算法不能够(其实逻辑上也能够,可是实现后没有现实意义),因此只能用多维的时间来表征不一样节点中的时间却无法相互转化。

参考文献

相关文章
相关标签/搜索