Gossip 是一种被用在分布式的非强一致性系统中用来同步各节点状态的方法。
因为在去中心化的集群环境里,各节点“实时”地洞察其他节点的重要信息是非常重要的。这消息包括:
- 节点的心跳
- 节点的状态(失效检查/live/dead)
- 节点当前负载
Gossip被设计成低 CPU开销和低网络带宽占用。因此非常适合大型的P2P 网络。Gossip周期地随机地选择一个节点并发起一轮Gossip会话,一个 Gossip包括3个消息。比如 NodeA向 Node B发起一个Gossip:
- A → B GossipRequestMessage
- B → A GossipAckMessage
- A → B GossipResponseMessage
并且,基于以上来来回回的消息传送来探测失效与否。
协议
1GossiperSummary
节点的概要信息
Ip
Node ip address
generation
代:
如果更新,代表一个大的状态改动,如 data model更动
version
版本:
一个小的状态版本更新,比如节点 restart
2 GossipAppState
应用状态消息
HeartBeat
心跳:
generation
version
event
Status (状态事件):bootstrap/join/leaving/moving/removing/..
load (负载事件)
datamodel (数据模型事件)
3GossiperRequestMessage
由 gossiper生成,发送给 gossipee
List<GossiperSummary>包含发起节点的当前状态
4GossipeeAckMessage
在收到 gossiper的请求后,由 gossipee生成,并发回给 gossiper
List<GossiperSummary>in
包含与进来的GossiperRequestMessage的差值,即本地节点(gossipee)的信息已经过时,发起者(gossiper)有更新的信息,需要同步进来。
Map<Ip,GossipAppState> out
本地节点(gossipee)有更新的 GossipAppState信息,需要同步回给发起者(gossiper)
5GossiperResponseMessage
在收到 gossipee的响应后,由 gossiper生成
Map<Ip,GossipAppState> out
回传给gossipee请求的差异部分(即gossipee发现 gossiper有更新的 GossipAppState信息,要求gossiper回传)
处理流程
1. gossiper基于自己本地缓存的系统拓扑信息,为其缓存的每个节点分别创建GossiperSummary,再基于这个列表,创建出GossiperRequestMessage
2. 向各个live节点发送GossiperRequestMessage
3. 接收方gossipee解析请求消息,合计出自己过时了的状态信息GossiperSummary
4. 接收方gossipee 同时计算出自己比gossiper (发送方)的更新的状态信息GossipAppState
5. gossipee基于上述计算,创建出GossipeeAckMessage
6. gossipee向 发送方发送 GossipeeAckMessage 消息
7. 发送方基于gossipee送过来的 GossipAppState 更新自己状态
8. 发送方根据gossipee的请求,计算出GossipAppState (此信息即是gossipee过时了的状态)
9. 发送方 基于上述计算,创建GossiperResponseMessage信息
10. 发送方向gossipee发送 GossiperResponseMessage信息
11. gossipee根据发送方回送过来的GossipAppState 更新自己状态