Distributed初探-判断因果关系的向量时钟算法实现

感谢参考原文-http://bjbsair.com/2020-04-01/tech-info/18304.html

今天的文章来聊聊向量时钟,在前文介绍分布式系统一致性的时候,曾经介绍过,在弱一致性模型当中会有一个因果性的问题。向量时钟算法正是设计出来解决因果关系问题的。

我们来回顾一下因果问题,在实际日常的网页行为当中,部分行为存在因果关系。比方说知乎里面回答问题,显然得先有一个同学提出问题,然后才能有各路大V谢邀解答问题。但是由于是分布式系统,有可能问题和回答并不是存放在同一台机器,导致有可能它们更新的顺序不一致,所以就有可能会出现用户在访问知乎的时候,发现自己关注的大V回答了某个问题,但是点进去问题却是空的。这种幽灵情况不是灵异事件,只是单纯的分布式系统设计没过关,没有考虑因果问题。

有的同学可以会说,这个不难啊,我们加入时间戳啊。时间戳的确可以解决一部分问题,但是并不能解决所有问题。有了时间戳之后,我们可以获得事件发生的时间,但是仍然不知道不同的数据之间的因果关系。由于分布式系统存在延迟,也不能简单地通过时间戳来做过滤或者筛选。不过,虽然单纯的时间戳不行,但已经非常接近了。

我们日常生活当中用事件发生的时间来反应事物发生的顺序,我们说的先后顺序,其实是以客观上的时间作为参考系参考得到的结果。问题来了,我们能不能找到或者构造出其他的参考系来反应事物发生的顺序呢?

当然是可以的,不然也没有这篇文章了,这就是大名鼎鼎的逻辑时钟算法。多说一句,逻辑时钟算法和许多其他分布式算法一样,同样源于大神Lamport的发明。

逻辑时钟

我们还用之前的例子来思考一下,一个人在知乎提交了问题,另一个人回答了问题,这是两个事件。我们第一反应自然是通过两个事件发生的时间来反应因果顺序,但我们仔细分析一下这个场景。后面那个人既然能回答问题,说明他一定是看到了问题。也就是说回答问题和看到问题之间发生了交互,所以很自然地可以想到,我们是不是可以用两个系统或者是两个事件之间有没有发生过信息交互来反应因果顺序呢?

于是基于这个思想,Lamport大神提出了逻辑时钟的概念。逻辑时钟概念的核心就是刚才我们说的,两个事件之间建立因果关系的前提是,两个事件之间发生过信息传递

我们梳理一下可能发生的事件的种类,可以分成三种。第一种是发生在某个节点内部,也就是说没有和其他任何节点发生联系。第二种是发送事件,是事件的发送方。第三种是接收事件,和第二种对应,是事件的接收方。明确了这三点之后,我们就可以用时间戳来表示这三种情况了。首先,我们假设每个节点内部都会维护一个时间戳,记录当下节点的状态。

针对上面说是三种时序关系呢,我们设定三种策略。

首先是内部事件,对于节点内部发生事件呢,很简单,我们只需要将它的时间戳增大1,表示发生过了某件事情。

其次是发送事件,节点内部的时间戳自增1,并且在发送消息当中加上这个时间戳。

最后是接收事件,由于会额外接收到一个时间戳,所以我们需要利用这个时间戳来更新节点内部的时间戳。更新的方法也很简单,假设节点内部的时间戳是tt,跟着消息传递而来的时间戳是t′t′, 那么: tnew=max(t+1,t′)tnew=max(t+1,t′)。

我们分析一下上面这个关系,假设当下有事件A和B,如果事件A是事件B发生的前提。那么显然事件A的时间戳小于事件B。如果反过来,事件A的时间戳小于B,能说明事件A是事件B的前提吗?并不能,所以时间戳较小是因果关系的必要条件,但不是充分条件

