redis       

redis

ppt

集群脑裂

当主从切换发生时,一定是有超过预设数量(quorum 配置项)的哨兵实例和主库的心跳都超时了,才会把主库判断为客观下线,然后,哨兵开始执行切换操作。哨兵切换完成后,客户端会和新主库进行通信,发送请求操作。

但是,在切换过程中,既然客户端仍然和原主库通信,这就表明,原主库并没有真的发生故障(例如主库进程挂掉)。

主从切换后,从库一旦升级为新主库,哨兵就会让原主库执行 slave of 命令,和新主库重新进行全量同步。而在全量同步执行的最后阶段,原主库需要清空本地的数据,加载新主库发送的 RDB 文件,这样一来,原主库在主从切换期间保存的新写数据就丢失了

Redis 已经提供了两个配置项来限制主库的请求处理,分别是 min-slaves-to-write 和 min-slaves-max-lag。

min-slaves-to-write:这个配置项设置了主库能进行数据同步的最少从库数量; min-slaves-max-lag:这个配置项设置了主从库间进行数据复制时,从库给主库发送 ACK 消息的最大延迟(以秒为单位)。 我们可以把 min-slaves-to-write 和 min-slaves-max-lag 这两个配置项搭配起来使用,分别给它们设置一定的阈值,假设为 N 和 T。这两个配置项组合后的要求是,主库连接的从库中至少有 N 个从库,和主库进行数据复制时的 ACK 消息延迟不能超过 T 秒,否则,主库就不会再接收客户端的请求了。

即使原主库是假故障,它在假故障期间也无法响应哨兵心跳,也不能和从库进行同步,自然也就无法和从库进行 ACK 确认了。这样一来,min-slaves-to-write 和 min-slaves-max-lag 的组合要求就无法得到满足,原主库就会被限制接收客户端请求,客户端也就不能在原主库中写入新数据了。

sentinel 有多个,具体谁来执行故障转移?

多个 sentinel 会选出一个 leader,具体的选举机制是依据 Raft 分布式一致性协议。

sentinel 是怎么发现 slave 和其他 sentinel 的?

通过上面的配置文件可以发现,只配置了 Redis master 的地址,并没有配置 slave 和其他 sentinel 的地址。

那是怎么知道的呢?

发现 slave 比较简单,通过询问 master 就可以得到 slave 的地址。

发现其他 sentinel 是通过“发布/订阅”机制实现的。

每个 sentinel 都会向 __sentinel__:hello 这个频道发送消息,每秒一次,报告自己的存在。

每个 sentinel 也会订阅这个频道,就可以发现其他的 sentinel 了。

  1. 故障节点主观下线
  2. 故障节点客观下线
  3. Sentinel集群选举Leader
  4. Sentinel Leader决定新主节点

选举过程

1、主观下线

Sentinel集群的每一个Sentinel节点会定时对redis集群的所有节点发心跳包检测节点是否正常。如果一个节点在down-after-milliseconds时间内没有回复Sentinel节点的心跳包,则该redis节点被该Sentinel节点主观下线。

2、客观下线

当节点被一个Sentinel节点记为主观下线时,并不意味着该节点肯定故障了,还需要Sentinel集群的其他Sentinel节点共同判断为主观下线才行。

该Sentinel节点会询问其他Sentinel节点,如果Sentinel集群中超过quorum数量的Sentinel节点认为该redis节点主观下线,则该redis客观下线。

如果客观下线的redis节点是从节点或者是Sentinel节点,则操作到此为止,没有后续的操作了;如果客观下线的redis节点为主节点,则开始故障转移,从从节点中选举一个节点升级为主节点。

3、Sentinel集群选举Leader

如果需要从redis集群选举一个节点为主节点,首先需要从Sentinel集群中选举一个Sentinel节点作为Leader

每一个Sentinel节点都可以成为Leader,当一个Sentinel节点确认redis集群的主节点主观下线后,会请求其他Sentinel节点要求将自己选举为Leader。被请求的Sentinel节点如果没有同意过其他Sentinel节点的选举请求,则同意该请求(选举票数+1),否则不同意。

如果一个Sentinel节点获得的选举票数达到Leader最低票数(quorumSentinel节点数/2+1的最大值),则该Sentinel节点选举为Leader;否则重新进行选举。

image-20220329150831045

4、Sentinel Leader决定新主节点

Sentinel集群选举出Sentinel Leader后,由Sentinel Leader从redis从节点中选择一个redis节点作为主节点:

  1. 过滤故障的节点

  2. 选择优先级slave-priority最大的从节点作为主节点,如不存在则继续

  3. 选择复制偏移量(数据写入量的字节,记录写了多少数据。主服务器会把偏移量同步给从服务器,当主从的偏移量一致,则数据是完全同步)最大的从节点作为主节点,如不存在则继续

  4. 选择runid(redis每次启动的时候生成随机的runid作为redis的标识)最小的从节点作为主节点

    image-20220329150810102

    为什么Sentinel集群至少3节点

一个Sentinel节选举成为Leader的最低票数为quorumSentinel节点数/2+1的最大值,如果Sentinel集群只有2个Sentinel节点,则

Sentinel节点数/2 + 1= 2/2 + 1= 2

Leader最低票数至少为2,当该Sentinel集群中由一个Sentinel节点故障后,仅剩的一个Sentinel节点是永远无法成为Leader

也可以由此公式可以推导出,Sentinel集群允许1个Sentinel节点故障则需要3个节点的集群;允许2个节点故障则需要5个节点集群。

https://blog.css8.cn/post/2305362.html

集群选主

集群选举的处理 在 RedisCluster 集群实现原理 中提到过从节点通过选举晋升为主节点的过程,其处理大致如下:

Slave 节点在每个周期任务中都会检查 Master 节点是否 FAIL,如是则尝试进行 Failover,以期成为新的 Master。不过在此之前需要过滤可用的 Slave 节点,具体做法就是检查每个 Slave 节点与 Master 节点断开连接的时间,如果超过了cluster-node-timeout * cluster-slave-validity-factor,那这个Slave 节点就没有资格切换成 Master 由于挂掉的 Master 可能会有多个 Slave 节点,所以在 Slave 节点发起选举前需要根据所有 Slave 节点的复制偏移量确定一个选举的优先级,Slave 节点的优先级越小则其发起选举的时间越靠前 当 Slave 节点到达其选举时间时,将自身的 currentEpoch 变量(该变量可视作集群所处版本的记录)自增,然后向集群中所有的节点发送 CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST 消息,请求其他集群节点进行投票 所有集群节点都会收到广播消息,但是只有 Master 节点会对其进行回应。Master 节点首先确定自身 currentEpoch 变量 是否小于广播消息中请求投票的 Slave 节点的currentEpoch 变量 ,再加上其他一些校验最终确定是否为 Slave 节点投票。如果决定投票,则回复 CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK 消息 Slave 节点发出广播后,会定时检查其他节点返回的消息,并更新其计票器 server.cluster->failover_auth_count 当 Salve节点获得的票数超过了集群内 Master 节点总数的一半,则认为选举胜出,其自身将切换为 Master 节点,并广播主从切换完成的消息

image-20220329152600017

hystrix完成对redis访问的资源隔离

事前,事中,事后三个层次去思考怎么来应对缓存雪崩的场景

redisson

image-20220224135430028

https://www.cnblogs.com/sunliyuan/p/11594502.html

https://zhuanlan.zhihu.com/p/135864820