Redis Sentinel 哨兵模式
1.网络架构
网络结构如下,通过Sentinel监控Master和Slave服务器:
2.配置启动
配置文件如下:
vi /etc/redis-sentinel.conf
port 26379
dir "/tmp"
logfile "/var/log/redis/sentinel_20086.log"
# 进程守护
daemonize yes
# 格式:sentinel <option_name> <master_name> <option_value>
# 最后的一个2代表在sentinel集群中,多少个节点认为master死了,才能真正认为该master不可用
sentinel monitor T1 127.0.0.1 6379 2
# sentinel会向master发送心跳确认存活
# 如果master在“一定时间范围”内不回应PONG 或者是回复了一个错误消息
# 那么这个sentinel会主观地认为这个master已经不可用了
# (subjectively down, 也简称为SDOWN)。
# down-after-milliseconds 用来指定这个“一定时间范围”,单位是毫秒,默认30秒。
sentinel down-after-milliseconds T1 15000
# failover过期时间。
# 当failover开始后,在此时间内仍然没有触发任何failover操作,当前sentinel将会认为此次failoer失败。
# 默认180秒,即3分钟。
sentinel failover-timeout T1 120000
# 在发生failover时,这个选项指定了最多可以有多少个slave同时对新的master进行同步。
# 这个数字越小,完成failover所需的时间就越长;
# 这个数字越大,就意味着越多的slave因为replication而不可用。
# 可以通过将这个值设为 1 来保证每次只有一个slave处于不能处理命令请求的状态。
sentinel parallel-syncs T1 1
# sentinel 连接密码验证
# sentinel auth-pass <master_name> xxxxx
# 发生切换之后执行的一个自定义脚本
# sentinel notification-script <master-name> <script-path>
# sentinel client-reconfig-script <master-name> <script-path>
Sentinel 也需要集群化,以确保:
- 某个/些 Sentinel节点挂了,仍然可以实现Redis主从切换;
- Redis客户端可以通过任意一个Sentinel读取/写入信息。
启动Sentinel:
redis-sentinel /path/to/sentinel.conf
启动后,通过Sentinel的自动识别,配置文件中会自动加上已识别的Redis集群节点和Sentinel集群节点。
3.实现流程
- Sentinel集群通过配置文件发现master,启动时会监控master;
- 向master发送info命令,获取其所有slave节点;
- Sentinel集群向Redis主从服务器发送hello信息(心跳),包括Sentinel本身的ip、端口、id等内容,以此来向其他Sentinel宣告自己的存在;
- Sentinel集群通过订阅接收其他Sentinel发送的hello信息,以此来发现监视同一个主服务器的其他Sentinel;集群之间会互相创建命令连接用于通信,因为已经有主从服务器作为发送和接收hello信息的中介,Sentinel之间不会创建订阅连接;
- Sentinel集群使用ping命令来检测实例的状态,如果在指定的时间内(down-after-milliseconds)没有回复或则返回错误的回复,那么该实例被判为下线;
- 当failover主备切换被触发后,并不会马上进行,还需要Sentinel中的大多数sentinel授权后才可以进行failover,即进行failover的Sentinel会去获得指定quorum个的Sentinel的授权,成功后进入ODOWN状态。如在5个Sentinel中配置了2个quorum,等到2个Sentinel认为master死了就执行failover。
- Sentinel向选为master的slave发送 SLAVEOF NO ONE 命令,选择slave的条件是Sentinel首先会根据slaves的优先级来进行排序,优先级越小排名越靠前。如果优先级相同,则查看复制的下标,哪个从master接收的复制数据多,哪个就靠前。如果优先级和下标都相同,就选择进程ID较小的。
- Sentinel被授权后,它将会获得宕掉的master的一份最新配置版本号(config-epoch),当failover执行结束以后,这个版本号将会被用于最新的配置,通过广播形式通知其它sentinel,其它的sentinel则更新对应master的配置。
注意:
因为redis采用的是异步复制,没有办法避免数据的丢失。
可以在redis.conf通过以下配置来使得数据不会丢失:
// master最少得有多少个健康的slave存活才能执行写命令
min-slaves-to-write 1
// 延迟小于min-slaves-max-lag秒的slave才认为是健康的slave
min-slaves-max-lag 10
当所有Slave都不符合条件时,master将停止写入。
4.故障转移
发生故障转移时,需要进行领导者选举。
- sentinel首先会根据slaves的优先级来进行排序,优先级越小排名越靠前;
- 如果优先级相同,则查看复制的下标,哪个从master接收的复制数据多,哪个就靠前;
- 如果优先级和下标都相同,就选择RunID较小的那个;
如果一个redis的slave优先级配置为0,那么它将永远不会被选为master。
故障转移过程
领导者Sentinel需要将一个salve提升为master,此slave必须为状态良好,不能处于SDOWN/ODOWN状态。
- “+failover-triggered”: Leader开始进行failover,此后紧跟着“+failover-state-wait-start”,wait数秒。
- “+failover-state-select-slave”: Leader开始查找合适的slave
- “+selected-slave”: 已经找到合适的slave
- “+failover-state-sen-slaveof-noone”: Leader向slave发送“slaveof no one”指令,此时slave已经完成角色转换,此slave即为master
- “+failover-state-wait-promotition”: 等待其他sentinel确认slave
- “+promoted-slave”:确认成功
- “+failover-state-reconf-slaves”: 开始对slaves进行reconfig操作
- “+slave-reconf-sent”:向指定的slave发送“slaveof”指令,告知此slave跟随新的master
- “+slave-reconf-inprog”: 此slave正在执行slaveof + SYNC过程,如过slave收到“+slave-reconf-sent”之后将会执行slaveof操作。
- “+slave-reconf-done”: 此slave同步完成,此后leader可以继续下一个slave的reconfig操作。循环 step 7
- “+failover-end”: 故障转移结束
- “+switch-master”:故障转移成功后,各个sentinel实例开始监控新的master。
5.增加和删除节点
Sentinel会通过PUB/SUB自动识别新增节点。
删除流程:
- 停止所要删除的sentinel
- 发送一个SENTINEL RESET 命令给所有其它的sentinel实例,如果你想要重置指定master上面的sentinel,只需要把号改为特定的名字,注意,需要一个接一个发,每次发送的间隔不低于30秒(down-after-milliseconds);
- 检查一下所有的sentinels是否都有一致的当前sentinel数;
参考资料:
https://www.cnblogs.com/zhouj...
http://www.cnblogs.com/zhouji...
https://segmentfault.com/u/be...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。