携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
当没有哨兵机制的时候,redis的主从服务器出现故障时,需要手动进行恢复。
哨兵模式(Redis Sentinel)就是提供了监控主从服务器,提供主从节点故障转移的功能。
哨兵节点是如何工作的?
哨兵节点主要负责三件事情:监控、选主、通知
所以,了解哨兵机制,需要学习:
- 哨兵节点如何监控节点?如何判断主节点是否真的故障?
- 根据什么规则选择一个从节点切换为主节点?
- 怎么把新主节点的相关信息通知给从节点和客户端呢?
哨兵节点如何监控节点?如何判断主节点是否真的故障?
哨兵每秒给所有主从节点发送PING命令。当主从节点收到命令后,会返回一个响应命令,以此判断是否正常运行。
如何节点没有在规定时间(down-after-milliseconds d单位毫秒)响应哨兵的PING命令,哨兵就会将他们标记为 主观下线
\
有了主观下线,难道有客观下线?
存在客观下线,但是客观下线只适用主节点。
之所以针对主节点存在客观下线,是因为主节点在规定时间内没有响应PING命令可能只是因为网络拥塞等原因。为了减少误判才有客观下线。之所以从节点没有客观下线,可能是因为哨兵机制主要是为了主节点故障时的自动故障转移。从节点故障时不需要故障转移。
为了减少误判的情况,哨兵部署采用的是哨兵集群(至少三台机器来部署哨兵集群),能够尽量避免单个哨兵节点因网络原因导致的误判。
怎么判定为客观下线呢?
当一个哨兵判断一个主节点为主观下线后,就会向其他哨兵发起命令,其他哨兵根据和主节点的连通性做出赞成或者拒绝投票的响应。
当赞同票数达到哨兵配置文件中的quorum配置值后,主节点就会被发起投票的哨兵标记为客观下线。
quorum的值一般设置为哨兵个数的二分之一+1
例如,现有三个哨兵,quorum设置为2,一个哨兵判断主节点下线,只需再来一票赞成就能将主节点标记为客观下线。
这时就需要发起故障转移,选出一个从节点来做新主节点。
那由哪个哨兵进行主从故障转移呢?
为了减少主节点下线的误判,所以哨兵以哨兵集群的方式存在。
当判定主节点为客观下线后,需要故障转移,这时需要哨兵选出一个leader来执行主从切换。
成为leader也需要投票,从候选者开始选
谁来作为候选者呢?
一般哪个节点判断主节点为客观下线,这个哨兵节点就是候选者。候选者候选者候选者,重要的事情说三遍,这里选的是候选者!
候选者如何成为leader?
候选者会向其他哨兵发起命令,请求成为leader执行主从切换。
而每个哨兵在选取leader时只有一次投票机会,可以选择投给自己或者别人。
候选者成为leader需要满足以下两个条件:
- 第一,拿到半数以上的赞成票
- 第二,拿到票数大于等于哨兵配置文件中的quorum值。
下面举个例子,假设有3个哨兵节点,quorum设置为2,任何一个想成为leader的哨兵只要拿到两张就可以选举成功了。
如果在某个时间节点,刚好同时有两个哨兵节点判断主节点客观下线如何确定谁是leader?
由于每个人只要一票的机会,每位候选者都会先投给自己,然后向别人发起投票请求,假如候选者A向一个哨兵节点发起请求,哨兵节点投给他之后,候选者B再向其发起请求,就会被拒绝。
为什么哨兵节点至少有3个?
其实,通过上面的内容已经能够解释,为什么至少需要3个哨兵节点。
假如只有两个哨兵,如果想成为leader,必须有两票,如果当一个哨兵挂掉了,谁也不能成为leader,自然完成不了主从节点的切换。
下面练习一下,Redis1主4从,5个哨兵,quorum设置为3,如果2个哨兵故障,当主节点宕机时,哨兵能否判断主节点“客观下线”?主从能否自动切换?
- 可以判定主节点“客观下线”。当哨兵集群剩下3个,当主节点主观下线后,有可能拿到3张赞同票
- 哨兵集群可以完成主从切换。当有个哨兵标记为客观下线后,就会进行leader选举,剩下3个,有机会拿到3个选票。
这里有个问题:
如果quorum为2,并且有3个哨兵故障的话,虽然可以判定主节点为客观下线,但不能完成主从切换,所以这样的设置是没有意义的,应该尽量避免。
所以quorum的值应设置为哨兵个数的二分之一加一,即为奇数。
主从故障转移的过程是怎样的?
- 从旧主节点属下的从节点里面,挑选一个从节点,并将其转换为主节点。
- 让已下线主节点属下的所有从节点修改复制目标,修改为复制新主节点
- 将新主节点的IP地址和信息,通过发布者/订阅者机制通知给客户端
- 继续监视旧主节点,当这个旧主节点重新上线时,将它设置为新主节点的从节点。
详解:
步骤1:选出新节点
找出新节点成为主节点,为了防止多次的主从切换,应该首先把已经下线的从节点过滤掉,然后过滤掉以往网络连接状态不好的从节点。
如何判断从节点,遗忘的网络连接状态不好呢?
redis有个叫down-after-millisecos * 10 的配置项,down-after-millisecos 的配置项是主从节点断连的最大连接超时时间。如果超过了这个时间没有联系上,就认为主从节点断连了,超过10就代表网络状况不好,不适合作为新的主节点。
到这里,就把网络不好的从节点给过滤掉了,接下来要对所有从节点进行三轮考察:
- 优先级
- 复制进度
- ID号
第一轮考察:优先级
slave-priority配置项,可以给从节点设置优先级。
每一台从节点服务器配置不一定是相同的,可以根据服务器性能配置来设置从节点的优先级。
第二轮考察:复制进度最靠前的从节点胜出
如果优先级相同,则会考察复制进度。
主从架构中,主节点会将写操作同步给从节点。主节点会master_repl_offert记录当前最新写操作在repl_backlog_buffer中的位置,从节点会用slave_repl_offset记录当前的复制进度。越接近master_repl_offset说明复制进度与靠前。
第三轮考察:ID号小的从节点胜出
如果前两轮都相同,则比较ID号
选出从节点后,哨兵leader向从节点发出SLAVEOF no one 命令,从节点变为主节点。
发送完命令后,哨兵leader会以每秒1次的频率向变为主节点的从节点发送INFO命令,(没转移前是10秒1次),并观察回应中的角色信息,当角色信息从slave变为master的时候,就说明升级成功。
步骤2:将从节点指向新主节点
当新主节点出现后,需要将从节点指向新的主节点。
通过哨兵节点向从节点发送SLAVEOF命令,让其成为新主节点的从节点。
步骤3:通知客户的主节点已更换
哨兵集群完成主从切换后,需要将新主节点的信息通知给客户端。
通过Redis的发布者/订阅者模式来实现
下面是关键事件和频道
客户端和哨兵建立连接后,客户端会订阅哨兵提供的频道。主从切换完成后,哨兵就会向+switch-master频道发布新主节点的IP地址和端口的信息,这个时候客户端收到后就会使用心得主节点的IP和端口进行通信。
另外,客户端还可以通过这些频道监控到主从节点切换过程中的各个重要事件方便了解进度。
步骤4:将旧主节点变为从节点
当旧主节点重新上线后,哨兵集群就会向它发送SLAVEOF命令,让他成为新主节点的从节点。
到这里主从节点的故障转移工作结束。
哨兵集群是如何组成的?
哨兵集群也是通过redis的发布订阅机制组成的。
在配置哨兵时,只需要填下面几个参数,设置主节点名字、主节点的IP和端口号以及quorum值
sentinel monitor <master-name> <ip> <redis-port> <quorum>
那他们是怎么组成哨兵集群的呢?
答案是通过发布订阅机制来相互发现的。
在主从集群上,主节点有一个名为_sentinel_:hello的频道,不同哨兵就是通过它来相互发现,实现互相通信的。
哨兵将自己的信息发布到该频道上,然后其他的哨兵就能直接获取,建立网络。
哨兵集群会对「从节点」的运行状态进行监控,那哨兵集群如何知道「从节点」的信息?
主节点会知道所有从节点的信息,哨兵会每10秒向主节点发送INFO命令来获取所有从节点的信息。当主节点接收到INFO就会把从节点列表返回给哨兵。哨兵根据这些信息和从节点建立连接。集群中的其他哨兵也通过相同的方法进行连接。从而进行监控。
总结
为了实现主从节点故障转移,redis提供了哨兵机制。它会检测主节点是否存活,然后选举从节点为主节点,并且把新主节点的相关信息通知给从节点和客户端。
哨兵一般以集群方式不是,至少需要3个哨兵节点,主要负责监控、选主和通知。
监控:
一个哨兵发现主节点下线后,会发起投票,如果投票数超过quorum配置项设定的值后,这时主节点就会被该哨兵标记为客观下线。
该值一般是哨兵节点数的二分之一+1
这时就需要主从节点切换。
但是需要有一个leader哨兵节点去执行这个主从节点的切换,所以需要选出leader。
这时某个判定主节点客观下线后,该哨兵就会发起投票,成为候选者,每个哨兵节点只能投一票,所以当有两个候选者出现时,第一个询问其余节点的候选者将拿到票数。
成为leader的两个条件:
- 拿到半数以上的赞成票
- 拿到的票数同时还需要大于等于哨兵配置中的quorum。
选出leader之后,就执行主从故障转移。
主从故障转移的过程需要4个步骤:
- 选择新的主节点。
从所有的从节点中挑选新的主节点有以下规则
- 过滤掉下线节点
- 过滤掉网络不好的节点,通过断连的次数来判断
- 三轮考察,优先级、复制进度、ID号。
胜出的节点将成为主节点。
- 将旧主节点的所有从节点的复制目标修改为新主节点。
- 将新主节点的IP地址和信息,通过发布订阅机制通知给客户端。
- 继续监视旧主节点,当这个旧主节点重新上线时,将它设置为新主节点的从节点。