定义
Redis sentinel称为哨兵模式,是Redis 高可用的实现方法,具有故障发现,故障自动转移,配置中心和客户端通知,2.8版本后sentinel生产可用。sentinel作为一个独立的进程,监控多个运行的Redis 数据库。
主要解决主从复制发生故障时,进行手动故障转移的复杂性问题,当主节点宕机后,需要手动选择一个从节点作为新的主数节点,其他作为从节点,而利用sentinel能自动完成故障转移过程。
sentinel也支持集群,因为使用单个sentinel进程了监控Redis是不可靠的,容易出现单点问题
- 即使有一些sentinel进程宕掉了,依然可以进行Redis 集群的主从切换
- 如果只有一个sentinel进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现Redis 集群的主从切换
- 如果有多个sentinel,redis的客户端可以随意地连接任意一个sentinel来获得关于Redis 集群中的信息
功能和架构
- 功能
- 监控Redis的运行状况
- 当发生故障时实现主从切换。当一个master宕机之后,从它的多个slave中投票选举中一个新的master,剩余节点作为新的master的slave
- 架构
在这个架构中,sentinel节点会监控master和slave的相关信息,主要值得关注的是client与sentinel之间的交互:
- client首先需要知道sentinel节点集合和mastername信息,通过遍历它所知道的sentinel集合,获取到一个可用的sentinel节点
- 找到可用的sentinel节点之后,client通过 sentinel get-master-addr-by-name masterName 命令的得到master节点的地址和端口
- 得到master相关信息之后,会进行一次role/role replication验证,master节点会返回验证信息,至此client可以对master进行写入和读取
- sentine也会将redis数据节点的变化通知给客户端 - 使用发布订阅模式进行通知
- 上述过程不是通过代理模式实现的,即上述client和master建立关系的过程通常只需执行一次即可
故障转移过程
- 当一个sentinel检测master宕机并不会马上进行故障转移(主观下线),只有当后面的sentinel也都认为master不可用并达到一定数量时(客观下线),选举出一个领导者sentinel来进行故障转移操作
- 选出一个slave作为master,执行 slave of one 让其成为master节点
- 通知其余slave做为新的master的slave
- 等待老的master复活,若复活成功,成为新的master的slave
- 通知客户端发生了主从变化
实现上述故障转移依靠三个定时任务:
- 每10s每个sentinel对master和slave执行info操作
- 发现slave操作
- 确认主从关系
- 每2s每个sentinel通过master节点的channel交换信息
- 发布订阅模式
- 通过_sentinel_:hello频道交互
- 交互对节点的"看法"和自身信息 - 可以知道其他sentinel的相关信息或投票来确定哪个sentinel来进行故障转移
- 每1s每个sentinel对其他sentinel和redis执行ping
- 心跳检测,失败判定依据,比如可以作为客观下线的依据。
Sentinel配置和启动
- 配置文件
# sentinel运行端口 |
注:可以看到sentinel.conf配置文件主要是对master节点进行监控,通过master节点使用 info replecation 进行slave的相关信息获取,会将获取的slave信息自动添加到 sentinel.conf配置文件之中,在配置文件中的标识为:Generated by CONFIG REWRITE,需要注意的是,redis在添加slave信息的同时,也会对一些配置信息进行更改,例如sentinel down-after-milliseconds,sentinel parallel-syncs,sentinel failover-timeout会被移除,添加sentinel config-epoch,sentinel leader-epoch等配置 。
- 启动
redis-sentinel sentinel.conf # 启动sentinel
redis-cli -p 26379 # 连接sentinel, sentinel也当成一个普通的Redis 节点来对待
扩展
- 主观下线:每个sentinel节点对Redis 节点失败的"偏见",可能由于网络问题,Redis 节点不能在规定的时间内回应sentinel节点
- 客观下线:所有sentin节点对Redis 节点失败达成"共识",即sentinel节点中认为Redis 节点可以进行客观下线的个数超过quorum的个数,此时可以真正进行故障转移操作。其中达成共识通过sentinel is-master-down-by-addr命令询问其他sentinel节点的"意见"来完成的
- 领导者选举
- 原因:只需要一个sentinel节点来进行故障转移
- 如何:1. 每个做主观下线的sentinel节点通过sentinel is-master-down-by-addr 来询问其他sentinel节点的"意见"是否要对master节点进行客观下线的时候,通过也会要求将其设置为领导者;2. 收到命令的sentinel节点如果没有同意其他sentinel节点成为领导者的请求,那就同意,否则拒绝;3. 如果该sentinel节点发现自己的票数超过了sentinel集合半数且超过了quorum,那么它将成为领导者来进行故障处理;4. 如果有多个sentin节点成为领导者,则过一段时间再进行选举
- 如何选择合适的slave让其成为master
- 选择 slave-priority优先级最高的slave节点
- 若全部优先级相同,则选择复制偏移量最大(与以前的master节点数据最接近)的slave节点
- 若上述都不成立,则选择runId最小的节点,即启动最早的slave
运维问题
- 主节点手动下线,进行故障转移
sentinel failover masterName - 高可用的读写分离
sentinel只会对master节点进行故障转移,对于slave节点只有进行主观下线,所以要实现高可用的读写分离,客户端要关注slave节点的变化,例如关注以下三个消息: +switch-master: 从节点晋升为主节点,+conver-to-slave: 原主节点降为从节点,+sdown: 主观下线
参考资料
[1] https://segmentfault.com/a/1190000002680804
[2] https://coding.imooc.com/class/151.html