第07章-Redis Sentinel
# 一、架构说明
# 1.1 为什么需要 Redis Sentinel
主从复制存在以下问题:
- 手动故障转移:主从结构中节点故障需要手动切换
- 写能力和存储能力受限:写只能写在主节点,其他节点都是数据副本
为了解决上述问题,redis提供了 redis sentinel 这样一种高可用的实现
# 1.2 Redis Sentinel 架构说明
在主从结构的redis中,增加了很多redis sentinel节点,redis sentinel也是节点进程,但是不存储数据,而是负责判断节点的健康状况,完成故障转移的功能。对于客户端来说,不再从redis存储节点获取数据,而是直接从redis sentinel获取数据。
# 1.3 Redis Sentinel 故障转移
- 多个sentinel发现并确认master有问题
- 选举出一个sentinel作为领导
- 选出一个slave作为master
- 通知其余slave成为新的master的slave
- 通知客户端主从变化
- 等待老的master复活成为新master的slave
redis sentinel还可以同时监控多套主从结构,每套主从结构使用master-name
作为唯一标识,如下图所示
# 二、安装配置
# 2.1 配置方案
- 配置开启主从节点
- 配置开启sentine监控主节点。(sentinel是特殊的redis)
- 实际应该多机器
- 详细配置节点
# 2.2 配置实践
按照下图,配置启动redis主从和sentinel
redis主节点
redis从节点
sentinel主要配置
配置文件:sentinel.conf
配置说明:
# 监控master-name为mymaster的节点,只当ip和端口,2表示2个sentinel节点发现master故障了,就触发故障转移
sentinel monitor mymaster 127.0.0.1 7000 2
# sentinel监控节点健康的心跳周期,30000毫秒
sentinel down-after-milliseconds mymaster 30000
# 选择主节点后,同时从主节点复制数据的从节点个数,1表示串行
sentinel parallel-syncs mymaster 1
# 故障转移时间
sentinel failover-timeout mymaster 180000
2
3
4
5
6
7
8
启动方式:redis-sentinel [configPath]
启动sentinel节点后,sentinel会根据主节点的 info 信息,自动获取从节点信息,进而监控从节点
# 四、客户端连接
# 4.1 客户端接入sentinel流程
高可用要同时实现客户端高可用和服务端高可用。服务端高可用依赖于sentinel,客户端高可用需要连接客户端实现。
下面介绍客户端连接sentinel实现高可用的基本原理。
客户端获取所有sentinel节点和对应的masterName,选举一个sentinel节点来连接
通过选出的sentinel节点,传入masterName,获取真正的master节点信息
拿到master节点信息后,验证节点角色信息,看是否真是master
如果master节点信息发生变化,sentinel会使用发布订阅的模式通知客户端
# 4.2 jedis连接sentinel
JedisSentinelPool sentinelPool = new JedisSentinelPool(masterName, sentinelSet, poolConfig, timeout);
Jedis jedis = null;
try {
jedis = redisSentinelPool.getResource();
//jedis command
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
if (jedis != null)
jedis.close();
}
2
3
4
5
6
7
8
9
10
11
# 五、实现原理
# 5.1 三个定时任务
redis sentinel 内部有三个定时任务
每10秒每个sentinel对master和slave执行info
- 发现slave节点
- 确认主从关系
每2秒每个sentinel通过master节点的channel交换信息(pub/sub)
- 通过
__sentinel__:hello
频道交互 - 交互对节点的“看法”和自身信息
- 通过
每1秒每个sentinel对其他sentinel和redis执行ping
- 心跳检测,失败判定依据
# 5.2 主观下线和客观下线
相关配置:
# 超过2个sentinel节点认为节点下线,就做后续下线处理(客观下线)
# sentinel monitor <masterName> <ip> <port> <quorum>
sentinel monitor myMaster 127.0.0.1 6379 2
# sentinel节点ping其他节点,超过多少毫秒,就认为该节点下线了(主观下线)
# sentinel down-after-milliseconds <masterName> <timeout>
sentinel down-after-milliseconds mymaster 30000
2
3
4
5
6
7
主观下线:每个sentinel节点对Redis节点失败的“偏见"
客观下线:所有sentinel节点对Redis节点失败“达成共识"(超过quorum个统一)
sentinel首先对主节点做主观下线的一个判断,然后通过
sentinel is-master-down-by-addr
询问其他sentinel节点是否也认为主节点下线了
slave节点做主观下线,因为不需要故障转移,master节点需要做客观下线
# 5.3 领导者选举
原因:只有一个sentinel节点完成故障转移
选举:通过 sentinel is-master-down-by-addr
命令都希望成为领导者
过程:
- 每个做主观下线的Sentinel节点向其他Sentinel节点发送命令,要求将它设置为领导者。
- 收到命令的Sentinel节点如果没有同意通过其他Sentinel节点发送的命令,那么将同意该请求,否则拒绝。
- 如果该Sentinel节点发现自己的票数已经超过Sentinel集合半数且超过quorum,那么它将成为领导者。
- 如果此过程有多个Sentinel节点成为了领导者,那么将等待一段时间重新进行选举。
# 5.4 故障转移
故障转移由sentinel选举出的领导者节点完成,过程如下:
- 从slave节点中选出一个“合适的"节点作为新的master节点
- 对上面的slave节点执行slaveof no one命令让其成为master节点。
- 向剩余的slave节点发送命令,让它们成为新master节点的slave节点,复制规则和parallel-syncs参数有关。
- 更新对原来master节点配置为slave,并保持着对其“关注",当其恢复后命令它去复制新的master节点。
如何选择“合适的”slave节点作为新的master节点:
- 选择slave-priority(slave节点优先级)最高的slave节点,如果存在则返回,不存在则继续。
- 选择复制偏移量最大的slave节点(复制的最完整),如果存在则返回,不存在则继续。
- 选择runId最小的slave节点。
# 六、开发运维中问题
# 6.1 节点运维
# 节点下线
节点需要下线的原因:
- 机器下线:例如过保等情况
- 机器性能不足:例如CPU、内存、硬盘、网络等
- 节点自身故障:例如服务不稳定等
主节点下线
sentinel failover <masterName>
从节点下线:从节点下线要考虑是临时下线还是永久下线,例如是否做一些清理工作。还要考虑读写分离的情况。
Sentinel节点下线:同上
# 节点上限
- 主节点:sentinel failover进行替换。
- 从节点:slaveof 即可,sentinel节点可以感知。
- Sentinel节点:参考其他sentinel节点启动即可。
# 6.2 高可用读写分离
从节点的作用:
- 副本:高可用的基础
- 扩展:读能力
读写分离是客户端实现的,要实现读写分离,需要关注三个消息
- +switch-master:切换主节点(从节点晋升主节点)
- +convert-to-slave:切换从节点(原主节点降为从节点)
- +sdown:主观下线。
# 七、总结
- Redis Sentinel是Redis的高可用实现方案:故障发现、故障自动转移、配置中心、客户端通知。
- Redis Sentinel从Redis2.8版本开始才正式生产可用,之前版本生产不可用。
- 尽可能在不同物理机上部署Redis Sentinel所有节点。
- Redis Sentinel中的Sentinel节点个数应该为大于等于3且最好为奇数。
- Redis Sentinel中的数据节点与普通数据节点没有区别。
- 客户端初始化时连接的是Sentinel节点集合,不再是具体的Redis节点,但Sentinel只是配置中心不是代理。
- Redis Sentinel通过三个定时任务实现了Sentinel节点对于主节点、从节点、其余Sentinel节点的监控。
- Redis Sentinel在对节点做失败判定时分为主观下线和客观下线。
- 看懂Redis Sentinel故障转移日志对于Redis Sentine以及问题排查非常有帮助。
- Redis Sentinel实现读写分离高可用可以依赖Sentinel节点的消息通知,获取Redis数据节点的状态变化。