Gossip协议笔记--谣言、流行病协议

668 阅读8分钟

gossip是一个去中心化思路的分布式通信协议,主要用在分布式数据库系统中各个副本节点同步数据之用,这种场景的一个最大特点就是组成的网络的节点都是对等节点,是非结构化网络,这区别于结构化网络。

Gossip Protocol原本用于分布式数据库中节点同步数据使用,后来被广泛用于数据库复制、信息扩散、集群成员身份确认、故障探测等,应用实例有Redis集群、springcloud consul等。

问题 ● 如何在多个不可靠、变化缓慢的网络中将多个节点实现并保持数据一致性的方法 目标 ● 设计一种高效且强大的算法,并随着节点数量的增加而优雅地扩展。 算法考量因素 ● 信息变更后,更新传播到所有节点所需的时间 ●传播单个更新时生成的网络流量

执行过程:

Gossip 过程是由种子节点发起,当一个种子节点有状态需要更新到网络中的其他节点时,它会随机的选择周围几个节点散播消息,收到消息的节点也会重复该过程,直至最终网络中所有的节点都收到了消息。这个过程可能需要一定的时间,由于不能保证某个时刻所有节点都收到消息,但是理论上最终所有节点都会收到消息,因此它是一个最终一致性协议。 在这里插入图片描述

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

Gossip 的特点(优势)

1)扩展性

网络可以允许节点的任意增加和减少,新增加的节点的状态最终会与其他节点一致。

2)容错

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

3)去中心化

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

4)一致性收敛

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

5)简单

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

Gossip 的缺陷

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

1)消息的延迟

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

2)消息冗余

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

Gossip协议机制

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

●直接邮寄(Direct Mail) 每个节点更新都会立即从其变更节点邮寄通知到所有其他节点。 在这里插入图片描述 主要是当节点有数据更新便开始遍历节点池,遍历发送其他所有节点消息来通知自身节点数据的更新情况

好处:实现起来比较容易,数据同步也很及时 缺点:可能会因为A的缓存队列满了而丢数据,所以只采用直接邮寄是无法实现最终一致性的。

  1. 节点A发送数据给B成功。
  2. 节点A发送数据给D失败,但是节点A的缓存满了,发送的数据无法保存。
  3. 节点B和D数据不一致

●反熵(Anti-entropy) 熵:混乱的意思,反熵,就是反差异的意思

每个节点都会定期随机选择节点池中的一些节点,通过交换数据内容来解决两者之间的任何差异。

  1. 所有参与节点只有两种状态:Suspective(病原)、Infective(感染)
  2. 过程是种子节点会把所有的数据都跟其他节点共享,以便消除节点之间数据的任何不一致
  3. 缺点是消息数量非常庞大,且无限制;通常只用于新加入节点的数据初始化。

反熵是一种通过异步修复实现最终一致性的方法。

方式

● 推 就是将自己的所有副本数据,推给对方,修复对方副本中的熵 在这里插入图片描述

● 拉 就是拉取对方的所有副本数据,修复自己副本中的熵 在这里插入图片描述

● 推拉 就是同时修复自己副本和对方副本中的熵 在这里插入图片描述

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

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

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

●谣言传播(Rumor mongering)

  1. 所有的节点在最开始没有产生数据变更时都假设是未知状态,它是不知道任何谣言信息的
  2. 当节点收到其他节点更新数据通知时,相当于听到了一条谣言,并将其视为热门开始传播给周边节点
  3. 当某个节点谣言盛行时,它会定期随机选择其他节点,并确保另一个节点知道
  4. 当某个节点发现周边节点都知道这个谣言时,该节点将停止将该谣言视为热点,并保留更新,而不会进一步传播 在这里插入图片描述节点 A 向节点 B、D 发送新数据 节点 B 收到新数据后,变成活跃节点,然后节点 B 向节点 C、D 发送新数据。

gossip 算法实现伪代码 Anti-Entropy(反熵) 和 Rumor-Mongering(谣言传播) 的实现伪代码 在这里插入图片描述 在这里插入图片描述 Gossip协议通过反熵传播(anti-entropy)和谣言传播(rumor mongering)两种机制进行实现并保证节点数据的最终一致性。

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

协议可以支持以下需求

  1. Database replication
  2. 消息传播
  3. Cluster membership
  4. Failure 检测
  5. Overlay Networks
  6. Aggregations (比如计算平均值、最大值以及总和)

总结 Gossip是一个去中心化的分布式协议,数据通过节点像病毒一样逐个传播,整体传播速度非常快,很像现在全球蔓延的新冠病毒(2019-nCoV)。 Gossip的信息传播和扩散通常需要由种子节点发起。整个传播过程可能需要一定的时间,由于不能保证某个时刻所有节点都收到消息,但是理论上最终所有节点都会收到消息,因此它是最终一致性协议。 Gossip是一个多主协议,所有写操作可以由不同节点发起,并且同步给其他副本。Gossip内组成的网络节点都是对等节点,是非结构化网络。