由于会存在多个节点或者进程时间戳相等的情况,所以我们把进程id也作为比较的银子。我们用C表示一个事件的时间戳,P表示事件的进程pid。如果事件A排在事件B前面,只有两种可能:

分布式初探——判断因果关系的向量时钟算法

我们来看一个例子:

分布式初探——判断因果关系的向量时钟算法

上图当中有A、B和C三个进程,其中P(A) < P(B) < P(C)。图中每一个箭头都代表传递的消息

我们根据重新定义的时序关系,可以得到这些点的先后顺序是:

C1⇒B1⇒B2⇒A1⇒B3⇒A2⇒C2⇒B4⇒C3⇒A3⇒B5⇒C4⇒C5⇒A4

如果仔细观察这条链的话会发现它并不能真实反映事件发生的顺序,会存在不公平的情况。但至少因果关系可以保证。

以上这个算法被称为是逻辑时钟算法,它相当于重新定义了一个逻辑上的时间来代替真实物理世界的时间。由于它是Lamport大神提出的,所以也被称为是Lamport逻辑时钟算法

向量时钟

在上面的文章当中我们也分析了,逻辑时钟算法有一个问题是虽然保证了因果顺序,但也牺牲了公平。比如上图当中B3和A2发生在同一时间,但是B3排在A2的前面。也就是说我们通过比较C(A)C(A)和C(B)C(B)无法得出真实的发生顺序。

为了解决这个问题,大神们在Lamport的逻辑时钟上做了改进,提出了向量时钟算法

向量时钟和逻辑时钟的原理几乎一样,只不过对于每个节点或者进程而言,它维护的不再是一个单个的时间戳,而是一个时间戳构成的向量。向量的维度就等于进程的数量,也就是说每个进程不止记录自己的时间戳,而且还会记录其他进程的时间戳,这些时间戳组合在一起,就构成了一个时间向量

在事件的处理上,向量时钟算法和逻辑时钟基本一致。

分布式初探——判断因果关系的向量时钟算法

同样,由于单个时间戳换成了向量时钟,所以我们判断因果顺序的方式也需要变化。在向量时钟算法当中,我们定义如果事件A在事件B之前,那么需要满足两个条件:

分布式初探——判断因果关系的向量时钟算法

也就是说至少需要一个维度存在严格小于,其他维度全部小于等于,才可以看做是因果关系。原因也很简单,因为如果存在消息传递,那么至少有一个维度会带来增加。如果两个事件的向量时钟相等,说明两者是没有发生过信息传递的,自然也就不符合我们定义的因果关系。

我们回顾一下之前的例子,将节点改写成向量时钟之后,得到的结果如下图:

分布式初探——判断因果关系的向量时钟算法

将逻辑时钟优化成向量时钟之后,就可以严格判断因果关系了。如果两个节点的时钟向量没有大小关系,那么可以说明这两个事件之间没有联系。

实际应用

和我们之前介绍的一样,向量时钟算法主要用在分布式系统的因果关系的检测上。而因果关系之所以需要检测,往往是因为我们面临多个副本同时更新,我们需要检测这些副本的冲突

我们来一起看一个例子,这个例子是亚马逊的Dynamo系统, 它是一个KV的存储系统,类似于redis,可以简单理解成缓存。为了高可用,Dynamo保证即使在出现网络分区或者机器宕机的时候,仍然可读可写。但是这会导致一个问题,当网络分区恢复之后,多个副本的数据可能会出现不一致的情况,这个时候我们就需要通过向量时钟算法来检测冲突了。

分布式初探——判断因果关系的向量时钟算法
分布式初探——判断因果关系的向量时钟算法

除了知乎之外,其实还有很多场景下的一致性问题都需要考虑因果关系。因此向量时钟算法在分布式领域可以说是鼎鼎大名,使用非常广泛。在刚听到这个名字的时候,往往会觉得它非常晦涩难懂,但实际深入了解之后,会发现其实并不困难,反而非常有趣,这也算是学习的乐趣之一吧。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容