Gossip协议

     Gossip是一个带冗余的容错算法,最终一致性算法。虽然无法保证在某个时刻所有节点状态一致,但可以保证在”最终“所有节点一致,”最终“是一个现实中存在,但理论上无法证明的时间点。因为Gossip不要求节点知道所有其他节点,因此又具有去中心化的特点,节点之间完全对等,不需要任何的中心节点。Gossip可以用于众多能接受“最终一致性”的领域:失败检测、路由同步、Pub/Sub、动态负载均衡。


Gossip的特点

     在一个有界网络中,每个节点都随机地与其他节点通信,经过一番杂乱无章的通信,最终所有节点的状态都会达成一致。每个节点可能知道所有其他节点,也可能仅知道几个邻居节点,只要这些节可以通过网络连通,最终他们的状态都是一致的。


Gossip的缺点
       Gossip的缺点也很明显,冗余通信会对网路带宽、CPU资源造成很大的负载,而这些负载又受限于通信频率,该频率又影响着算法收敛的速度,后面我们会讲在各种场合下的优化方法。


Gossip通信方式:
      Gossip节点的通信方式及收敛性
两个节点(A、B)之间存在三种通信方式:
push: A节点将数据(key,value,version)及对应的版本号推送给B节点,B节点更新A中比自己新的数据
pull:A仅将数据key,version推送给B,B将本地比A新的数据(Key,value,version)推送给A,A更新本地
push/pull:与pull类似,只是多了一步,A再将本地比B新的数据推送给B,B更新本地
如果把两个节点数据同步一次定义为一个周期,则在一个周期内,push需通信1次,pull需2次,push/pull则需3次,从效果上来讲,push/pull最好,理论上一个周期内可以使两个节点完全一致。直观上也感觉,push/pull的收敛速度是最快的。
(akka Cassandra都是采用的push/pull这种通信方式)


Gossip工作方式:
      Gossip的节点的工作方式又分两种:
Anti-Entropy(反熵):仅传播新到达的数据  
Rumor-Mongering(谣言传播):以固定的概率传播所有的数据
(注,网上些文章把上面两种的工作方式搞反了)


Anti-Entropy(反熵)又分为两种具体的工作(Reconciliation 和解/协调)方式:
     精确(Precise Reconciliation)
在每次通信周期内都非常准确地消除双方的不一致性,具体表现为相互发送对方需要更新的数据,因为每个节点都在并发与多个节点通信,理论上这很难做到。精确协调需要给每个数据项独立地维护自己的version,在每次交互是把所有的(key,value,version)发送到目标进行比对,从而找出双方不同之处从而更新。因为Gossip消息存在大小限制,因此每次选择发送哪些数据就成了问题。当然可以随机选择一部分数据,也可确定性的选择数据。对确定性的选择而言,可以有最老优先(根据版本)和最新优先两种,最老优先会优先更新版本最新的数据,而最新更新正好相反,这样会造成老数据始终得不到机会更新,也即饥饿。
当然,开发这也可根据业务场景构造自己的选择算法,但始终都无法避免消息量过多的问题。
     整体(Scuttlebutt Reconciliation)
不是为每个数据都维护单独的版本号,而是为每个节点上的宿主数据维护统一的version。比如节点P会为(p1,p2,...)维护一个一致的全局version,相当于把所有的宿主数据看作一个整体,当与其他节点进行比较时,只需必须这些宿主数据的最高version,如果最高version相同说明这部分数据全部一致,否则再进行精确协调。
整体协调对数据的选择也有两种方法:
广度优先:根据整体version大小排序,也称为公平选择

你可能感兴趣的:(Gossip协议)