最新消息:

Redis Sentinel(哨兵)原理

IT技术 ipcpu 1049浏览

Redis Sentinel(哨兵)原理.md

一、Redis Sentinel概述

Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。

二、Sentinel主要功能

sentinel的主要功能:

监控(Monitoring): sentinel 会不断地检查Master和Slave是否运作正常。

通知(Notification):当被监控的某个Redis实例出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。

自动故障迁移(Automatic failover):当一个Master不能正常工作时,sentinel)会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master; 当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用Master代替失效Master。

配置中心(Configuration provider):如果故障转移发生了,sentinel会返回新的master地址。

很显然,只使用单个sentinel进程来监控redis集群是不可靠的,当sentinel进程宕掉后(sentinel本身也有单点问题,single-point-of-failure)整个集群系统将无法按照预期的方式运行。所以有必要将sentinel集群。

如下图,就是最常见的Sentinel的使用方式。

三、Sentinel原理

在Sentinel哨兵的运行阶段,其会向其他的Sentinel哨兵、master和slave发送消息确认其是否存活,如果在指定的时间内未收到正常回应,暂时认为对方挂起了(被标记为主观宕机–SDOWN)
当多个Sentinel哨兵(数量由quorum 参数设定)都报告同一个master没有响应了,通过投票算法(Raft算法),系统判断其已死亡(被标记为客观宕机–ODOWN)。

此时Sentinel集群会选取领头的哨兵(leader)进行故障恢复,从现有slave节点中选出(算法后续有介绍)一个提升为Master,并把剩余Slave都指向新的Master,继续维护主从关系。

四、Sentinel集群

redis的sentinel是一个分布式系统,可以在一个架构下运行多个sentinel进程,这些进程之间通过流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从slave服务器作为新的主服务器。

那么,Sentinel集群的 机器是如何发现集群中的其他机器呢?
使用广播?很显然不合适,既然是redis的产品,自然要充分运用redis功能,Sentinel集群节点利用了Redis master的发布/订阅机制去自动发现其它节点。

每个Sentinel使用发布/订阅的方式持续地传播master的配置版本信息,配置传播的发布/订阅管道是:sentinel:hello,我们可以通过订阅其频道查看频道中的消息,如下:

snetinel的状态会被持久化地写入sentinel的配置文件中。每次当收到一个新的配置时,或者新创建一个配置时,配置会被持久化到硬盘中,并带上配置的版本戳。这意味着,可以安全的停止和重启sentinel进程。

五、redis sentinel的主观下线和客观下线

redis sentinel关于被监控的redis实例出现不响应的判断,内部有两种不同的概念:主观下线和客观下线

主观下线(SDOWN):当只有单个sentinel实例对redis实例做出无响应的判断,此时进入主观判断,不会触发自动故障转移等操作。
一个服务器必须在 master-down-after-milliseconds 毫秒内, 一直返回无效回复才会被 Sentinel 标记为主观下线。

客观下线(ODOWN) :多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断。 (一个 Sentinel 可以通过向另一个 Sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否认为给定的服务器已下线)

从主观下线状态切换到客观下线状态并没有使用严格的法定人数算法(strong quorum algorithm), 而是使用了流言协议: 如果 Sentinel 在给定的时间范围内, 从其他 Sentinel 那里接收到了足够数量的主服务器下线报告, 那么 Sentinel 就会将主服务器的状态从主观下线改变为客观下线。 如果之后其他 Sentinel 不再报告主服务器已下线, 那么客观下线状态就会被移除。

客观下线条件只适用于主服务器: 对于任何其他类型的 Redis 实例, Sentinel 在将它们判断为下线前不需要进行协商, 所以从服务器Slave或者其他 Sentinel 永远不会达到客观下线条件。

六、领头哨兵选举

  在原理中提及到了,当sentinel发现主库客观下线时候会进行领头哨兵选举进行故障恢复,其选举算法采用Raft算法,这也为什么说其设计思想类似与zookpeer,选举过程大体如下:

6.1 发现主库客观下线的哨兵节点(这里称为A)向每个哨兵节点发送命令要求对方选举自己为领头哨兵(leader);
6.2 如果目标哨兵没有选举过其他人,则同意将A选举为领头哨兵;
6.3 如果A发现有超过半数且超过quorum参数值的哨兵节点同意选自己成为领头哨兵,则A哨兵成功选举为领头哨兵。
6.4 当有多个哨兵节点同时参与领头哨兵选举时,出现没有任何节点当选可能,此时每个参选节点等待一个随机时间进行下一轮选举,直到选出领头哨兵。

七、故障恢复时从Slave中间选出Master的算法

7.1 按照slave优先级进行排序,slave-priority越低,优先级就越高;
7.2 如果slave priority相同,那么比较复制偏移量,offset越靠后(越大)则表明和旧的主库数据同步越接近,优先级就越高 ;
7.3 如果上面两个条件都相同,那么选择一个run id最小的从库;

八、Sentinel集群部署

Sentinel部署很简单,只需要配置一下/etc/redis-sentinel.conf配置文件就可以了,如下

#工作端口
port 26379
#工作目录
dir "/var/lib/redis/sentinel"
#sentinel id ,建议注释掉,会自动生成
#sentinel myid 827f0104ad153f34db5a29b8cbb51ef21a31d6d5
#配置要监控的master名字和地址,最后一个2代表当sentinel集群中有2个sentinel认为master故障时候才判定master真正不可用。官方把该参数称为quorum,在后续选举领头哨兵时候会用到
sentinel monitor mymaster 10.130.2.155 6379 2
#配置master密码
sentinel auth-pass mymaster Password
#日志
logfile "/var/log/redis/sentinel.log"

配置完成后,使用systemctl start redis-sentinel启动即可。

Sentinel可以调整的相关参数

#主观SDOWN时间,单位毫秒,默认30秒。
sentinel down-after-milliseconds mymaster 30000

#在发生failover主备切换时候,最多允许多少个slave同时同步新的master。这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave处于不能处理命令请求的状态。
sentinel parallel-syncs mymaster 1


#failover-time超时时间,当failover开始后,在此时间内仍然没有触发任何failover操作,当前sentinel将会认为此次failover失败,单位毫秒。默认3分钟。
sentinel failover-timeout mymaster 180000

参考资料

https://minichou.github.io/2016/03/25/Redis%20Sentinel%E5%8E%9F%E7%90%86/
http://weizijun.cn/2015/04/30/Raft%E5%8D%8F%E8%AE%AE%E5%AE%9E%E6%88%98%E4%B9%8BRedis%20Sentinel%E7%9A%84%E9%80%89%E4%B8%BELeader%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90/
http://blog.fnil.net/blog/255ccfae971d6d30b0921120d327490b/
http://mdba.cn/2015/05/04/redis-sentinel%E5%9F%BA%E6%9C%AC%E5%91%BD%E4%BB%A4%E4%B8%8E%E5%8F%82%E6%95%B0/
https://www.cnblogs.com/ivictor/p/9755065.html
https://www.cnblogs.com/starlion/p/9091337.html
https://throwsnew.com/2017/11/21/%E5%9B%BE%E8%A7%A3redis%20sentinel/
https://www.cnblogs.com/wdliu/p/9555620.html

转载请注明:IPCPU-网络之路 » Redis Sentinel(哨兵)原理