为什么需要 Redis 哨兵?
作者 | 阿文
责编 | 郭芮
出品 | CSDN(ID:CSDNnews)
-
监控:定期检测Redis 数据节点、其他 Sentinel 节点是否可达。 -
通知:将故障转移的结果通知给应用方。 -
主节点故障转移:实现从节点晋升为主节点,并维护后续正确的主从关系 -
配置提供者:客户端在初始化的时候连接 Sentinel 节点集合,从中获取主节点信息。
redis-6379.conf
port 6379
daemonize yes
logfile "6739.log"
dbfilename "dump-6379.rdb"
dir "/opt/soft/redis/data"
redis-6380.conf
port 6380
daemonize yes
logfile "6780.log"
dbfilename "dump-6380.rdb"
dir "/opt/soft/redis/data"
slaveof 127.0.0.1 6379
redis-6381.conf
port 6381
daemonize yes
logfile "6781.log"
dbfilename "dump-6381.rdb"
dir "/opt/soft/redis/data"
slaveof 127.0.0.1 6379
redis-sentinel-26379.conf
port 26379
daemonize yes
logfile "26379.log"
dir /opt/soft/redis/data
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
redis-sentinel-26380.conf
port 26380
daemonize yes
logfile "26380.log"
dir /opt/soft/redis/data
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
redis-sentinel-26381.conf
port 26381
daemonize yes
logfile "26381.log"
dir /opt/soft/redis/data
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel monitor mymaster-1 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster-1 1
sentinel failover-timeout mymaster-1 180000
sentinel monitor mymaster-2 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster-2 1
sentinel failover-timeout mymaster-2 180000
配置说明:
-
port 指定 sentinel 节点的端口 sentinel monitor master-name 是给要监控的节点起一个名字,ip 和 port 表示监控一个主节点,quorum 表示要判断主节点最终不可达所需要的票数。同时这个参数还与选举领导者有关,至少需要max(quorum,num/2+1)个节点参与选举,才能选出领导者 sentinel,从而完成故障转移。比如总共有 5 个 sentinel 节点,quorum =4 ,name 至少需要 4 个sentinel 节点才可以进行领导者的选举。
-
sentinel 自动发信了从节点以及其他 sentinel 节点。 -
去掉里面默认配置,例如 parallel-sync failover-timeout 参数。 -
添加了配置 纪元相关参数。
sentinel down-after-milliseconds <master-name> <times>
sentinel parallel-syncs <master-name> <nums>
sentinel failover-timeout <master-name> <times>
-
选出合适从节点; -
晋升选出的从节点为主节点; -
命令其余从节点复制新的主节点; -
等待原主节点恢复后命令它去复制新的主节点。
如果Redis Sentinel对一个主节点故障转移失败,那么下次再对该主 节点做故障转移的起始时间是failover-timeout的2倍;
在晋升选出的从节点为主节点阶段时,如果Sentinel节点向a)阶段选出来的从节点执行slaveof no one一直失败(例如该从节点此时出现故障),当此过程超过 failover-timeout时,则故障转移失败;
在晋升选出的从节点为主节点阶段如果执行成功,Sentinel节点还会执行info命令来确认a) 阶段选出来的节点确实晋升为主节点,如果此过程执行时间超过failover- timeout时,则故障转移失败;
如果命令其余从节点复制新的主节点阶段执行时间超过了failover-timeout(不包含复制时间), 则故障转移失败。注意即使超过了这个时间,Sentinel节点也会最终配置从 节点去同步最新的主节点。
-
sentinel 节点不应该部署在同一台物理机上; -
至少要部署三个以上的奇数 sentinel 节点; -
选一套还是多套 sentinel,如果选一套可以一定程度降低维护成本,但是如果 sentinel 节点出现异常,可能会多多个 redis 数据节点造成影响,如果是多套,会造成资源浪费,但是每套 sentinel 都彼此隔离。
public class RedisSentinelClient {
/**
* @param args
*/
public static void main(String[] args) {
Set sentinels = new HashSet();
sentinels.add(new HostAndPort("10.12.37.71", 26379).toString());
sentinels.add(new HostAndPort("10.12.37.72", 26380).toString());
sentinels.add(new HostAndPort("10.12.37.73", 26381).toString());
JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster", sentinels);
System.out.println("Current master: " + sentinelPool.getCurrentHostMaster().toString());
Jedis master = sentinelPool.getResource();
master.set("username","awen");
sentinelPool.returnResource(master);
Jedis master2 = sentinelPool.getResource();
String value = master2.get("username");
System.out.println("username: " + value);
master2.close();
sentinelPool.destroy();
}
}
实现原理
Sentinel 的三个定时监控任务:
每隔 10 秒向主节点和从节点发送 info 命令获取最新的拓扑。
每隔 2 秒,每个 sentinel 节点会向数据节点的
sentinel:hello
频道发送该 sentinel 节点对于主节点的判断以及当前 sentinel 节点信息,同时每个 sentinel 节点也会订阅该频道,来了解其他 sentinel 节点以及他们对主节点的判断。每个 1 秒,每个 sentinel 节点会向主节点、从节点、其他 sentinel 节点发送一条 ping 命令做一次心跳检测,判断节点是否存活。
主观下线:
当节点超过 down-after-milliseconds 没有进行有效回复,就会判定该节点失败,这叫主观下线。
客观下线:
当Sentinel主观下线的节点是主节点时,该Sentinel节点会通过sentinel is- master-down-by-addr命令向其他Sentinel节点询问对主节点的判断,当超过
个数,Sentinel节点认为主节点确实有问题,这时该Sentinel节点会 做出客观下线的决定 。
领导者选举:选举的过程非常快,基本上谁先完成客观下线,谁就是领导者。
每个在线的Sentinel节点都有资格成为领导者,当它确认主节点主观 下线时候,会向其他Sentinel节点发送sentinel is-master-down-by-addr命令, 要求将自己设置为领导者。
收到命令的Sentinel节点,如果没有同意过其他Sentinel节点的sentinel is-master-down-by-addr命令,将同意该请求,否则拒绝。
如果该Sentinel节点发现自己的票数已经大于等于max(quorum, num(sentinels)/2+1),那么它将成为领导者。
如果此过程没有选举出领导者,将进入下一次选举。
故障转移,在从节点列表中选出一个节点作为新的主节点,选择方法如下:
过滤:“不健康”(主观下线、断线)、5秒内没有回复过Sentinel节 点ping响应、与主节点失联超过down-after-milliseconds*10秒。
选择slave-priority(从节点优先级)最高的从节点列表,如果存在返回,不存在则继续。
选择复制偏移量最大的从节点(复制的最完整),如果存在则返回,不存在则继续。
选择runid最小的从节点。
【End】
热 文 推 荐
☞
点击阅读原文,参加中国开发者现状调查!