本文看下用来解决分布式环境下共识问题的Gossip协议,其一般用在非中心式结构,即去中心化的分布式体系结构中。在redis cluster ,Consul等分布式软件中都使用了该协议。接下来我们一起看下。
Gossip是分布式环境中的一种数据共识协议,用来解决让多个节点对某个值达成共识。其过程类似于新冠病毒的感染,一个人传染给3个人,3个人又分别传染给3个人,最终传染给所有人。这里新冠病毒就相当于分布式环境中需要同步的数据,被传染了新冠病毒的人就相当于分布式环境中的节点。为了更好地理解Gossip协议,我们可以先来看下六度分隔理论
,六度分割理论是社会学中一个理论,其表达的是,一个人如果是想要认识一个陌生人的话,最多只需要通过6个人,比如我现在想要认识阿里某技术大牛,可以这样:
第1个人:老板,老板给马云讲过课
第2个人:马云,通过马云就能认识到想认识的某阿里技术大牛。
我。。草,直接认识马云他不香吗?
Gossip原理如下:
1:随机选择N个节点,将数据传给N个节点
2:收到数据的N个节点,重复1
3:经过若干次的重复,所有节点都接收到了消息
以上的N
,叫做fanout [fænaʊt],扇形散开的意思,假设总节点数是A,则需要循环的次数是log(A)base(N)
,即以fanout N为底数的对数值,可以看到当fanout值越大时,需要循环的次数也越小,且因为是对数,所以随着A的增大需要循环的次数增加非常缓慢,如下图是fanout为4时不同的A需要循环的次数:
假设我们有20个节点,fanout等于4,如下图:
第一次传播假设是4条粗线:
新增了4个被感染节点,此时有5个红色被感染节点,如下图:
最终经过3次传播后,所有节点都被感染,都变成红色,如下图:
这样数据就同步到所有节点了。
这个感染的过程是不是很像六度分割理论中找人的过程,感染了所有节点就相当于是找到所有人。
因为Gossip完成传播的次数是log(A)base(N)
,当需要传播的节点总数变多时,传播的总次数并不会有很大增加,所以具备很强的扩展性,如下图:
因为会传播多次,且一个节点可能会收到多次传播的消息,所以,即使因为网络等问题,某次传播的消息某些节点没有收到,也没有任何关系,所以具备容错能力。
因为并没有具有特殊角色的节点(如leader),所以新节点的加入,或者是个别节点的退出,都不会影响整个集群的正常工作,消息还是可以正常传播到集群中的所有节点。
出现这个问题的原因是,当节点选择一组节点来传播消息时,并不知道当前都有哪些节点已经接收过消息了,因此只需要在传播消息时,除了携带数据外,同时携带已经接收过消息的节点信息即可,比如A传播给BC消息,则携带如已接收消息节点集合(ABC)
这种消息就可以了,而C传播给EF,则携带如已接收消息节点集合(ABCEF)
这种消息就可以了。
如果这样做了,又会带来另外一个问题,即,如果某节点的消息丢失了,因为不会进行第二次消息传播,则该节点将会无法接收到消息。
参考文章列表:
图解Gossip:可能是最有趣的一致性协议 。