原创声明

原文地址:https://blog.csdn.net/qq_44961149/article/details/115398350


1. 简介

Gossip 是去中心化的分布式通信协议,主要用于分布式数据库系统中各个副本节点之间同步数据。该场景的最大特点是组成网络的节点都是对等节点,是非结构化网络,这与结构化网络不同。

Gossip 被广泛应用于数据库复制、信息扩散、集群成员身份确认、故障探测等,应用实例有 Redis 集群、Consul 等。


2. 执行过程

Gossip 过程由种子节点发起,当种子节点有状态需要更新到网络中的其它节点时,它将随机地选择周围若干个节点散播消息,收到消息的节点将重复该过程,最终网络中的所有节点都将收到该消息。该过程需要一定的时间,由于不能保证某个时刻所有节点都收到消息,但是理论上最终所有节点都将收到消息,因此 Gossip 是最终一致性协议。

gossip-example-1.gif

注意:Gossip 过程是异步的,也就是说,发消息的节点不关注对方是否收到,不等待响应;不管对方是否收到,它都会每隔 1 秒向周围节点发消息。异步是它的优点,而消息冗余则是它的缺点。


3. 优势

3.1. 扩展性

允许任意增加和减少节点,新增加的节点的状态最终将与其它节点一致。

3.2. 容错

网络中任何节点的宕机和重启都不会影响 Gossip 消息的传播,Gossip 协议具有天然的分布式系统容错特性。

3.3. 去中心化

在 Gossip 协议中,没有任何中心节点,所有节点都是对等的,任何节点无需知道网络的整体状况,只要网络是连通的,任意节点就可以把消息散播到全网。

3.4. 一致性收敛

在 Gossip 协议中,消息会以一传十、十传百一样的指数级速度在网络中快速传播,因此系统状态可以在很快的时间内收敛到一致。消息传播速度可达到 logN。

3.5. 简单

Gossip 协议的过程极其简单,实现起来几乎没有太多复杂性。


4. 缺点

分布式网络中,没有完美的解决方案,Gossip 协议跟其它协议一样,也有不可避免的缺陷,主要是两个:

4.1. 消息的延迟

由于在 Gossip 协议中,节点只会随机地向少数几个节点发送消息,消息最终通过多个轮次的散播而到达全网,因此使用 Gossip 协议会造成不可避免的消息延迟。不适合用在对实时性要求较高的场景下。

4.2. 消息冗余

Gossip 协议规定,节点定期随机选择周围节点发送消息,而收到消息的节点重复该步骤,因此就不可避免地存在消息被重复发送给同一节点的情况,造成消息的冗余,同时也增加收到消息的节点的处理压力。而且由于是定期发送,因此节点会反复地收到重复消息,加重了消息的冗余。


5. 协议机制

直接邮寄(Direct Mail)、反熵(Anti-entropy)和谣言传播(Rumor mongering)是实现最终一致性的三种常用方法。

5.1. 直接邮寄(Direct Mail)

每个节点更新都会立即从其变更节点邮寄通知到所有其它节点。

gossip-direct-mail.png

当节点有数据更新,便开始遍历节点池,向其它所有节点发送消息,来通知自身节点数据的更新情况。

5.2. 反熵(Anti-entropy)

每个节点定期随机选择节点池中的一些节点,通过交换数据内容来解决两者之间的差异。所有参与节点只有两种状态:Suspective(病原)、Infective(感染)。其过程是:种子节点将所有数据跟其它节点共享,以便消除节点之间数据的不一致。由于消息数量庞大,且无限制,因此通常只用于新加入节点的数据初始化。反熵是一种通过异步修复实现最终一致性的方法。

5.2.1. 推

将自己的所有副本数据,推给对方,修复对方副本中的熵。

gossip-push.png

5.2.2. 拉

拉取对方的所有副本数据,修复自己副本中的熵。

gossip-pull.png

5.2.3. 推拉

同时修复自己副本和对方副本中的熵。

gossip-push-pull.png

反熵(anti-entropy)与直接邮寄(direct mail)相比,其最大特点是解决了消息丢失无法补偿容错导致的数据无法保持一致的致命问题。它通过定时随机通知周边节点进行数据交互的方式,保持各节点之间数据一致性。一致性的保持是在节点数据变更后一段时间内通过节点间的数据交互逐渐完成的最终一致,并且由于每个节点都定期广播数据到周边的一部分节点,因此在数据交互上存在冗余和延迟。

反熵需要节点两两交换和比对自己所有的数据,执行反熵时通讯成本很高,所以不建议在实际场景中频繁执行反熵,可以通过引入校验和(Checksum)等机制,降低需要对比的数据量和通讯消息等。

执行反熵时,相关的节点都是已知的,而且节点数量不能太多,在动态变化或节点数比较多的分布式环境(比如在 DevOps 环境中检测节点故障,动态维护集群节点状态)中,不适合使用反熵。那么当你面临这种情况时,如何实现最终一致性呢?答案是谣言传播。

5.3. 谣言传播(Rumor mongering)

  1. 所有节点在没有产生数据变更时,都处于未知状态,它不知道任何谣言信息
  2. 当节点收到其它节点更新数据的通知时,相当于听到一条谣言,将其视为热门传播给周边节点
  3. 当某个节点谣言盛行时,它定期随机选择其它节点,确保另一个节点知道
  4. 当某个节点发现周边节点都知道该谣言时,该节点停止将该谣言视为热点,保留更新,但不会进一步传播

gossip-rumor-mongering.png


6. 伪代码

Anti-Entropy(反熵) 和 Rumor-Mongering(谣言传播) 的伪代码。

gossip-pcode-1.png

gossip-pcode-2.png

Gossip 协议通过反熵传播(Anti-Entropy)和谣言传播(Rumor-Mongering)两种机制实现及保证节点数据的最终一致性。

  1. 种子节点周期性地散播消息
  2. 被感染节点随机选择 N 个邻接节点散播消息
  3. 节点只接收消息不反馈结果,每次散播消息都选择尚未发送过的节点
  4. 收到消息的节点不再向发送节点散播,即单向不可逆,如A -> B,那么 B 进行散播时,不再发给 A