1.Redis哨兵
主从结构中master节点的作用非常重要,一旦故障就会导致集群不可用。那么有什么办法能保证主从集群的高可用性呢?
2.哨兵工作原理
Redis提供了哨兵(Sentinel)机制来监控主从集群监控状态,确保集群的高可用性。
2.1.哨兵作用
哨兵集群作用原理图:
哨兵的作用如下:
- 状态监控:
Sentinel 会不断检查你的 master 和 slave 是否按预期工作 - 故障恢复(failover):如果
master 故障,Sentinel 会将一个 slave 提升为 master 。当故障实例恢复后会成为 slave - 状态通知:
Sentinel 充当 Redis 客户端的服务发现来源,当集群发生 failover 时,会将最新集群信息推送给 Redis 的客户端
那么问题来了, Sentinel 怎么知道一个 Redis 节点是否宕机呢?
2.2.状态监控
官方文档:
Sentinel 基于心跳机制监测服务状态,每隔1秒向集群的每个节点发送ping命令,并通过实例的响应结果来做出判断:
- 主观下线(sdown):如果某sentinel节点发现某Redis节点未在规定时间响应,则认为该节点主观下线。
- 客观下线(odown):若超过指定数量(通过
quorum 设置)的sentinel都认为该节点主观下线,则该节点客观下线。quorum值最好超过Sentinel节点数量的一半,Sentinel节点数量至少3台。
如图:
- 首先会判断
slave 节点与 master 节点断开时间长短,如果超过 down-after-milliseconds * 10 则会排除该slave节点 - 然后判断
slave 节点的 slave-priority值,越小优先级越高,如果是 0 则永不参与选举(默认都是1)。 - 如果
slave-prority 一样,则判断 slave 节点的 offset 值,越大说明数据越新,优先级越高 - 最后是判断
slave 节点的 run_id 大小,越小优先级越高(通过 info server 可以查看 run_id )。
问题来了,当选出一个新的master后,该如何实现身份切换呢?
大概分为两步:
- 在多个
sentinel 中选举一个 leader - 由
leader 执行 failover
2.3.选举leader
首先,Sentinel 集群要选出一个执行 failover 的 Sentinel 节点,可以成为 leader 。要成为 leader 要满足两个条件:
- 最先获得超过半数的投票
- 获得的投票数不小于
quorum 值
而 sentinel 投票的原则有两条: - 优先投票给目前得票最多的
- 如果目前没有任何节点的票,就投给自己
比如有3个 sentinel 节点,s1 、s2 、s3 ,假如 s2 先投票: - 此时发现没有任何人在投票,那就投给自己。
s2 得 1 票 - 接着
s1 和 s3 开始投票,发现目前 s2 票最多,于是也投给 s2 ,s2 得 3 票 s2 称为 leader ,开始故障转移
不难看出,谁先投票,谁就会称为 leader ,那什么时候会触发投票呢?
答案是 第一个确认 master 客观下线的人会立刻发起投票,一定会成为 leader 。
OK,sentinel找到 leader 以后,该如何完成 failover 呢?
2.4.failover
我们举个例子,有一个集群,初始状态下 7001 为 master ,7002 和 7003 为 slave:
假如 master 发生故障,slave1 当选。则故障转移的流程如下:
sentinel 给所有其它 slave 发送 slaveof 192.168.150.101 7002 命令,让这些节点成为新 master ,也就是 7002 的 slave 节点,开始从新的 master 上同步数据。
- 最后,当故障节点恢复后会接收到哨兵信号,执行
slaveof 192.168.150.101 7002 命令,成为 slave :
参考: