Redis的主从复制模式下, 一旦主节点由于故障不能提供服务, 需要人工将从节点晋升为主节点, 同时还要通知应用方更新主节点地址, 对于很多应用场景这种故障处理的方式是无法接受的。可喜的是Redis从2.8开始正式提供了Redis Sentinel(哨兵) 架构来解决这个问题。
Redis Sentinel是Redis的高可用实现方案, 在实际的生产环境中, 对提高整个系统的高可用性是非常有帮助的。
Redis Sentinel的高可用性
当主节点出现故障时, Redis Sentinel能自动完成故障发现和故障转移,并通知应用方, 从而实现真正的高可用。
Redis Sentinel是一个分布式架构, 其中包含若干个Sentinel节点和Redis数据节点, 每个Sentinel节点会对数据节点和其余Sentinel节点进行监控, 当它发现节点不可达时, 会对节点做下线标识。 如果被标识的是主节点, 它还会和其他Sentinel节点进行“协商”, 当大多数Sentinel节点都认为主节点不可达时, 它们会选举出一个Sentinel节点来完成自动故障转移的工作, 同时会将这个变化实时通知给Redis应用方。 整个过程完全是自动的, 不需要人工来介入, 所以这套方案很有效地解决了Redis的高可用问题。
整个故障转移的处理逻辑有下面4个步骤:
1) 如图9-8所示, 主节点出现故障, 此时两个从节点与主节点失去连接, 主从复制失败。
2) 如图9-9所示, 每个Sentinel节点通过定期监控发现主节点出现了故障。
3) 如图9-10所示, 多个Sentinel节点对主节点的故障达成一致, 选举出sentinel-3节点作为领导者负责故障转移。
4) 如图9-11所示, Sentinel领导者节点执行了故障转移
5) 故障转移后整个Redis Sentinel的拓扑结构图9-12所示。
三个定时监控任务
一套合理的监控机制是Sentinel节点判定节点不可达的重要保证, RedisSentinel通过三个定时监控任务完成对各个节点发现和监控:
1) 每隔10秒, 每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构, 如图9-26所示。
2) 每隔2秒, 每个Sentinel节点会向Redis数据节点的__sentinel__: hello
频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息
(如图9-27所示) , 同时每个Sentinel节点也会订阅该频道, 来了解其他
Sentinel节点以及它们对主节点的判断, 所以这个定时任务可以完成以下两个工作:
·发现新的Sentinel节点: 通过订阅主节点的__sentinel__: hello了解其他的Sentinel节点信息, 如果是新加入的Sentinel节点, 将该Sentinel节点信息保存起来, 并与该Sentinel节点创建连接。
·Sentinel节点之间交换主节点的状态, 作为后面客观下线以及领导者选举的依据。
3) 每隔1秒, 每个Sentinel节点会向主节点、 从节点、 其余Sentinel节点发送一条ping命令做一次心跳检测, 来确认这些节点当前是否可达。
5.2 主观下线和客观下线
1.主观下线
每个Sentinel节点会每隔1秒对主节点、 从节点、 其他Sentinel节点发送ping命令做心跳检测, 当这些节点超过down-after-milliseconds没有进行有效回复, Sentinel节点就会对该节点做失败判定, 这个行为叫做主观下线。
2.客观下线
当Sentinel主观下线的节点是主节点时, 该Sentinel节点会通过sentinel ismaster-down-by-addr命令向其他Sentinel节点询问对主节点的判断, 当超过<quorum>个数, Sentinel节点认为主节点确实有问题, 这时该Sentinel节点会做出客观下线的决定, 这样客观下线的含义是比较明显了, 也就是大部分Sentinel节点都对主节点的下线做了同意的判定, 那么这个判定就是客观的。
5.4 故障转移
领导者选举出的Sentinel节点负责故障转移, 具体步骤如下:
1) 在从节点列表中选出一个节点作为新的主节点, 选择方法如下:
a) 过滤: “不健康”(主观下线、 断线) 、 5秒内没有回复过Sentinel节
点ping响应、 与主节点失联超过down-after-milliseconds*10秒。
b) 选择slave-priority(从节点优先级) 最高的从节点列表, 如果存在则
返回, 不存在则继续。
c) 选择复制偏移量最大的从节点(复制的最完整) , 如果存在则返
回, 不存在则继续。
d) 选择runid最小的从节点。
2) Sentinel领导者节点会对第一步选出来的从节点执行slaveof no one命令让其成为主节点。
3) Sentinel领导者节点会向剩余的从节点发送命令, 让它们成为新主节点的从节点, 复制规则和parallel-syncs参数有关。
4) Sentinel节点集合会将原来的主节点更新为从节点, 并保持着对其关注, 当其恢复后命令它去复制新的主节点。
6.3 高可用读写分离
1.从节点的作用
从节点一般可以起到两个作用: 第一, 当主节点出现故障时, 作为主节点的后备“顶”上来实现故障转移, Redis Sentinel已经实现了该功能的自动化, 实现了真正的高可用。 第二, 扩展主节点的读能力, 尤其是在读多写少的场景非常适用, 通常的模型如图9-36所示。