分布式原理:错误探测和成员表

错误检测

一个可靠的系统必须具备下面四点:

011_001.jpg

然后错误又分为下面三种,理论性的东西而已

011_002.jpg

那么在分布式系统里,我们怎么防止错误的出现呢(failure masking)

  1. 信息冗余,比如出错的概率是1%,我把信息变多了,正确信息出错的概率就小了,我加一堆冗余的信息
  2. 次数的重复,多发几次
  3. 物理的重复,多弄几个设备存

成员表

上面说了那么多,其实错误检测主要是为了控制一个成员表,成员表顾名思义,就是维系一个分布式系统有多少成员的列表,或者说,有多少在线用户(没有崩的)列表。

那么就需要注意,1.怎么检测有没有崩 2.怎么传播(dissemination)这个列表

先来看看怎么检测,我们要检测,就是如果有人崩了,必须得有人知道,所以可是宁错杀一万,不留一个坏的,所以,它可以容忍假阳性,但是不能容忍没有检测出来。

011_003.jpg

很明显我们可以看出,完备性和准确性是不能同时存在的,也就是你不能要求它做的又对又全,能全对就不能全做完,能全做完就不保证全对。这里选择了全做完!

Completeness – always guaranteed

所以我们由上面的条件诞生了。。。heartbeat检测,其实这玩意早就在用了。。。

维系一个seq,隔一段时间就++

传播方式当然是选择,Gossip一样的传播,毕竟是分布式系统嘛!

011_004.jpg

每个node维系一个table,有所有的在线node 的ID,seq,local time

如何更新呢?记住口诀,只更新大的时间晚的,超时剔除

什么意思呢?就是说,当一个node发送给你一个table,你先看一下这两个table的所有seq有没有差别,找到有差别的,然后看看时间,如果有差别的,只更新大的且时间晚的,如下图所示

011_005.jpg

并且我们设置一个超时时间,当table里的localtime+超时时间超过了本地的时间时候,将这个node剔除!

011_006.jpg

如果从别的node的table又发现了它,那也可以将他复活(incarnation)

那么问题就来了,如果一个node真的死了,但是一定有node记得他,那么这个node就反复发送死去的它的信息,它就永远活在了这个系统里,这可不行,于是我们还需要设计一个Tclean,超过这个时间,就必须在所有node中删除!

后面我们又想,如果这个分布式系统特别大,每个node维系的table就会特别大,每次发送这么大的表那也不是一件好事,于是SWIM协议就诞生。

SWIM:

Scalable Weakly-consistent Infection-style Membership Protocol(SWIM),可扩展的弱一致的感染式成员协议。简单来说,就是每次heartbeat不发送table了,只给对应的节点发送ping,如果有反应(ack)就更新自己心中的表。

失效检测:

首先就是直接发送ping,没有回复可以继续发给附近的节点,让他们帮忙问问这个node有没有死

传播机制:

Gossip!!

在失效检测中,还可以提供权重系统,也就是怀疑系统(suspision system)

如果一个node被判定失效(ping不出来)之后,我们首先先将他的状态改成suspicion,怀疑它死了,如果过一段时间,它又ping的出来了,我们再让他复活,如果timeout,就宣布它的死亡

011_007.jpg

在此我们又引入了复活机制(incarnation)

每次从suspicion到active的时候给这个人的incarnation数目++(初始都是0)

然后设置一个override机制

011_008.png


分布式原理:错误探测和成员表
https://yiyuwang.be/2022/01/13/2022-01-13-457105107/
作者
StevenWong
发布于
2022年1月13日
许可协议