redis- sentinel整体架构图
redis客户端通过redis-sentinel来获取集群中的主从节点,同时redis-sentinel负责管理整个redis集群,当集群中的主节点发生宕机时,redis-sentinel负责选出新的主节点,并变更主从关系,同时会将最后的变更信息通知给客户端。
redis-sentinel集群的安装与配置
本地7000端口被占用,使用7001端口为主节点,7002、7003端口为从节点。
7001端口配置
port 7001
pidfile /var/run/redis_7001.pid
logfile "7001.log"
dbfilename dump-7001.rdb
dir /Users/xiaosa/learning/redis/data/7001-data
7002端口配置
port 7002
pidfile /var/run/redis_7002.pid
logfile "7002.log"
dbfilename dump-7002.rdb
dir /Users/xiaosa/learning/redis/data/7002-data
slaveof 127.0.0.1 7001
7003端口配置
port 7003
pidfile /var/run/redis_7003.pid
logfile "7003.log"
dbfilename dump-7003.rdb
dir /Users/xiaosa/learning/redis/data/7003-data
slaveof 127.0.0.1 7001
执行启动命令
./redis-server /Users/xiaosa/learning/redis/config/7001.conf &
./redis-server /Users/xiaosa/learning/redis/config/7002.conf &
./redis-server /Users/xiaosa/learning/redis/config/7003.conf &
查看启动状态
xiaosa@XIAOSAdeMacBook-Pro bin % ps -ef | grep redis
501 2873 556 0 5:44下午 ttys000 0:01.14 ./redis-server *:7003
501 2886 556 0 5:48下午 ttys000 0:00.33 ./redis-server *:7001
501 2898 556 0 5:49下午 ttys000 0:00.20 ./redis-server *:7002
501 2909 556 0 5:53下午 ttys000 0:00.00 grep redis
查看主节点集群状态
xiaosa@XIAOSAdeMacBook-Pro bin % ./redis-cli -h 127.0.0.1 -p 7001
127.0.0.1:7001> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=7003,state=online,offset=434,lag=1
slave1:ip=127.0.0.1,port=7002,state=online,offset=434,lag=1
master_failover_state:no-failover
master_replid:cd225765d88fab0e8cb14fec04a0aecc6422f824
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:434
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:434
开始安装配置sentinel
26379端口配置
port 26379
pidfile /var/run/redis-26379.pid
logfile "26379.log"
dir /Users/xiaosa/learning/redis/data/26379-data
sentinel monitor mymaster 127.0.0.1 7001 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
26380端口配置
port 26380
pidfile /var/run/redis-26380.pid
logfile "26380.log"
dir /Users/xiaosa/learning/redis/data/26380-data
sentinel monitor mymaster 127.0.0.1 7001 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
26381端口配置
port 26381
pidfile /var/run/redis-26381.pid
logfile "26381.log"
dir /Users/xiaosa/learning/redis/data/26381-data
sentinel monitor mymaster 127.0.0.1 7001 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
执行启动命令
./redis-sentinel /Users/xiaosa/learning/redis/config/26379.conf &
./redis-sentinel /Users/xiaosa/learning/redis/config/26380.conf &
./redis-sentinel /Users/xiaosa/learning/redis/config/26381.conf &
查看启动状态
xiaosa@XIAOSAdeMBP 26379-data % ps -ef | grep redis-sentinel
501 3048 556 0 6:33下午 ttys000 0:00.53 ./redis-sentinel *:26379 [sentinel]
501 3056 556 0 6:34下午 ttys000 0:00.44 ./redis-sentinel *:26380 [sentinel]
501 3057 556 0 6:34下午 ttys000 0:00.41 ./redis-sentinel *:26381 [sentinel]
501 3063 1978 0 6:36下午 ttys002 0:00.00 grep redis-sentinel
查看sentinel集群状态
xiaosa@XIAOSAdeMacBook-Pro bin % ./redis-cli -h 127.0.0.1 -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:7001,slaves=2,sentinels=3
启动成功,至此基于redis-sentinel的redis已搭建完成。
Jedis客户端链接sentinel集群
redis向sentinel集群中的一个节点发送请求,sentinel返回对应的主从节点信息。同时订阅redis- sentinel的一个channel,redis客户端根据返回的主从节点信息与redis进行直连。当redis集群发生变化时,通过channel向客户端发送节点变更信息。
客户端介入核心参数
sentinel地址集合。
masterName。
package com.test;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import java.util.Set;
public class JedisSentinelPoolTest {
public static void main(String[] args) {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
Set<String> sentinelSets = Set.of(
"127.0.0.1:26379",
"127.0.0.1:26380",
"127.0.0.1:26381"
);
JedisSentinelPool pool = new JedisSentinelPool("mymaster",sentinelSets,config);
Jedis jedis = null;
try {
jedis = pool.getResource();
jedis.set("key","value");
String value = jedis.get("key");
System.out.println(value);
}catch (Exception e){
e.printStackTrace();
}finally {
if(jedis != null){
jedis.close();
}
}
}
}
// 控制台输出
20:32:21.129 [main] INFO redis.clients.jedis.JedisSentinelPool - Trying to find master from available Sentinels...
20:32:21.130 [main] DEBUG redis.clients.jedis.JedisSentinelPool - Connecting to Sentinel 127.0.0.1:26381
20:32:21.175 [main] DEBUG redis.clients.jedis.JedisSentinelPool - Found Redis master at 127.0.0.1:7001
20:32:21.176 [main] INFO redis.clients.jedis.JedisSentinelPool - Redis master running at 127.0.0.1:7001, starting Sentinel listeners...
20:32:21.177 [main] INFO redis.clients.jedis.JedisSentinelPool - Created JedisSentinelPool to master at 127.0.0.1:7001
value
Process finished with exit code 0
sentinel的三个定时任务
每10秒钟,每个sentinel节点对master和slave执行info命令。
每2秒每个sentinel通过master节点的channel交换信息(pub/sub)
通过__sentinel__:hello频道交互。
交互对节点的“看法”和自身信息。
每1秒每个sentinel对其他sentinel和redis执行ping
失败的判断依据。
sentinel主观下线与客观下线
两个关键配置
sentinel monitor <masterName> <ip> <port> <quorum>,masterName集群名称,ip:master节点ip,port:master节点端口,quorum:投票数,当某一个redis节点宕机时,达到quorum个sentinel认为宕机,如果是主节点进行故障转移,从节点进行下线操作。
sentinel down-after-milliseconds <masterName> <timeout>,masterName集群名称,sentinel与主节点的断开时间。
redis-sentinel与redis集群中的个个节点每秒进行ping操作,某一个sentinel如果发现超过 down-after-milliseconds配置的时间,则认为该节点已宕机,此时针对该节点的下线成为主观下线。当sentinel集群中超过quorum个节点认为该节点宕机时称为客观下线。
执行客观下线
执行客观下线操作需要sentinel集群选举出一个执行者,底层的共识协议使用的时raft算法。
sentinel故障转移的过程
从slave节点中选取一个“合适的”节点作为新的master节点。
slave-priority(优先级)最好的节点,当从节点的配置不相同时,通常会将配置更好的节点优先级增大。如果优先级相同,进行下一条件判断。
选择复制偏移量更大的slave节点。如果偏移量相同,进行下一条件判断。
选择runid最小的节点(启动更早的节点)。
对上面的slave节点执行slaveof no one命令让其成为master节点。
向剩余的slave节点发送命令,让他们成为新master节点的slave节点。
更新原有master节点的配置为slave,并保持着对它的“关注”,在其恢复后命令其去同步新master节点的数据。