如果考虑使用阿里云Redis的话,哨兵是没有深入研究的价值的,因为阿里云Redis提供了自己的HA组件,来实现备份节点到主节点的转换。但是出于系统学习Redis知识的目的,我还是需要花点时间了解一下哨兵机制底层原理。
这篇笔记更多的是进行整理。
配置文件
我没有自己去配哨兵(我用的Helm,可以通过修改values.yaml文件实现哨兵机制)
- 两台Redis服务器的配置
|
|
- 三个哨兵的配置
|
|
工作原理
Sentinel与Sentinel之间、Sentinel与Redis之间的感知
-
Sentinel与Redis节点:在Sentinel进程启动时,会与Master节点建立连接,然后Sentinel从Master节点获取所有节点信息,之后Sentinel会定时想Master节点和Slave节点发送info命令获取其拓步结构和状态信息。
-
Sentinel与Sentinel节点:基于Redis的Pub/Sub功能,每个Sentinel会向sentinel:hello频道上发送该Sentinel对于主节点的判断以及当前Sentinel节点的信息;同时每个Sentinel也会订阅该频道,来获取其他Sentinel节点的信息已经它们对主节点的判断(主节点如果挂了,这个判断信息有个毛用啊)。
通过以上两步,所有的Sentinel节点以及它们与所有的Redis节点之间都已经彼此感知到,之后每个Sentinel节点会向主节点、从节点、以及其余Sentinel节点定时发送ping命令作为心跳检测,来确认这些节点是否可达。
判断Master节点是否可达
-
每个sentinel哨兵节点每隔1s向所有的master、slave以及其他sentinel节点发送一个PING命令,作用是通过心跳检测,检测主从服务器的网络连接状态
-
如果master节点回复PING命令的时间超过down-after-milliseconds设定的阈值(默认30s),则这个master会被sentinel标记为主观下线,修改其flags状态为SRI_S_DOWN
-
当sentinel哨兵节点将master标记为主观下线后,会向其余所有的sentinel发送sentinel is-master-down-by-addr消息,询问其他sentinel是否同意该master下线
-
每个sentinel收到命令之后,会根据发送过来的ip和port检查自己判断的结果,回复自己是否认为该master节点已经下线了
-
sentinel收到回复之后,如果同意master节点进入主观下线的sentinel数量大于等于quorum,则master会被标记为客观下线,即认为该节点已经不可用。
-
在一般情况下,每个Sentinel每隔10s向所有的Master,Slave发送INFO命令。当Master被Sentinel标记为客观下线时,Sentinel向下线的Master的所有Slave发送INFO命令的频率会从10秒一次改为每秒一次。作用:发现最新的集群拓扑结构
基于Raft算法选举负责故障转移的Sentinel
-
判断客观下线的sentinel节点向其他sentinel节点发送SENTINEL is-master-down-by-addr ip port current_epoch runid
-
目标sentinel回复是否同意master下线并选举领头sentinel,选择领头sentinel的过程符合先到先得的原则。举例:sentinel1判断了客观下线,向sentinel2发送了第一步中的命令,sentinel2回复了sentinel1,说选你为领头,这时候sentinel3也向sentinel2发送第一步的命令,sentinel2会直接拒绝回复。
-
当sentinel发现选自己的节点个数超过majority的个数的时候,自己就是领头节点
-
如果没有一个sentinel达到了majority的数量,等一段时间,重新选举
故障转移
-
在进行选择之前需要先剔除掉一些不满足条件的slaver,这些slaver不会作为变成master的备选
- 剔除列表中已经下线的从服务
- 剔除有5s没有回复sentinel的info命令的slave
- 剔除与已经下线的主服务连接断开时间超过down-after-milliseconds * 10 + master宕机时长的slaver
-
选主过程
- 选择优先级最高的节点,通过sentinel配置文件中的replica-priority配置项,这个参数越小,表示优先级越高
- 如果第一步中的优先级相同,选择offset最大的,offset表示主节点向从节点同步数据的偏移量,越大表示同步的数据越多
- 如果第二步offset也相同,选择run id较小的
修改被选举出来的主节点的配置
- 领头sentinel会对选出来的从节点执行slaveof no one 命令让其成为主节点
- 领头sentinel向别的slave发送slaveof命令,告诉他们新的master是谁谁谁,你们向这个master复制数据
- 如果之前的master重新上线时,领头sentinel同样会给起发送slaveof命令,将其变成从节点