Redis_07_Redis Sentinel-哨兵
Redis Sentinel
Redis Sentinel(哨兵):分布式架构实现自动故障发现和故障转移(并通知)
1)Sentinel节点只监控(不存储数据,且支持部分命令);
2)Sentinel节点执行故障转移后会同时维护Redis节点间的主从复制关系;
//Sentinel节点属于特殊的Redis节点(可通过INFO等命令查询相关状态)
Sentinel节点会监控主从复制中的所有节点
1)Sentinel节点通过主节点获取其相关从节点和其他Sentinel节点的信息;
Redis Sentinel集合:多个Sentinel节点对同一主从Redis节点监控组成的集合
1)Sentinel之间也会互相监控(发现不可达时,会标记该Sentinel节点);
2)Sentinel集合中只能有一个Sentinel可作为主Sentinel节点执行故障转移;
3)Sentinel集合可有效防止误判(Sentinel集合中每个Sentinel可投票决定);
//Redis Sentinle集合中所有的Sentinel节点尽量部署在不同的物理机上
//Sentinel集合中建议至少有3个以上且奇数个Sentinel节点(避免脑裂)
实现原理
三个定时任务
Sentinel集合通过3个定时任务实现对所有节点和其他Sentinel节点的监控
1)确保Sentinel节点可与主/从节点和其他Sentinel节点都建立连接
(1)每个Sentinel节点每隔10秒向主/从节点发送INFO命令
1)通过INFO命令可获知最新的拓扑结构和增加/删除的从节点信息;
(2)每个Sentinel节点每隔2秒向主/从节点__sentinel__:hello频道发信息
1)每个Sentinel节点默认订阅所有主/从节点的__sentinel__:hello频道;
2)通过该频道Sentinel节点可互通(交换信息);
(3)每个Sentinel节点每隔1秒向主/从节点和其他Sentinel节点发送ping命令
1)通过发送ping命令可获知该Sentinel节点是否可达(心跳检测);
主观/客观下线
主观下线:当主/从节点和其他Sentinel节点未满足心跳检测,则下线该节点
1)未满足心跳检测:参数down-after-milliseconds
指定时间内未回复ping命令;
2)从节点和Sentinel节点在主观下线后,没有后续的故障转移操作
3)主观下线存在误判可能;
客观下线:由多个Sentinel节点投票确定主节点是否下线
1)当票数超过预设值时,则下线该主节点并执行故障转移操作;
2)客观下线仅作用于主节点;
选举Sentinel
选举Sentinel:Sentinel集合中选举出作为领导者的Sentinel节点(Raft算法)
1)仅能由领导者Sentinel执行故障转移操作;
2)每个在线的Sentinel节点都有资格成为领导者Sentinel;
3)选举的流程非常快:谁先完成客观下线谁就是领导者Sentinel;
选举Sentinel流程如下:
-
索要票数:想要将Redis主节点下线的Sentinel节点假设为领导者Sentinel并向其他Sentinel节点索要票数;
-
若被索要的Sentinel节点仍有票数则同意(否则拒绝);
-
当该Sentinel节点发现自己的票数大于
max(quorum,num(sentinels)/2+1)
个时,就将本身选举为领导者Sentinel; -
若因其他因素未选举出,则进行下一次选举;
//一次选举流程中每个Sentinel节点只拥有一票
//至少max(quorum,num(sentinels)/2+1)个sentinel节点参加选举才可选出领导者
故障转移
故障转移:领导者Sentinel使用健康的从节点代替下线的主节点
故障转移流程如下:
1)在从节点列表中过滤出健康的从节点作为新主节点;
2)在新主节点中执行“SLAVEOF NO ONE
”命令(使其成为主节点);
3)向其他从节点发送更改主节点命令(成为新主节点的从节点);
4)若后续旧主节点上线,则将其更改为新主节点的从节点;
过滤健康从节点的条件如下:
1)Sentinel节点的ping命令均在5秒内回复;
2)与主节点断联未超过after-milliseconds * 10
秒;
3)若设置从节点优先级,则优先选择优先级较高的从节点;
4)选择复制偏移量最大的从节点;
5)选择运行ID最小的从节点;
如:故障转移流程图
//若想将指定从节点晋升为主节点,可先将其他从节点的优先级设置为0
部署Sentinel
部署Sentinel:等同于Redis节点指定配置启动
1)Sentinel节点的配置参数部分等同于Redis节点(有部分相关监控配置);
2)Sentinel节点部署后会自动感知其他已存在/新增的Sentinel节点;
3)默认配置文件:sentinel.conf
1)通过redis-sentinel命令启动:
redis-sentinel 配置文件
2)通过redis-server命令启动:
redis-server 配置文件 --sentinel
//多个Sentinel节点可使用同一配置文件(互不影响)
Sentinel节点支持动态配置参数
1)动态配置参数(Sentinel节点的客户端中执行)SENTINEL SET 参数 参数值
2)动态配置参数仅对执行命令的Sentinel节点有效;
3)动态配置参数后会自动刷新至配置文件中;
//建议所有Sentinel节点的配置保持一致(便于发现/转移故障)
配置参数
通用配置相关参数(等同Redis节点):
(1)指定Sentinel节点占用端口
port 端口号
(2)指定Sentinel节点的工作目录
dir 目录路径
(3)是否以守护进程运行
daemonize yes或no
(4)日志文件名
logfile “文件名”
监控配置相关参数:
(1)指定该Sentinel节点监控的Redis主节点
sentinel monitor 主节点别名 主节点IP 主节点端口 票数N
1)票数N:将该Redis主节点标记为不可达时,至少需N个Sentinel节点同意;
2)N建议设置为:Sentinel集合中含有Sentinel节点数的一半加一;
(2)指定该Sentinel节点发送ping命令周期
sentinel down-after-milliseconds 主节点别名 数值N
1)数值N:Sentinle每隔N毫秒发送一次ping命令;
//Sentinle节点通过发送ping命令至Redis节点和其他Sentinle判断是否可达
(3)指定故障转移后可复制的从节点个数
sentinel parallel-syncs 主节点别名 数值N
1)数值N:故障转移后只能有N个从节点可向新Redis主节点发送复制请求;
(4)指定故障转移的超时时间
sentinel failover-timeout 主节点别名 数值N
1)数值N:进行故障转移的4个阶段所用时间都需在N毫秒内;
2)若选择从节点阶段超时,将N翻倍继续执行;
3)若晋升从节点阶段超时,则重新选择从节点;
(5)指定该Sentinel节点监控的Redis主节点密码
sentinel auth-pass 主节点别名 密码
1)若Redis主节点未设置密码,可省略该参数;
(6)指定故障转移时发生警告级别的事件时,所执行的脚本文件
sentinel notificatio-script 主节点别名 脚本路径
1)会同时向该脚本文件发送相应事件参数;
//常见的事件如:-sdown
(客观下线)、-odown
(主观下线)
(7)指定故障转移结束后执行的脚本文件
sentinel client-reconfig-script 主节点别名 脚本路径
1)会同时向该脚本文件发送转移结果;
2)可执行脚本文件必须为Shell脚本文件,且具有可执行权限;
3)0
是正常退出状态码,1
是重试退出状态码,2
是强制退出状态码;
4)脚本文件的执行事件不可超过60秒,否则将强制结束该脚本文件;
//结果内容:主节点别名 leader或observer 状态 原主节点IP 原主节点端口 新主节点IP 新主节点端口
常用命令
Sentinel节点的命令只能在其连接的客户端中执行
1)Sentinel节点客户端大致上与Redis节点的客户端相同(命令不同);
2)Sentinel节点支持的其他普通命令如下:
命令 | 命令 |
---|---|
SUBSCRIBE | UNSUBSCRIBE |
PSUBSCRIBE | PUNSUBSCRIBE |
PUBLISH | INFO |
ROLE | CLIENT |
INFO | SHUTDOWN |
(1)获取信息:
(1)返回监控的所有Redis主节点信息
SENTINEL MASTERS
(2)返回指定Redis主节点信息
SENTINEL MASTER 主节点别名
(3)返回指定主节点的相关从节点信息
SENTINEL SLAVES 主节点别名
(4)返回监控指定主节点的Sentinel节点信息
SENTINEL SENTINELS 主节点别名
(5)返回指定主节点的IP和端口
SENTINEL GET-MASTER-ADDR-BY-NAME 主节点别名
(6)检测当前可达Sentinel节点个数是否达到票数个
SENTINEL CKQUORUM 主节点别名
(2)管理Sentinel节点:
(1)动态配置参数(Sentinel节点的客户端中执行)
SENTINEL SET 参数 参数值
(2)将当前Sentinel节点的配置刷新到文件中
SENTINEL FLUSHCONFIG
(3)重置符合匹配的Redis主节点(清除数据)
SENTINEL RESET 正则表达式
(4)对指定主节点进行强制故障转移
SENTINEL FAILOVER 主节点别名
1)不会与其他Sentinel进行协商;
2)转移完成后会通知其他Sentinel节点(根据转移结果进行更新);
(5)取消对指定Redis主节点的监控
SENTINEL REMOVE 主节点别名
1)仅对执行该命令的Sentinel节点有效;
(6)添加指定Redis主节点以监控
sentinel monitor 主节点别名 主节点IP 主节点端口 票数N
1)票数N:将该Redis主节点标记为不可达时,至少需N个Sentinel节点同意;
2)N建议设置为:Sentinel集合中含有Sentinel节点数的一半加一;
(7)判断指定Redis主节点是否已下线
SENTINEL IS-MASTER-DOWN-BY-ADDR 主节点IP 主节点端口 配置纪元 运行ID或*
1)为*
时,Sentinel节点直接交换对主节点下线的判断;
2)为运行ID
时,Sentinel节点希望其他Sentinel节点投票自己成为领导者Sentinel(运行ID为Sentinel的运行ID)
3)返回值由以下3个参数构成:
返回参数 | 说明 |
---|---|
down_state | 0:代表Redis主节点仍在线 1:代表Redis主节点已下线 |
leader_runid | *:不同意做为领导者Sentinel 运行ID:该运行ID代表的Sentinel同意 |
leader_epoch | 领导者纪元 |
日志分析
(1)故障转移相关日志:
日志 | 说明 |
---|---|
+try-failover <instance details> | 开始故障转移 |
+failover-state-reconf-slaves <instance details> | 故障转移进入reconf-slaves状态 |
+failover-state-select-slave <instance details> | 故障转移进入select-slave状态 (寻找合适的从节点) |
no-good-slave <instance details> | 没有找到合适的从节点 |
selected-slave <instance details> | 找到合适的从节点 |
failover-state-send-slaveof-noone <instance details> | 故障转移进入 failover-state-send-slaveof-noone状态 (从节点执行SLAVEOF NO ONE ) |
+slave-reconf-sent <instance details> | 领导者Sentinel命令 其他从节点复制新主节点 |
failover-end <instance details> | 故障转移顺利完成 |
(2)从节点相关日志:
日志 | 说明 |
---|---|
+slave <instance details> | 新从节点被发现并关联 |
+slave-reconf-inprog <instance details> | 从节点正在重新配置主节点的slave 但是同步过程尚未完成 |
+slave-reconf-done <instance details> | 从节点完成和新主节点的同步 |
(3)其他相关日志:
日志 | 说明 |
---|---|
+reset-master <instance details> | 主节点被重置 |
+sentinel <instance details> | 新sentinel节点被发现并关联 |
+elected-leader <instance details> | 选举领导者Sentinel |
+new-epoch <instance details> | 更新当前纪元 |
+sdown <instance details> | 某节点被主观下线 |
-sdown <instance details> | 撤销对某节点的主观下线 |
+odown <instance details> | 某主节点被客观下线 |
-odown <instance details> | 撤销对某主节点的客观下线 |
+reboot | 重启某节点 |