当前位置: 首页 > 后端技术 > Java

Gossip算法及其在Redis集群中的应用

时间:2023-04-01 13:56:09 Java

Gossip的一些特点在有界网络中,每个节点随机与其他节点通信,经过一段时间的无序通信后,所有节点的状态最终会达到一致,即使某些节点宕机或新节点加入后重启,这些节点的状态会在一段时间后与其他节点达成一致。从这一点来看,Gossip自然具有分布式容错的优势。根据上面的描述,我们知道Gossip是一种最终一致性算法,不能保证某一时刻所有节点状态一致,但可以保证最终一致性。另外,Gossip不要求节点认识所有其他节点,因此具有去中心化的特点,节点之间完全平等,没有任何中心节点。不过,Gossip的缺点也很明显。冗余通信会对网络带宽和CPU资源造成很大的负载。根据一些数据,当集群规模超过数百个节点时,Gossip协议的效率将非常显着。降低,通信成本越来越高(节点间的定时任务每秒执行10次,即以100ms的频率执行)。Gossip节点的三种通信方式两个节点(A,B)之间有三种通信方式:push:A节点推送数据(key,value,version)和对应的版本号给B节点,B节点更新A的数据pullnewerthanitself:A只推送数据(key,version)给B,B推送本地比A更新的数据(key,value,version)给A,A更新本地push/pull:类似pull,只是多了一步,A将本地比B更新的数据推送给B,B更新本地。如果将两个节点的数据同步定义为一个周期,那么在一个周期内,push需要通信一次,pull需要通信2次,push/pull需要通信3次。但就效果而言,推/拉是最好的。理论上,一个循环可以使两个节点完全一致。Gossip在RedisCluster中的作用在分布式系统中,需要提供一种维护节点元数据信息的机制。所谓元数据是指节点负责哪些数据、主从属性、是否故障等状态信息。常见的元数据维护方式一般分为集中式和分散式。RedisCluster采用Gossip协议实现去中心化模式。详细来说,在RedisCluster中使用Gossip主要有两个作用:去中心化,实现分布式和弹性扩展故障检测,实现高可用的节点通信基础。RedisCluster中的每个实例监听两个TCP端口:6379用于服务客户端查询;16379用于集群内部通信。集群中节点的通信方式为:每个节点在固定周期内通过特定规则选择若干节点发送Ping消息,收到Ping消息的节点响应Pong消息。一个节点可能知道所有节点,也可能只知道部分节点,只要这些节点之间能正常通信,它们最终会达到一致状态。当节点故障、新节点加入、主从关系变化、槽信息变化等事件发生时,通过持续的Ping/Pong消息通信,所有节点会在一段时间后知道集群中所有节点的最新状态,从而达到集群状态同步的目的。选择节点通信的原则:当当前节点向另一个节点发送Ping报文时,其他节点携带的报文数量至少为3,最大等于集群节点总数-2为Ping消息体中选择的其他节点信息。采用混合选择模式:随机选择+偏好选择,既保证了Gossip协议的随机传播原则,又尽可能地传播了当前节点掌握的其他节点的故障信息。RedisClusterMeet消息中Gossip的消息类型:用于通知新节点加入。消息发送者通知接收者加入当前集群。Meet消息通信正常完成后,接收节点会加入集群并进行周期性的Ping和Pong消息交换Ping消息:集群中交换最频繁的消息,每个A节点每秒向多个其他节点发送Ping消息以检测节点是否在线并相互交换状态信息。Ping报文发送封装了自身节点和其他一些节点状态数据的Pong报文:当收到Ping、Meet报文时,会作为响应报文回复发送方,确认报文通信正常。Pong消息在内部封装了自己的状态数据。一个节点也可以向集群广播自己的Pong消息,通知整个集群更新自己的状态Fail消息:当一个节点判断集群中另一个节点离线时,会向集群广播一个Fail消息,其他的nodes收到Fail消息后,对应的node会更新为offline状态。由于集群需要频繁交换节点信息,而Ping/Pong消息中携带了当前节点和其他一些节点的状态数据,会增加带宽和计算的负担。Redis集群中的节点通信采用固定频率(定时任务每秒执行10次),因此节点选择每次需要通信的节点列表非常重要。虽然可以及时交换太多的通信节点,但成本太高。节点选择过少会降低集群中所有节点之间信息交换的频率,从而影响故障判断和新节点发现的速度。因此,Redis集群的Gossip协议需要兼顾实时信息交换和开销开销。最后关于redis集群的故障检测、failover和master选举可以看之前的文章:Redis学习集群参考文章:GossipAlgorithmGossipAlgorithmDistributedConsistencyProtocolGossip与Redis集群原理分析