搭建Redis哨兵集群
因公司项目需求原因,Redis用的是Redis哨兵集群模式,个人没有多余的电脑和服务器(穷)去搭建一样的环境,于是就选用了虚拟机+docker+docker-compose+Redis搭建Redis哨兵集群模拟。
哨兵集群:一主两从三哨兵
1、安装环境(参考)
- 虚拟机:VMware® Workstation 15 Pro
- docker:20.10.17
- docker-compose:v2.6.0
- redis镜像:redis:latest
2、搭建步骤
1)创建文件夹及文件
虚拟机usr/soft/dockers目录下创建文件夹及文件,结构如下:
-
redis-sentinel
-
redis
- docker-compose.yml
- redis1.conf
- redis2.conf
- redis3.conf
-
sentinel
- docker-compose.yml
- sentinel1.conf
- sentinel2.conf
- sentinel3.conf
- docker-compose.yml
-
2)添加配置文件
*注意将配置文件中对应ip改成本地电脑虚拟机的固定ip即可
redis目录
- docker-compose.yml
version: '3.4'
services:
master:
image: redis
container_name: redis-master
restart: always
volumes:
- ./redis1.conf:/usr/local/etc/redis/redis.conf
ports:
- 6379:6379
slave1:
image: redis
container_name: redis-slave-1
restart: always
volumes:
- ./redis2.conf:/usr/local/etc/redis/redis.conf
ports:
- 6380:6379
slave2:
image: redis
container_name: redis-slave-2
restart: always
volumes:
- ./redis3.conf:/usr/local/etc/redis/redis.conf
ports:
- 6381:6379
-
redis1.conf
port 6379 daemonize no logfile /logs/redis.log appendonly yes requirepass 1234 masterauth 1234
-
redis2.conf、redis.conf在redis1.conf
的基础上多了slaveof 192.168.232.130 6379
sentienl目录
-
docker-compose.yml
version: '3' services: sentinel1: image: redis container_name: redis-sentinel-1 ports: - 26379:26379 command: redis-sentinel /usr/local/etc/redis/sentinel.conf volumes: - ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf sentinel2: image: redis container_name: redis-sentinel-2 ports: - 26380:26379 command: redis-sentinel /usr/local/etc/redis/sentinel.conf volumes: - ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf sentinel3: image: redis container_name: redis-sentinel-3 ports: - 26381:26379 command: redis-sentinel /usr/local/etc/redis/sentinel.conf volumes: - ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf
-
sentinel1.conf
port 26379 dir "/tmp" # 自定义集群名,其中 127.0.0.1 为 redis-master 的 ip,6379 为 redis-master 的端口,2 为最小投票数(因为有 3 台 Sentinel 所以可以设置成 2) sentinel myid mk9vfc5x539dmr7xkm0q2aiml1ownqtarg3e5auu sentinel deny-scripts-reconfig yes sentinel monitor mymaster 192.168.232.130 6379 2 sentinel auth-pass mymaster 1234 sentinel config-epoch mymaster 0 sentinel leader-epoch mymaster 0 # Generated by CONFIG REWRITE sentinel known-replica mymaster 192.168.232.130 6381 sentinel known-replica mymaster 192.168.232.130 6380 sentinel known-sentinel mymaster 192.168.232.130 26381 p88utx173ga7body483zy21dn3ex8i9fzmh2un99 sentinel known-sentinel mymaster 192.168.232.130 26380 0da6yqhudf6bmvnkat5rds5s3bqs9imdg1kbz0mj sentinel current-epoch 0 # 哨兵从master节点宕机后,等待多少时间(毫秒),认定master不可用。 # 默认30s,这里为了测试,改成10s sentinel down-after-milliseconds mymaster 10000 # 当替换主节点后,剩余从节点重新和新master做同步的并行数量,默认为 1 sentinel parallel-syncs mymaster 1 # 主备切换的时间,若在3分钟内没有切换成功,换另一个从节点切换 sentinel failover-timeout mymaster 180000
-
sentinel2.conf
port 26380
dir "/tmp"
# 自定义集群名,其中 127.0.0.1 为 redis-master 的 ip,6379 为 redis-master 的端口,2 为最小投票数(因为有 3 台 Sentinel 所以可以设置成 2)
sentinel myid 0da6yqhudf6bmvnkat5rds5s3bqs9imdg1kbz0mj
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 192.168.232.130 6379 2
sentinel auth-pass mymaster 1234
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
# Generated by CONFIG REWRITE
sentinel known-replica mymaster 192.168.232.130 6381
sentinel known-replica mymaster 192.168.232.130 6380
sentinel known-sentinel mymaster 192.168.232.130 26379 mk9vfc5x539dmr7xkm0q2aiml1ownqtarg3e5auu
sentinel known-sentinel mymaster 192.168.232.130 26381 p88utx173ga7body483zy21dn3ex8i9fzmh2un99
sentinel current-epoch 0
# 哨兵从master节点宕机后,等待多少时间(毫秒),认定master不可用。
# 默认30s,这里为了测试,改成10s
sentinel down-after-milliseconds mymaster 10000
# 当替换主节点后,剩余从节点重新和新master做同步的并行数量,默认为 1
sentinel parallel-syncs mymaster 1
# 主备切换的时间,若在3分钟内没有切换成功,换另一个从节点切换
sentinel failover-timeout mymaster 180000
- sentinel3.conf
port 26381
dir "/tmp"
# 自定义集群名,其中 192.168.232.130 为 redis-master 的 ip,6379 为 redis-master 的端口,2 为最小投票数(因为有 3 台 Sentinel 所以可以设置成 2)
sentinel myid p88utx173ga7body483zy21dn3ex8i9fzmh2un99
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 192.168.232.130 6379 2
sentinel auth-pass mymaster 1234
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
# Generated by CONFIG REWRITE
sentinel known-replica mymaster 192.168.232.130 6380
sentinel known-replica mymaster 192.168.232.130 6381
sentinel known-sentinel mymaster 192.168.232.130 26380 0da6yqhudf6bmvnkat5rds5s3bqs9imdg1kbz0mj
sentinel known-sentinel mymaster 192.168.232.130 26379 mk9vfc5x539dmr7xkm0q2aiml1ownqtarg3e5auu
sentinel current-epoch 0
# 哨兵从master节点宕机后,等待多少时间(毫秒),认定master不可用。
# 默认30s,这里为了测试,改成10s
sentinel down-after-milliseconds mymaster 10000
# 当替换主节点后,剩余从节点重新和新master做同步的并行数量,默认为 1
sentinel parallel-syncs mymaster 1
# 主备切换的时间,若在3分钟内没有切换成功,换另一个从节点切换
sentinel failover-timeout mymaster 180000
3)启动容器
-
首先进入redis目录下,执行启动命令:
docker-compose up -d
[root@centos7 redis]# ll 总用量 16 -rw-r--r--. 1 root root 1012 10月 26 23:02 docker-compose.yml -rw-r--r--. 1 root root 135 10月 26 23:02 redis1.conf -rw-r--r--. 1 root root 131 10月 26 23:02 redis2.conf -rw-r--r--. 1 root root 131 10月 26 23:02 redis3.conf [root@centos7 redis]# docker-compose up -d [+] Running 4/4 ⠿ Network redis_default Created 0.1s ⠿ Container redis-slave-2 Started 1.1s ⠿ Container redis-master Started 1.1s ⠿ Container redis-slave-1 Started 1.1s [root@centos7 redis]# docker-compose ps NAME COMMAND SERVICE STATUS PORTS redis-master "docker-entrypoint.s…" master running 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis-slave-1 "docker-entrypoint.s…" slave1 running 0.0.0.0:6380->6379/tcp, :::6380->6379/tcp redis-slave-2 "docker-entrypoint.s…" slave2 running 0.0.0.0:6381->6379/tcp, :::6381->6379/tcp
-
然后进入sentinel目录下,执行启动命令:
docker-compose up -d
[root@centos7 sentinel]# ll 总用量 16 -rw-r--r--. 1 root root 747 10月 26 15:28 docker-compose.yml -rw-r--r--. 1 root root 1241 10月 26 15:50 sentinel1.conf -rw-r--r--. 1 root root 1241 10月 26 15:50 sentinel2.conf -rw-r--r--. 1 root root 1241 10月 26 15:50 sentinel3.conf [root@centos7 sentinel]# docker-compose up -d [+] Running 4/4 ⠿ Network sentinel_default Created 0.1s ⠿ Container redis-sentinel-3 Started 1.5s ⠿ Container redis-sentinel-1 Started 1.6s ⠿ Container redis-sentinel-2 Started 1.5s [root@centos7 sentinel]# docker-compose ps NAME COMMAND SERVICE STATUS PORTS redis-sentinel-1 "docker-entrypoint.s…" sentinel1 running 0.0.0.0:26379->26379/tcp, :::26379->26379/tcp redis-sentinel-2 "docker-entrypoint.s…" sentinel2 running 0.0.0.0:26380->26379/tcp, :::26380->26379/tcp redis-sentinel-3 "docker-entrypoint.s…" sentinel3 running 0.0.0.0:26381->26379/tcp, :::26381->26379/tcp
4)查看状态
-
在第一步启动redis后,使用
docker exec -it redis-master bash
,进入redis三个节点(一个即可),然后执行redis-cli -p 6379
连接redis,然后执行info replication
查看主从状态,这时候不显示主从关系[root@centos7 redis]# docker exec -it redis-master bash root@f6c863c22248:/data# redis-cli -p 6379 127.0.0.1:6379> info replication # Replication role:master connected_slaves:0 master_failover_state:no-failover master_replid:4b24b632e7f8ccac9cb9e995639ec01c5a73e45f master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0
-
在启动sentinel后,使用
docker exec -it redis-sentinel-1 bash
,进入sentinel三个节点(一个即可),然后执行redis-cli -p 26379
连接redis,然后执行info sentinel
查看哨兵中当前redis的主节点信息及注册节点数[root@centos7 sentinel]# docker exec -it redis-sentinel-1 bash root@32f8c76dc918:/data# redis-cli -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=192.168.232.130:6379,slaves=3,sentinels=3
-
然后再回到执行第一步命令,在redis中查看主从状态,此时主节点信息和sentinel哨兵中显示的主节点信息一致
127.0.0.1:6379> info replication Error: Broken pipe not connected> info replication # Replication role:slave master_host:172.18.0.1 master_port:6379 master_link_status:down master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_read_repl_offset:6817 slave_repl_offset:6817 master_link_down_since_seconds:-1 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:2 slave0:ip=172.18.0.1,port=6379,state=online,offset=6817,lag=0 slave1:ip=172.18.0.1,port=6379,state=online,offset=6817,lag=0 master_failover_state:no-failover master_replid:8cc606b65ace0e6ce04006c38fe5610c3e46b78d master_replid2:bea30e1b7447b84f0bf5e284ac58ff48e92d74e0 master_repl_offset:6817 second_repl_offset:2861 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:6817
3、创建测试项目
创建springboot项目
1)添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2)配置信息
server:
port: 8080
spring:
application:
name: redissentinel
redis:
sentinel:
master: mymaster
#哨兵集群的地址(修改为虚拟机ip)
nodes: 192.168.232.130:26379,192.168.232.130:26380,192.168.232.130:26381
jedis:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: -1
3)核心代码
-
RedisConfig
/** * redis配置 */ @Configuration public class RedisConfig { /** * 方法描述: 初始化redis连接 * @param factory redis连接工厂 * @return {@link RedisTemplate} */ @Bean public RedisTemplate redisTemplate(RedisConnectionFactory factory) { // 新建redisTemplate对象 RedisTemplate<String, Object> template = new RedisTemplate<>(); // 设置工厂 template.setConnectionFactory(factory); //序列化配置 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); //1,用StringRedisSerializer进行序列化的值,在Java和Redis中保存的内容是一样的 //2,用Jackson2JsonRedisSerializer进行序列化的值,在Redis中保存的内容,比Java中多了一对双引号。 //3,用JdkSerializationRedisSerializer进行序列化的值,对于Key-Value的Value来说,是在Redis中是不可读的。对于Hash的Value来说,比Java的内容多了一些字符。 //如果Key的Serializer也用和Value相同的Serializer的话,在Redis中保存的内容和上面Value的差异是一样的,所以我们保存时,只用StringRedisSerializer进行序列化 // key采用String的序列化方式 template.setKeySerializer(stringRedisSerializer); // value序列化方式采用jackson template.setValueSerializer(stringRedisSerializer); // hash的key也采用String的序列化方式 template.setHashKeySerializer(stringRedisSerializer); // hash的value序列化方式采用jackson template.setHashValueSerializer(stringRedisSerializer); // 返回redisTemplate对象 return template; } }
-
RedisThreadPoolConfig
/** * redis测试线程池 */ @Configuration public class RedisThreadPoolConfig { @Bean("redisThreadPool") public Executor msgThreadPool() { //获取当前机器的核数 int cpuNum = Runtime.getRuntime().availableProcessors(); ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //配置核心线程数cpuNum executor.setCorePoolSize(cpuNum); //配置最大线程数cpuNum * 2 executor.setMaxPoolSize(cpuNum * 2); //配置队列大小 executor.setQueueCapacity(1000); //线程存活时间 executor.setKeepAliveSeconds(60); //配置线程池中的线程的名称前缀 executor.setThreadNamePrefix("redis-pool-thread-"); // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //执行初始化 executor.initialize(); return executor; } }
-
RedisConstant
public class RedisConstant { /** * 模拟数据,key报存位置 */ public static ArrayList<String> redisKeyList = new ArrayList<>(); }
-
RedisUtil
/** * redis工具类 */ @Component public class RedisUtil { @Autowired private RedisTemplate redisTemplate; // =============================common============================ /** * 指定缓存失效时间 * * @param key 键 * @param time 时间(秒) * @return */ public boolean expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据key 获取过期时间 * * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */ public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 判断key是否存在 * * @param key 键 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除缓存 * * @param key 可以传一个值 或多个 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } // ============================String============================= /** * 普通缓存获取 * * @param key 键 * @return 值 */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * * @param key 键 * @param value 值 * @return true成功 false失败 */ public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通缓存放入并设置时间 * * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 * @return true成功 false 失败 */ public boolean set(String key, Object value, long time) { try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); } else { set(key, value); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } }
-
RedisInit
/** * 项目启动后自动执行redis测试 */ @Slf4j @Component public class RedisInit { @Autowired private RedisService redisService; @PostConstruct public void start(){ /* * 循环10000次,每次间隔 400毫秒 */ for (int i = 0; i < 100000; i++) { redisService.setValue(i); if(i>10){ redisService.getValue(); } try { TimeUnit.MILLISECONDS.sleep(400); } catch (InterruptedException e) { log.error("延时执行异常",e); } } } }
-
RedisService
/** * redis测试实际执行逻辑 */ @Slf4j @Service public class RedisService { @Autowired private RedisUtil redisUtil; private static Random random = new Random(); /** * 线程异步添加数据到redis中 * @param i 当前添加次数 */ @Async("redisThreadPool") public void setValue(int i) { String key = "key"+i; String value = "value"+i; try { redisUtil.set(key,value); RedisConstant.redisKeyList.add(key); log.info("redis写数据key:{},value={}",key,value); }catch (Exception e){ log.error("redis写数据:key:{},value:{}失败,{}",key,value,e.getMessage(),e); } } /** *在redis历史添加数据中,随机选取一个key值,进行查找对应value */ @Async("redisThreadPool") public void getValue() { int index = random.nextInt(RedisConstant.redisKeyList.size()); String key = RedisConstant.redisKeyList.get(index); try { String value = redisUtil.get(key).toString(); log.info("redis查询数据key={},value={}",key,value); }catch (Exception e){ log.error("redis读数据key:{}:失败,{}",e.getMessage(),e); } } }
4)启动项目
启动项目后,会看到控制台打印不断的在写入redis,并且i>10后开始随机读取redis中的值
2022-10-27 17:59:04.147 INFO 29224 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1096 ms
2022-10-27 17:59:05.088 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key0,value=value0
2022-10-27 17:59:05.490 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key1,value=value1
2022-10-27 17:59:05.893 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key2,value=value2
2022-10-27 17:59:06.294 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key3,value=value3
2022-10-27 17:59:06.696 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key4,value=value4
2022-10-27 17:59:07.098 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key5,value=value5
2022-10-27 17:59:07.500 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key6,value=value6
2022-10-27 17:59:07.902 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key7,value=value7
2022-10-27 17:59:08.304 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key8,value=value8
2022-10-27 17:59:08.706 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key9,value=value9
2022-10-27 17:59:09.109 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key10,value=value10
2022-10-27 17:59:09.511 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key11,value=value11
2022-10-27 17:59:09.513 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis查询数据key=key10,value=value10
2022-10-27 17:59:09.915 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key12,value=value12
2022-10-27 17:59:09.916 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis查询数据key=key10,value=value10
2022-10-27 17:59:10.318 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key13,value=value13
2022-10-27 17:59:10.319 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis查询数据key=key0,value=value0
2022-10-27 17:59:10.721 INFO 29224 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key14,value=value14
5)高可用测试
步骤(启动项目后):
下方展示是操作两次的结果,第一次在控制台日志上没有显示主节点切换痕迹
-
哨兵中查看当前redis主节点(比如master),手动停止master节点:
docker-compose down master
[root@centos7 redis]# docker-compose stop master [+] Running 1/1 ⠿ Container redis-master Stopped 0.2s [root@centos7 redis]# docker-compose ps NAME COMMAND SERVICE STATUS PORTS redis-master "docker-entrypoint.s…" master exited (0) redis-slave-1 "docker-entrypoint.s…" slave1 running 0.0.0.0:6380->6379/tcp, :::6380->6379/tcp redis-slave-2 "docker-entrypoint.s…" slave2 running 0.0.0.0:6381->6379/tcp, :::6381->6379/tcp [root@centos7 redis]# docker-compose restart master [+] Running 1/1 ⠿ Container redis-master Started 0.5s [root@centos7 redis]# docker-compose ps NAME COMMAND SERVICE STATUS PORTS redis-master "docker-entrypoint.s…" master running 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis-slave-1 "docker-entrypoint.s…" slave1 running 0.0.0.0:6380->6379/tcp, :::6380->6379/tcp redis-slave-2 "docker-entrypoint.s…" slave2 running 0.0.0.0:6381->6379/tcp, :::6381->6379/tcp
-
然后观察控制台日志redis的读写情况是否正常,以及在sentinel中查看主节点状态(操作参考)
2022-10-27 16:46:40.569 INFO 24800 --- [xecutorLoop-1-4] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was /192.168.232.130:6380 2022-10-27 16:46:42.610 WARN 24800 --- [ioEventLoop-4-4] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [192.168.232.130:6380]: Connection refused: no further information: /192.168.232.130:6380 2022-10-27 16:46:46.869 INFO 24800 --- [xecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was 192.168.232.130:6380 2022-10-27 16:46:48.902 WARN 24800 --- [ioEventLoop-4-2] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [192.168.232.130:6380]: Connection refused: no further information: /192.168.232.130:6380 2022-10-27 16:46:53.168 INFO 24800 --- [xecutorLoop-1-8] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was 192.168.232.130:6380 2022-10-27 16:46:53.174 INFO 24800 --- [ioEventLoop-4-8] i.l.core.protocol.ReconnectionHandler : Reconnected to 192.168.232.130:6381 2022-10-27 16:46:53.174 INFO 24800 --- [ restartedMain] com.mengl.sentinel.service.RedisService : redis写数据key:key470,value=value470
[root@centos7 sentinel]# docker exec -it redis-sentinel-1 bash root@cd6a26c2b10d:/data# redis-cli -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=sdown,address=192.168.232.130:6379,slaves=3,sentinels=3 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=192.168.232.130:6380,slaves=3,sentinels=3
-
手动重启(重点:重启不是启动)停止的,命令:
docker-compose restart master
[root@centos7 redis]# docker-compose stop slave1
[+] Running 1/1
⠿ Container redis-slave-1 Stopped 0.8s
[root@centos7 redis]# docker-compose restart slave1
[+] Running 1/1
⠿ Container redis-slave-1 Started 0.7s
[root@centos7 redis]# docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
redis-master "docker-entrypoint.s…" master running 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp
redis-slave-1 "docker-entrypoint.s…" slave1 running 0.0.0.0:6380->6379/tcp, :::6380->6379/tcp
redis-slave-2 "docker-entrypoint.s…" slave2 running 0.0.0.0:6381->6379/tcp, :::6381->6379/tcp
6)注意事项
- redis是在哨兵集群启动起来后才进行选举,区分主从的;
- 其中操作的命令要注意,容器重启必须使用命令:
docker-compose restart slave1