Redis高可用高性能缓存的应用系列04 - Cluster模式,集群数据分布算法
概述
Redis高可用高性能缓存的应用系列的第4篇,主要介绍RedisCluster模式,集群数据分布算法,和Gossip协议的学习和介绍。
Redis cluster集群
- 无中心的结构,数据分散在各个节点上,并且保存了整个集群的状态,每个节点都和其他节点相连。
- 官方规定最小需要6个节点,3个主节点和3个从节点
- 各个节点时通过gossip协议交换数据的,数据分布采用哈希槽算法实现
哈希槽算法
Redis集群首先预设了16384个槽位,可以把他看成16384个箱子,每个里面可以放置很多Redis的key,假设有3个master,相当于Redis的3个仓库,按照平均分配的方式来分,当一个数据来存储时,根据Redis Key的路由公式,把值放进相应的箱子中,就可以了。
Redis Key的路由公式 crc16(key) % 16384
crc16的算法的Hash值最大是65535,为什么redis不创建65535个槽位呢? 首先,Redis需要把所有的节点信息放置在发送的心跳包中,方便节点知道集群的信息,压缩以后的大小为2k左右,虽然crc16的算法压65535压缩完后是8k,作者认为发送8k的心跳包会有浪费,另外一般情况下一个Redis集群也不会超过1000个Master节点,所以16384是比较适合的。
Gossip协议
Gossip协议,就像流言蜚语一样,利用一种随机、带有传染性的方式,将信息传播到整个网络中,并在一定时间内,使得系统内的所有节点数据一致,实现最终一致性。
所有的节点都持有一份元数据,不同的节点如果出现了元数据变更以后,就不断地将元数据发送给其他节点,让其他节点也进行元数据变更。
- 优点:元数据的更新比较分散,没有集中在一个点,更新会陆续的到所有的节点,因为有一定的延时,所以会降低压力。
- 缺点:有延时性,导致一些操作会滞后
每个节点都会维护一份集群的状态:
- 当前集群的状态
- 集群中各节点负责的slots信息和migrate状态
- 集群各节点的master和slave状态
- 集群各节点存货状态和怀疑Fail状态
Gossip协议命令
- MEET : 通过
cluster meet ip port
命令,已有集群的节点会像新的节点发送邀请,加入现有集群,然后新节点就会开始与其他节点进行通信。 - PING :节点按照配置的时间间隔向集群中其他节点发送ping消息,消息中带有自己的状态,还有自己维护的集群元数据,和部分其他节点的元数据。
- PONG : 节点用于回应PING和MEET的消息,结构和PING消息类似,也包含自己的状态和其他信息,也可以用于信息广播和更新。
- FAIL :节点PING不通某点节点后,会向集群所有节点广播该节点挂掉的消息,其他节点收到消息后标记已下线。
1.节点直接是怎么进行ping/pong消息的呢?
首先呢,每一个实例之间会按照一定的频率,从集群中随机挑选一些实例把ping消息发给新消息中的实例,检测这些实例是否在线,并交互彼此的状态信息。
比如图1节点1向节点2发送ping消息,ping消息中封装了发送消息的实例自身的状态消息以及solt映射表,节点2在接收到ping消息后会给节点1发送一个pong消息,pong消息和平消息的内容是一样的,这样就完成了一次交互。
2.是怎么新增节点的呢?
在节点1上执行了cluster meet ip port
,它首先为新节点创建cluster Node数据,并将这些数据添加到自己维护的Node字典中,然后节点1会根据ip和端口号会发送消息,新节点接收到meet消息后,新节点收到消息,也会为节点1的cluster node结构,并将该结构添加到自己维护的字典中。
新节点向节点1发送一个ping消息,节点1成功返回pong消息,节点1就知道了已经成功的接收到成功返回的pong消息,一个新节点的握手操作,转而向集群中的其他节点进行握手操作,最后新节点会被集群里所有节点认识。
3.节点是怎样下线的呢?
节点的下线有下线和疑似下线,Redis的节点中会定期发送ping消息的接收到,是否在规定时间内返回了pong消息,如果没有返回,标记成疑似下线(Pfail)状态。
节点1会把节点2,疑似下线的状态传递给其他节点,其他节点得知节点2处于疑似下线(Pfail)状态,修改本节点的cluster Node
结构体信息,并把节点2下线信息同步到下线节点列表中,会向集群中其他节点广播,节点2下线了。
转载自:https://juejin.cn/post/7220441273919012924