介绍

Gossip 是一种去中心化、保证最终一致性的分布式协议,其英文原意是 流言蜚语。它的作用就像其名字一样,流言一传十,十传百。Gossip 在 P2P网络和分布式系统中应用广泛 ,如人们熟知的 Bitcoin、Redis Cluster、Consul等

原理

在若干个可以相互通信的节点中,当某个种子节点需要将其数据和状态同步到其它节点时,它会在周围的节点中随机选择几个节点散播消息,收到消息的其它节点也会重复该动作,直至最终所有的网络节点都受到了消息 。这个过程可能需要一定的时间,由于不能保证某个时刻所有节点都收到消息,但是理论上最终所有节点都会收到消息,因此它是一个最终一致性协议。 (网上盗了个图)

通信模式

Push

节点 A 将数据已经对应的版本号发送给节点 B,B 节点更新 A 中比自己新的数据

Pull

节点 A 将当前的数据版本发给节点 B,节点 B 将高于这个版本的数据返回给 A,A节点更新本地数据

Push/Pull

结合 Push 和 Pull

  1. A 将当前数据版本发送给 B

  2. B 返回新数据,A更新

  3. A 再将比 B 新的数据发送给 B,B更新

特点

优势

  • 扩展性高:发送方节点向固定数量的接收方节点发送消息,与网络中的总节点数量无关。
  • 容错:网络中任何节点的宕机和重启都不会影响 Gossip 消息的传播,Gossip 协议具有天然的分布式系统容错特性
  • 去中心化: Gossip 协议不要求任何中心节点,所有节点都可以是对等的,任何一个节点无需知道整个网络状况,只要网络是连通的,任意一个节点就可以把消息散播到全网。

缺陷

  • 消息的延迟:消息并不会立刻同步到所有的节点
  • 消息冗余:由于 Gossip 协议是概率性的,因此可能会出现向同一个节点发送多次重复数据的情况

在 Redis 中的应用

在 Redis Cluster 的集群方式中,基于 Gossip 协议实现节点间的通信。所有节点都持有一份元数据,当某个节点的元数据发生了变更,九江元数据发送给其他节点,让其它节点进行数据变更

Redis Gossip消息分为消息头和消息体,消息体一共有4类,其中MEETFAILPINGPONG

  • 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 个其它节点的信息。

参考:

https://zhuanlan.zhihu.com/p/41228196

http://www.ymcall.com/artinfo/780867682346446665.html