参考
码哥字节:https://xie.infoq.cn/article/1c714709d00b2b55e8416fb99
小林coding: https://xiaolincoding.com/redis/cluster/sentinel.html
为什么要有哨兵?
在 Redis 的主从架构中,由于主从模式是读写分离的,如果主节点(master)挂了,那么将没有主节点来服务客户端的写操作请求,也没有主节点给从节点(slave)进行数据同步了。
这时如果要恢复服务的话,需要人工介入:
- 选择一个「从节点」切换为「主节点」
- 让其他从节点指向新的主节点
- 通知上游那些连接 Redis 主节点的客户端,将其配置中的主节点 IP 地址更新为「新主节点」的 IP 地址。
这样也不太“智能”了,要是 有一个节点能监控「主节点」的状态,当发现主节点挂了 ,它自动将一个「从节点」切换为「主节点」的话,那么可以节省我们很多事情啊!
Redis 在 2.8 版本以后提供的 哨兵(Sentinel)机制,它的作用是实现 主从节点故障转移。它会监测主节点是否存活,如果发现主节点挂了,它就会选举一个从节点切换为主节点,并且把新主节点的相关信息通知给从节点和客户端。
哨兵节点主要负责三件事情:监控、选主、通知。
如何判断主节点真的故障了?(监控)
哨兵会每隔 1 秒给所有主从节点发送 PING 命令,当主从节点收到 PING 命令后,会发送一个响应命令给哨兵,这样就可以判断它们是否在正常运行。
如果主节点或者从节点没有在规定的时间内响应哨兵的 PING 命令,哨兵就会将它们标记为「主观下线」。这个「规定的时间」是配置项 down-after-milliseconds
参数设定的,单位是毫秒
那什么是客观下线?
哨兵在部署的时候不会只部署一个节点,而是用多个节点部署成哨兵集群(最少需要三台机器来部署哨兵集群),通过多个哨兵节点一起判断,就可以就可以避免单个哨兵因为自身网络状况不好,而误判主节点下线的情况。
当一个哨兵判断主节点为「主观下线」后,就会向其他哨兵发起 is-master-down-by-addr 命令,其他哨兵收到这个命令后,就会根据自身和主节点的网络状况,做出赞成投票或者拒绝投票的响应。
当这个哨兵的赞同票数达到哨兵配置文件中的 quorum (这里不需要过半)配置项设定的值后,这时主节点就会被该哨兵标记为「客观下线」。
PS:quorum 的值一般设置为哨兵个数的二分之一加1,例如 3 个哨兵就设置 2。
哨兵判断完主节点客观下线后,哨兵就要开始在多个「从节点」中,选出一个从节点来做新主节点。
哨兵选主
由哪个哨兵作为 Leader 来进行主从故障转移?
哨兵的选举采用的是Raft算法,Raft是一个用户管理日志一致性的协议,它将分布式一致性问题分解为多个子问题:Leader选举、日志复制、安全性、日志压缩等。Raft将系统中的角色分为领导者(Leader)、跟从者(Follower)和候选者(Candidate).......
大致简单过程
- 每个做主观下线的sentinel节点像其他sentinel节点发送命令,要求将自己设置为领导者
- 接收到的sentinel可以同意或者拒绝
- 如果该sentinel节点发现自己的 (1)票数已经超过半数 并且 (2)超过了quorum
- 如果此过程选举出了多个领导者,那么将等待一段时重新进行选举
为什么哨兵节点至少要有 3 个?
只有 2 个哨兵节点,此时如果一个哨兵想要成功成为 Leader,必须过半,也就是说得获得 2 票,而不是 1 票。如果哨兵集群中有个哨兵挂掉了,那么就只剩一个哨兵了,如果这个哨兵想要成为 Leader,这时票数就没办法达到 2 票,就无法成功成为 Leader,这时是无法进行主从节点切换的。
因此,通常我们至少会配置 3 个哨兵节点。这时,如果哨兵集群中有个哨兵挂掉了,那么还剩下两个个哨兵,如果这个哨兵想要成为 Leader,这时还是有机会达到 2 票的,所以还是可以选举成功的,不会导致无法进行主从节点切换。
Redis 1 主 4 从,5 个哨兵 :
- quorum 设置为 2,如果 2 个哨兵故障,当主节点宕机时,如果有 3 个哨兵故障的话。此时哨兵集群还是可以判定主节点为“客观下线”(投票可以超过 quorum),但是哨兵不能完成主从切换(但是票数不可以过半)。所以既然怎么样都不能完成主从切换的话(怎么样都不能过半),判定为客观下线相当于是做了无用功。
- quorum 设置为 3,如果 2 个哨兵故障,当主节点宕机时,如果有 3 个哨兵故障的话。此时哨兵集群不可以判定主节点为“客观下线”,也不能完成主从切换。
所以,quorum 的值建议设置为哨兵个数的二分之一加1,例如 3 个哨兵就设置 2,5 个哨兵设置为 3,而且哨兵节点的数量应该是奇数。
主节点故障如何进行主从切换?
主从故障转移操作包含以下四个步骤:
- 第一步:在已下线主节点(旧主节点)属下的所有「从节点」里面,挑选出一个从节点,并将其转换为主节点。
- 第二步:让已下线主节点属下的所有「从节点」修改复制目标,修改为复制「新主节点」;
- 第三步:将新主节点的 IP 地址和信息,通过「发布者/订阅者机制」通知给客户端;
- 第四步:继续监视旧主节点,当这个旧主节点重新上线时,将它设置为新主节点的从节点;
步骤一:从故障主节点的从节点中选出新的主节点
首先过滤掉网络状况不好的从库:
-
从库当前在线状态,下线的直接丢弃;
-
评估之前的网络连接状态 down-after-milliseconds * 10:如果从库总是和主库断连,而且断连次数超出了一定的阈值(10 次),我们就有理由相信,这个从库的网络状况并不是太好,就可以把这个从库筛掉了。
然后进行几轮评估:
- 有个叫 slave-priority 配置项,可以给从节点设置优先级。每一台从节点的服务器配置不一定是相同的,我们可以根据服务器性能配置来设置从节点的优先级。
- 如果 1 同,比较谁的复制进度更接近之前的主节点,即 某个从节点的 slave_repl_offset 最接近之前主节点的 master_repl_offset
- 如果 2 同,比较用来唯一标识从节点的 ID 号
在选举出从节点后,哨兵 leader 向被选中的从节点发送 SLAVEOF no one
命令,让这个从节点解除从节点的身份,将其变为新主节点。
在发送 SLAVEOF no one
命令之后,哨兵 leader 会以每秒一次的频率向被升级的从节点发送 INFO
命令(没进行故障转移之前,INFO
命令的频率是每十秒一次),并观察命令回复中的角色信息,当被升级节点的角色信息从原来的 slave 变为 master 时,哨兵 leader 就知道被选中的从节点已经顺利升级为主节点了。
步骤二:将其余从节点指向新主节点
哨兵 leader 向其余所有从节点发送 SLAVEOF
,让它们成为新主节点的从节点。
通过 Redis 的发布者/订阅者机制来实现的。每个哨兵节点提供发布者/订阅者机制,客户端可以从哨兵订阅消息。
标签:可用,新主,Redis,主从,故障,哨兵,下线,节点 From: https://www.cnblogs.com/suBlog/p/17464167.html