Loading

Redis集群

Redis集群

主从

单节点的Redis的并发能力是有限的,如果需要提供更高的并发能力,可以通过搭建Redis的主从集群,实现读写分离,从而提高Redis的并发能力。

主从复制

Redis节点和节点之间(可主从也可从此从,单向)的数据同步是通过RGB文件进行的

注意:在主从复制场景下,为了主从节点的数据一致性,从节点不会主动删除数据,而是由主节点控制从节点中过期数据的删除。从节点会等待主节点触发键过期。当主节点触发键过期时,主节点会同步一个del命令给所有的从节点。由于主节点的惰性删除和定期删除策略,都不能保证主节点及时对过期数据执行删除操作,因此,当客户端通过Redis从节点读取数据时,很容易读取到已经过期的数据。

Redis 3.2中,从节点在读取数据时,增加了对数据是否过期的判断:如果该数据已过期,则不返回给客户端;Redis 3.2 开始,通过从节点读取数据时,先判断数据是否已过期。如果过期则不返回客户端,并且删除数据。

数据同步阶段

主从节点之间的连接建立以后,便可以开始进行数据同步,该阶段可以理解为从节点数据的初始化。具体执行的方式是:从节点向主节点发送psync命令(Redis2.8以前是sync命令),开始同步。

数据同步阶段是主从复制最核心的阶段,根据主从节点当前状态的不同,可以分为全量复制和部分复制

需要注意的是,在数据同步阶段之前,从节点是主节点的客户端,主节点不是从节点的客户端;而到了这一阶段及以后,主从节点互为客户端。原因在于:在此之前,主节点只需要响应从节点的请求即可,不需要主动发请求,而在数据同步阶段和后面的命令传播阶段,主节点需要主动向从节点发送请求(如推送缓冲区中的写命令),才能完成复制。

全量复制

执行过程

增量复制

执行过程

命令传播阶段

数据同步阶段完成后,主从节点进入命令传播阶段;在这个阶段主节点将自己执行的写命令发送给从节点,从节点接收命令并执行,从而保证主从节点数据的一致性。主从是维持了一个长连接的。

哨兵

在主从集群的模式下,一旦主节点出现故障,就会导致整个集群不能对外提供写服务,数据也不能同步到各个从节点,出现瘫痪。需要手动将一个从节点晋升为主节点,同时需要修改应用方的主节点地址,还需要命令其他从节点去复制新的主节点,整个过程都需要人工干预。Redis提供了哨兵机制来帮助我们实现故障转移

架构如下

哨兵的作用

  • 监控:监控所有redis节点(包括sentinel节点自身)的状态是否正常。

  • 通知:通知slave新的master连接信息,让它们执行replicaof成为新的master的slave。

  • 配置提供:客户端连接sentinel请求master的地址,如果发生故障转移, sentinel会通知新的

  • 故障转移:如果一个master出现故障,Sentinel会帮助我们实现故障转移,自动将某一 台slave升级为master,确保整个Redis系统的可用性。级为master,确保整个Redis系统的可用性。

检测节点下线和选举Master

下线的判断规则

  1. 主观下线
    每个Sentinel节点会每隔1秒对主节点、从节点、其他Sentinel节点发送ping命令做心跳检测,当这些节点超过 down-after-milliseconds没有进行有效回复,Sentinel节点就会对该节点做失败判定,这个行为叫做主观下线。
  2. 客观下线
    当Sentinel主观下线的节点是主节点时,该Sentinel节点会通过sentinel is- master-down-by-addr命令向其他Sentinel节点询问对主节点的判断,当超过 个数(一般认为是超过一半),Sentinel节点认为主节点确实有问题,这时该Sentinel节点会做出客观下线的决定

判断主节点下线后需要选取新的Master节点

  1. 过滤:“不健康”(主观下线、断线)、5秒内没有回复过Sentinel节 点ping响应、与主节点失联超过down-after-milliseconds*10秒。
  2. 选择slave-priority(从节点优先级)最高的从节点列表,如果存在则返回,不存在则继续。
  3. 选择复制偏移量(offset)最大的从节点(复制的最完整),如果存在则返 回,不存在则继续。
  4. 选择runid最小的从节点。

脑裂

哨兵模式可能存在脑裂问题。具体表现为主节点与哨兵之间因为网络问题导致网络分区,哨兵节点从而认为主节点已经不可用,进而从从节点中选取一个新的主节点,再此期间原来的主节点中可能有新的数据,等到网络恢复的时候,原来的主节点会被降为从节点,从而导致数据丢失。

如何应对脑裂
脑裂的主要原因其实就是哨兵集群认为主节点已经出现故障了,重新选举其它从节点作为主节点,而原主节点其实是假故障,从而导致短暂的出现两个主节点,那么在主从切换期间客户端一旦给原主节点发送命令,就会造成数据丢失。
所以应对脑裂的解决办法应该是去限制原主库接收请求,Redis提供了两个配置项。
min-slaves-to-write:与主节点通信的从节点数量必须大于等于该值主节点,否则主节点拒绝写入。
min-slaves-max-lag:主节点与从节点通信的ACK消息延迟必须小于该值,否则主节点拒绝写入。
这两个配置项必须同时满足,不然主节点拒绝写入。

在假故障期间满足min-slaves-to-write和min-slaves-max-lag的要求,那么主节点就会被禁止写入,脑裂造成的数据丢失情况自然也就解决了。

分片集群

前两种集群模式虽然已经能够很大程度上提高Redis的并发能力,但是事实上随着业务的发展,系统越来越庞大,主节点的写能力受到单机的限制。主节点的存储能力受到单机的限制。带来了新的问题。我们可以采用分片集群的方式来处理。

架构图

Redis 切片集群 就是部署多台 Redis 主节点(master),这些节点之间平等,并没有主从之说,同时对外提供读/写服务。缓存的数据库相对均匀地分布在这些 Redis 实例上,客户端的请求通过路由规则转发到目标 master 上。为了保障集群整体的高可用,我们需要保证集群中每一个 master 的高可用,可以通过主从复制给每个 master 配置一个或者多个从节点(slave)。

分片

采用的是 哈希槽分区 ,每一个键值对都属于一个 hash slot(哈希槽) 。

Redis Cluster 通常有 16384 个哈希槽 ,要计算给定 key 应该分布到哪个哈希槽中,我们只需要先对每个 key 计算 CRC-16(XMODEM) 校验码,然后再对这个校验码对 16384(哈希槽的总数) 取模,得到的值即是 key 对应的哈希槽。

假设集群有 3 个 Redis 节点组成,每个节点负责整个集群的一部分数据,哈希槽可能是这样分配的(这里只是演示,实际效果可能会有差异):

●Node 1 : 0 - 5500 的 hash slots
●Node 2 : 5501 - 11000 的 hash slots
●Node 3 : 11001 - 16383 的 hash slots

哈希槽的计算公式如下:

HASH_SLOT = CRC16(key) mod NUMER_OF_SLOTS

posted @ 2023-09-21 13:27  花园SON  阅读(16)  评论(0编辑  收藏  举报