Redis 高可用架构系列(三)cluster集群

828次围观   6个点赞   0人评论

作者头像

zeal

1年前 发表于 技术专栏

Redis 高可用架构系列(三)cluster集群

828次围观   6个点赞   0人评论

作者头像

zeal

1年前 发表于 技术专栏

Redis 高可用架构系列(三)cluster 集群

目前我们已经搭建起来了哨兵模式的高可用架构,在主节点宕机的时候,选举新的主节点来为集群提供服务,但是可以思考下,哨兵模式还是存在几个问题,我们看看应该如何解决。

哨兵模式下的几个问题

一、访问瞬断问题

哨兵模式在主从切换的瞬间存在访问瞬断的情况,在主节点宕机的时候,虽然会有选举算法来选举出新的主节点,但是这个过程中,会有一个时间差,那么在真正的线上环境中,在主节点宕机到选出新的主节点这一段时间内,会导致集群不可用。

二、无法横向扩容

哨兵模式只能有一个主节点提供写操作,那么就无法支持很高的并发,且单个主节点内存也不宜设置得过大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率。

高可用 Cluster 集群模式

Cluster集群模式
Cluster集群模式

redis 集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。Redis 集群不需要 sentinel 哨兵 ∙ 也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过 1000 个节点)。redis 集群的性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单。

Redis 集群原理分析

Redis Cluster 将所有数据划分为 16384 个 slots(槽位),每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。

当 Redis Cluster 的客户端来连接集群时,它也会得到一份集群的槽位配置信息并将其缓存在客户端本地。这样当客户端要查找某个 key 时,可以直接定位到目标节点。同时因为槽位的信息可能会存在客户端与服务器不一致的情况,还需要纠正机制来实现槽位信息的校验调整。

一、槽位定位算法

Cluster 默认会对 key 值使用** crc16** 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。
HASH_SLOT = CRC16(key) mod 16384

为什么有 16384 个槽?

解释详情见https://www.cnblogs.com/rjzheng/p/11430592.html

1.如果槽位为 65536,发送心跳信息的消息头达 8k,发送的心跳包过于庞大。2.redis 的集群主节点数量基本不可能超过 1000 个。16384 个槽位够用了。没有必要拓展到 65536 个。3.槽位越小,节点少的情况下,压缩比高。

ps:文件压缩率指的是,文件压缩前后的大小比。

二、跳转重定位

当客户端向一个错误的节点发出了指令,该节点会发现指令的 key 所在的槽位并不归自己管理,这时它会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。客户端收到指令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有 key 将使用新的槽位映射表。

重定向
重定向

三、Redis 集群节点间的通信机制

维护集群的元数据(集群节点信息,主从角色,节点数量,各节点共享的数据等)有两种方式:集中式gossip

redis cluster 节点间采取gossip协议进行通信

集中式:

优点在于元数据的更新和读取,时效性非常好,一旦元数据出现变更立即就会更新到集中式的存储中,其他节点读取的时候立即就可以立即感知到;不足在于所有的元数据的更新压力全部集中在一个地方,可能导致元数据的存储压力。 很多中间件都会借助 zookeeper 集中式存储元数据。

gossip:

gossip 协议包含多种消息,包括 ping,pong,meet,fail 等等。

gossip协议
gossip协议

meet:某个节点发送 meet 给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通信;
ping:每个节点都会频繁给其他节点发送 ping,其中包含自己的状态还有自己维护的集群元数据,互相通过 ping 交换元数据(类似自己感知到的集群节点增加和移除,hash slot 信息等);
pong: 对 ping 和 meet 消息的返回,包含自己的状态和其他信息,也可以用于信息广播和更新; fail: 某个节点判断另一个节点 fail 之后,就发送 fail 给其他节点,通知其他节点,指定的节点宕机了。

gossip 协议的优点在于元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续,打到所有节点上去更新,有一定的延时,降低了压力;缺点在于元数据更新有延时可能导致集群的一些操作会有一些滞后。

Redis 集群选举原理分析

当 slave 发现自己的 master 变为 FAIL 状态时,便尝试进行 Failover,以期成为新的 master。由于挂掉的 master 可能会有多个 slave,从而存在多个 slave 竞争成为 master 节点的过程, 其过程如下:

1.slave 发现自己的 master 变为 FAIL2.将自己记录的集群 currentEpoch 加 1,并广播 FAILOVER_AUTH_REQUEST 信息3.其他节点收到该信息,只有 master 响应,判断请求者的合法性,并发送 FAILOVER_AUTH_ACK,对每一个 epoch 只发送一次 ack4.尝试 failover 的 slave 收集 master 返回的 FAILOVER_AUTH_ACK5.slave 收到超过半数 master 的 ack 后变成新 Master(这里解释了集群为什么至少需要三个主节点,如果只有两个,当其中一个挂了,只剩一个主节点是不能选举成功的)6.slave 广播 Pong 消息通知其他集群节点。

从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟,一定的延迟确保我们等待 FAIL 状态在集群中传播,slave 如果立即尝试选举,其它 masters 或许尚未意识到 FAIL 状态,可能会拒绝投票

延迟计算公式:
DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms
SLAVE_RANK 表示此 slave 已经从 master 复制数据的总量的 rank。Rank 越小代表已复制的数据越新。这种方式下,持有最新数据的 slave 将会首先发起选举(理论上)。


推荐阅读

Redis 高可用架构系列(一)主从架构Redis 高可用架构系列(二)哨兵模式聊一聊 Redis 基本类型和使用场景揭秘 Redis 的高性能Redis 的持久化原理


如果觉得文章对你有帮助,可以点个赞,转载请注名出处。

标签:
评论 (0)
在这里说点什么吧... (取消回复)
留下一个好听的昵称吧!
好听的昵称!
请输入正确的邮箱格式!
不错的邮箱!
评论内容不能为空!
理性发言,和谐讨论!