master宕机
如果主从模式下的master宕机,一般处理流程:
- 将宕机的master下线
- 找一个slave作为master
- 通知所有的slave连接新的master
- 启动新的master与slave
全量复制*N + 部分复制*N
出现的问题:
- 谁来确认master宕机了
- 选新的master如何选?
- 修改配置后,原来的master恢复了怎么办?
哨兵
哨兵(sentinel)是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的master并将所有slave连接到新的master。
作用:
- 监控
不断的检查master和slave是否正常运行。
master存活检测、master与slave运行情况检测
- 通知(提醒)
当被监控的服务器出现问题时,向其他(哨兵间,客户端)发送通知
- 自动故障转移
断开master与slave连接,选取一个slave作为master,将其他slave连接到新的master,并告知客户端新的服务器地址。
哨兵也是一台redis服务器,只是不提供数据服务。
通常哨兵配置数量为单数。
哨兵搭建示例
配置哨兵(参考 sentinel.conf 配置文件)
编写配置文件sentinel-端口号.conf:
port 26379
daemonize no
pidfile /var/run/redis-sentinel.pid
logfile ""
dir /tmp
# sentinel monitor [自定义的名称] 监控的master的ip和端口 判断master宕机的哨兵数量
# 如果有2台哨兵认为master宕机了,master就下线
sentinel monitor mymaster 127.0.0.1 6379 2
# master判定宕机的未响应时长(单位毫秒)
sentinel down-after-milliseconds mymaster 30000
# 新的master上来之后,进行数据同步时,一次多少个数据开始同步
sentinel parallel-syncs mymaster 1
# 多久未同步完成算作超时(单位毫秒)
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
启动哨兵:
redis-sentinel sentinel-端口号.conf
使用客户端连接时,依然是redis-cli
启动客户端,但是不允许使用set
、get
等指令。
哨兵启动之后,刚刚编写的配置文件会被自动重写一部分,例如变为:
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel.pid"
logfile "26379.log"
dir "/home/redis/data"
sentinel myid d957acd3913031c3bec970b13f9a2cc446230d25
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
# Generated by CONFIG REWRITE
protected-mode no
maxclients 4064
user default on nopass ~* +@all
sentinel known-replica mymaster 127.0.0.1 6381
sentinel known-replica mymaster 127.0.0.1 6380
sentinel known-sentinel mymaster 127.0.0.1 26380 5b8d465eba4e61f72f245cc12d32d4c45b812ae5
sentinel known-sentinel mymaster 127.0.0.1 26381 8812ba72638e42fbbc1a9af8a8a2e1716e223011
sentinel current-epoch 0
工作原理
三个阶段:
- 监控
同步信息
- 通知
保持连通
- 故障转移
发现问题
选择竞选负责人
优选新的master
新master上任,其他slave切换master,原master改为slave
监控阶段
同步各个节点的状态信息
- 通过ping指令获取各个sentinel的状态(是否在线)
通过info指令获取master的状态
- master的属性:runid、role:master
- 各个slave的详细信息
通过info获取所有slave的状态(根据master中的slave信息)
- slave的属性:runid、role:slave、master_host、master_port、offset…..
通知阶段
故障转移阶段
确认master下线流程:
投票选择哨兵间的leader:
每个哨兵向哨兵间发布/订阅通道内发送信息:
SENTINEL is-master-down-by-addr ….
- 下线的master的ip
- 下线的master的端口号
- 哨兵自己参与哨兵leader竞选的次数
- 哨兵自己的runid
每一个哨兵作为参选者,同时也是投票者,每个哨兵有一票。哨兵根据自己接收到其他哨兵发送信息的先后顺序,把自己的票投给对应的哨兵。最终汇总得票结果,选出哨兵leader。如果第一轮没有选出来leader,再进行一轮投票,直至得出哨兵leader。每增加一轮,哨兵的参与竞选次数会增加1。
哨兵leader 从slave服务器里列表中挑选备用master转正,选择的原则:
- 备选的slave需要是在线的
- 给slave不停发送hello消息,淘汰掉响应慢的
- 淘汰与原master断开时间久的
优先原则
- 比较优先级
- 比较数据同步的offset
- 选择runid比较小的
哨兵leader发送指令告知新的master:
- 向新的master发送
slaveof no one
指令 - 向其他slave发送
slaveof 新master的ip 端口号