一、Gossip协议简单理解
Gossip,翻译过来就是八卦,Gossip协议就是八卦协议。
1.1、生活中的八卦协议
- 将你听到的八卦信息,告诉你身边的人。
01、八卦协议举例
华侨城总部一共有400个员工,某一天,刘xx知道某个领导绿帽子消息,刘xx将消息告诉身边的n个同事,收到消息的n个同事又将这个消息告诉身边的n个同事。
假设每人每天都将收到的消息发送一次,那么需要4天,全公司都知道某个领导绿帽子消息
如果过去13天,全地球都知道了
1.2、网络中Gossip协议
- 像流言蜚语一样,利用一种随机、带有传染性的方式,将信息传播到整个网络中,并在一定时间内,使得系统内的所有节点数据一致。
- 好处
- 实现最终一致性的算法
- 实现数据的最终一致性
- 实现最终一致性的算法
1.3、Gossip协议执行过程:
- 种子节点周期性的散播消息 【假定把周期限定为 1 秒】。
- 被感染节点随机选择N个邻接节点散播消息【假定fan-out(扇出)设置为6,每次最多往6个节点散播】。
- 节点只接收消息不反馈结果。
- 每次散播消息都选择尚未发送过的节点进行散播
- A第一次给B发送,第二次到第N次都不给B发送
- 收到消息的节点不再往发送节点散播:A -> B,那么B进行散播的时候,不再发给 A。
Goosip 协议的信息传播和扩散通常需要由种子节点发起。整个传播过程可能需要一定的时间,由于不能保证某个时刻所有节点都收到消息,但是理论上最终所有节点都会收到消息,因此它是一个最终一致性协议。
Gossip协议是一个多主协议,所有写操作可以由不同节点发起,并且同步给其他副本。Gossip内组成的网络节点都是对等节点,是非结构化网络。
二、Gossip协议三板斧
- 直接邮寄(Direct Mail)、反熵(Anti-entropy)和谣言传播(Rumor mongering)
- 是实现最终一致性的常用三种方法。
三、直接邮寄
3.1、定义
- 直接发送更新数据,当数据发送失败时,将数据缓存下来,然后重传。
- 从图中你可以看到,节点 A 直接将更新数据发送给了节点 B、D。
3.2、好处缺陷
- 好处:实现起来比较容易,数据同步也很及时
- 可能会因为A的缓存队列满了而丢数据,所以只采用直接邮寄是无法实现最终一致性的。
- 节点A发送数据给B成功。
- 节点A发送数据给D失败,但是节点A的缓存满了,发送的数据无法保存。
- 节点B和D数据不一致
四、反熵(Anti-entropy)
熵:混乱的意思,反熵,就是反差异的意思
-
反熵是一种通过异步修复实现最终一致性的方法。常见的最终一致性系统(比如Cassandra),都实现了反熵功能。
-
反熵指的是集群中的节点,每隔段时间就随机选择某个其他节点,然后通过互相交换自己的所有数据来消除两者之间的差异,实现数据的最终一致性。
- 所有参与节点只有两种状态:Suspective(病原)、Infective(感染)
- 过程是种子节点会把所有的数据都跟其他节点共享,以便消除节点之间数据的任何不一致
- 缺点是消息数量非常庞大,且无限制;通常只用于新加入节点的数据初始化。
-
方式
- 推
- 拉
- 推拉
-
注意
-
反熵需要节点两两交换和比对自己所有的数据,执行反熵时通讯成本会很高,所以不建议在实际场景中频繁执行反熵,可以通过引入校验和(Checksum)等机制,降低需要对比的数据量和通讯消息等。
-
执行反熵时,相关的节点都是已知的,而且节点数量不能太多,如果是一个动态变化或节点数比较多的分布式环境(比如在 DevOps 环境中检测节点故障,并动态维护集群节点状态),这时反熵就不适用了。那么当你面临这个情况要怎样实现最终一致性呢?
- 答案就是谣言传播。
-
4.1、反熵案例说明
节点 A 通过反熵的方式,修复了节点 D 中缺失的数据
4.2、方式
001、推
数据源
就是将自己的所有副本数据,推给对方,修复对方副本中的熵
002、拉
数据源
就是拉取对方的所有副本数据,修复自己副本中的熵
003、推拉(常用)
数据源
就是同时修复自己副本和对方副本中的熵
4.3、项目如何使用 Anti-entropy 实现最终一致
在分布式存储系统中,实现数据副本最终一致性,最常用的方法就是反熵了
一份数据副本是由多个分片组成的,也就是实现了数据分片,三节点三副本的集群,就像下图的样子:
反熵的目标是确保每个 DATA 节点拥有元信息指定的分片,而且不同节点上,同一分片组中的分片都没有差异。比如说,节点 A 要拥有分片 Shard1 和 Shard2,而且,节点 A 的Shard1 和 Shard2,与节点 B、C 中的 Shard1 和 Shard2,是一样的。
那么,在 DATA 节点上,存在哪些数据缺失的情况呢?也就说,我们需要解决哪些问题呢?
我们将数据缺失,分为这样 2 种情况。
缺失分片:
也就是说,在某个节点上整个分片都丢失了。
节点之间的分片不一致:
也就是说,节点上分片都存在,但里面的数据不一样,有数据丢失的情况发生。
第一种情况修复起来不复杂,我们只需要将分片数据,通过 RPC 通讯,从其他节点上拷贝过来就可以了
需要注意的是第二种情况,因为第二种情况修复起来要复杂一些。我们需要设计一个闭环的流程,按照一个顺序修复,执行完流程后,就实现了一致性了。
它是按照一定顺序来修复节点的数据差异,先随机选择一个节点,然后循环修复,每个节点生成自己节点有、下一个节点没有的差异数据,发送给下一个节点,进行修复(为了方便演示,假设 Shard1、Shard2 在各节点上是不一致的)
从图中你可以看到,数据修复的起始节点为节点 A,数据修复是按照顺时针顺序,循环修复的。
注意
最后节点 A 又对节点 B 的数据执行了一次数据修复操作,因为只有这样,节点 C 有、节点 B 缺失的差异数据,才会同步到节点 B 上。
在实现反熵时,实现细节和最初算法的约定有些不同。比如,不是一个节点不断随机选择另一个节点,来修复副本上的熵,而是设计了一个闭环的流程,一次修复所有节点的副本数据不一致。
为什么这么设计呢?因为我们希望能在一个确定的时间范围内实现数据副本的最终一致性,而不是基于随机性的概率,在一个不确定的时间范围内实现数据副本的最终一致性。
这样做能减少数据不一致对监控视图影响的时长。
注意
反熵需要做一致性对比,很消耗系统性能,所以建议你将是否启用反熵功能、执行一致性检测的时间间隔等,做成可配置的,能在不同场景中按需使用。
五、谣言传播(Rumor-Mongering)
-
广泛地散播谣言,它指的是当一个节点有了新数据后,这个节点变成活跃状态,并周期性地联系其他节点向其发送新数据,直到所有的节点都存储了该新数据。
- 所有参与节点有三种状态:Suspective(病原)、Infective(感染)、Removed(愈除)。
- 过程是消息只包含最新 update,谣言消息在某个时间点之后会被标记为 removed,并且不再被传播。
- 缺点是系统有一定的概率会不一致
- 通常用于节点间数据增量同步。
-
谣言传播非常具有传染性,它适合动态变化的分布式系统。
5.1、举例
- 节点 A 向节点 B、D 发送新数据
- 节点 B 收到新数据后,变成活跃节点,然后节点 B 向节点 C、D 发送新数据。其实,
六、gossip 算法实现
下面分别是 Anti-Entropy(反熵) 和 Rumor-Mongering(谣言传播) 的实现伪代码
七、总结
Gossip是一种去中心化的分布式协议,数据通过节点像病毒一样逐个传播。因为是指数级传播,整体传播速度非常快
7.1、优点
- 扩展性:允许节点的任意增加和减少,新增节点的状态 最终会与其他节点一致。
- 容错:任意节点的宕机和重启都不会影响 Gossip 消息的传播,具有天然的分布式系统容错特性。
- 去中心化:无需中心节点,所有节点都是对等的,任意节点无需知道整个网络状况,只要网络连通,任意节点可把消息散播到全网。
- 一致性收敛:消息会以"一传十的指数级速度"在网络中传播,因此系统状态的不一致可以在很快的时间内收敛到一致。消息传播速度达到了 logN。
- 简单
7.2、缺点:
- 消息延迟:节点随机向少数几个节点发送消息,消息最终是通过多个轮次的散播而到达全网;不可避免的造成消息延迟。
- 消息冗余:节点定期随机选择周围节点发送消息,而收到消息的节点也会重复该步骤;不可避免的引起同一节点消息多次接收,增加消息处理压力。
7.3、协议可以支持以下需求
- Database replication
- 消息传播
- Cluster membership
- Failure 检测
- Overlay Networks
- Aggregations (比如计算平均值、最大值以及总和)
7.4、下面的工程上使用到了 gossip 协议。
- Riak(https://github.com/basho/riak) 使用 gossip 协议来共享和传递集群的环状态(ring state)和存储桶属性(bucket properties)。
- Cassandra:节点间的信息交换使用了 gossip 协议,因此所有节点都可以快速了解集群中的所有其他节点。
- Dynamo:采用基于 gossip 协议的分布式故障检测和成员协议,这样集群中添加或移除节点,其他节点可以快速检测到。
- Consul:使用了称为 SERF 的gossip 协议,主要有两个目的
- 发现新的节点或者发现故障节点
- 为一些重要的事件(比如 Leader 选举)传播提供可靠、快速的传播
- Amazon s3:使用 gossip 协议将服务的状态传递给系统