介绍
Gossip 是一种去中心化、保证最终一致性的分布式协议,其英文原意是 流言蜚语。它的作用就像其名字一样,流言一传十,十传百。Gossip 在 P2P网络和分布式系统中应用广泛 ,如人们熟知的 Bitcoin、Redis Cluster、Consul等
原理
在若干个可以相互通信的节点中,当某个种子节点需要将其数据和状态同步到其它节点时,它会在周围的节点中随机选择几个节点散播消息,收到消息的其它节点也会重复该动作,直至最终所有的网络节点都受到了消息 。这个过程可能需要一定的时间,由于不能保证某个时刻所有节点都收到消息,但是理论上最终所有节点都会收到消息,因此它是一个最终一致性协议。 (网上盗了个图)
通信模式
Push
节点 A 将数据已经对应的版本号发送给节点 B,B 节点更新 A 中比自己新的数据
Pull
节点 A 将当前的数据版本发给节点 B,节点 B 将高于这个版本的数据返回给 A,A节点更新本地数据
Push/Pull
结合 Push 和 Pull
A 将当前数据版本发送给 B
B 返回新数据,A更新
A 再将比 B 新的数据发送给 B,B更新
特点
优势
- 扩展性高:发送方节点向固定数量的接收方节点发送消息,与网络中的总节点数量无关。
- 容错:网络中任何节点的宕机和重启都不会影响 Gossip 消息的传播,Gossip 协议具有天然的分布式系统容错特性
- 去中心化: Gossip 协议不要求任何中心节点,所有节点都可以是对等的,任何一个节点无需知道整个网络状况,只要网络是连通的,任意一个节点就可以把消息散播到全网。
缺陷
- 消息的延迟:消息并不会立刻同步到所有的节点
- 消息冗余:由于 Gossip 协议是概率性的,因此可能会出现向同一个节点发送多次重复数据的情况
在 Redis 中的应用
在 Redis Cluster 的集群方式中,基于 Gossip 协议实现节点间的通信。所有节点都持有一份元数据,当某个节点的元数据发生了变更,九江元数据发送给其他节点,让其它节点进行数据变更
Redis Gossip消息分为消息头和消息体,消息体一共有4类,其中MEET
、FAIL
、PING
和PONG
meet:某个节点发送 meet 给新加入的节点,让新节点加入集群中,然后新节点就会开始与其它节点进行通信。
ping:每个节点都会频繁给其它节点发送 ping,其中包含自己的状态还有自己维护的集群元数据,互相通过 ping 交换元数据。
pong:返回 ping 和 meeet,包含自己的状态和其它信息,也用于信息广播和更新。
fail:某个节点判断另一个节点 fail 之后,就发送 fail 给其它节点,通知其它节点说,某个节点宕机啦。
ping 消息深入
ping 时要携带一些元数据,如果很频繁,可能会加重网络负担。
每个节点每秒会执行 10 次 ping,每次会选择 5 个最久没有通信的其它节点。当然如果发现某个节点通信延时达到了 cluster_node_timeout / 2
,那么立即发送 ping,避免数据交换延时过长,落后的时间太长了。比如说,两个节点之间都 10 分钟没有交换数据了,那么整个集群处于严重的元数据不一致的情况,就会有问题。所以 cluster_node_timeout
可以调节,如果调得比较大,那么会降低 ping 的频率。
每次 ping,会带上自己节点的信息,还有就是带上 1/10 其它节点的信息,发送出去,进行交换。至少包含 3
个其它节点的信息,最多包含 总节点数-2
个其它节点的信息。
参考: