千家信息网

怎么使用docker搭建redis主从哨兵模式,并整合进springboot项目

发表于:2025-01-25 作者:千家信息网编辑
千家信息网最后更新 2025年01月25日,这篇文章主要介绍"怎么使用docker搭建redis主从哨兵模式,并整合进springboot项目",在日常操作中,相信很多人在怎么使用docker搭建redis主从哨兵模式,并整合进springbo
千家信息网最后更新 2025年01月25日怎么使用docker搭建redis主从哨兵模式,并整合进springboot项目

这篇文章主要介绍"怎么使用docker搭建redis主从哨兵模式,并整合进springboot项目",在日常操作中,相信很多人在怎么使用docker搭建redis主从哨兵模式,并整合进springboot项目问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"怎么使用docker搭建redis主从哨兵模式,并整合进springboot项目"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

其实上一篇的思路做法是百度后参考各种博客文章搭的,但是发现最后还是有问题后,就直接去官网看文档了,于是在之前的熟悉的基础的下,重新搭了一遍,在基于容器网络的情况下,实现主备来回自动切换功能。

1,先上redis主备编排文件,master-slave/docker-compose.yml

version: "3"services:  master:    image: redis:latest    container_name: redis-master    command: redis-server /usr/local/etc/redis/redis.conf    ports:    - "6379:6379"    volumes:    - "/root/redis/redis-master.conf:/usr/local/etc/redis/redis.conf"    networks:    - sentinel-master  slave1:    image: redis:latest    container_name: redis-slave-1    command: redis-server /usr/local/etc/redis/redis.conf    depends_on:    - master    ports:    - "6380:6379"    volumes:    - "/root/redis/redis-slave-1.conf:/usr/local/etc/redis/redis.conf"    networks:    - sentinel-master  slave2:    image: redis:latest    container_name: redis-slave-2    command: redis-server /usr/local/etc/redis/redis.conf    depends_on:    - master    ports:    - "6381:6379"    volumes:    - "/root/redis/redis-slave-2.conf:/usr/local/etc/redis/redis.conf"    networks:    - sentinel-masternetworks:  sentinel-master:

这里还是使用配置文件,加多了两个配置项,用于宣布ip和端口给哨兵,防止哨兵取容器内网ip

redis-master.conf

port 6379requirepass 123456#  防止重启后,作为从节点加入集群时认证失败masterauth 123456# 宣布给哨兵的ip,如不配置,哨兵会取容器内部ip,这样客户端就无法访问了slave-announce-ip 192.168.1.254# 宣布给哨兵的端口slave-announce-port 6379

redis-slave-1.conf

port 6379requirepass 123456slaveof 192.168.1.254 6379masterauth 123456slave-announce-ip 192.168.1.254slave-announce-port 6380

redis-slave-2.conf

port 6379requirepass 123456slaveof 192.168.1.254 6379masterauth 123456slave-announce-ip 192.168.1.254slave-announce-port 6381

2,哨兵编排文件,sentinel/docker-compose.yml

# Example sentinel.conf can be downloaded from http://download.redis.io/redis-stable/sentinel.confversion: "3"services:  sentinel1:    image: redis:latest    container_name: redis-sentinel-1    command: redis-sentinel /usr/local/etc/redis/sentinel.conf    ports:    - "26379:26379"    volumes:    - "/root/redis/sentinel1.conf:/usr/local/etc/redis/sentinel.conf"  sentinel2:    image: redis:latest    container_name: redis-sentinel-2    command: redis-sentinel /usr/local/etc/redis/sentinel.conf    ports:    - "26380:26379"    volumes:    - "/root/redis/sentinel2.conf:/usr/local/etc/redis/sentinel.conf"  sentinel3:    image: redis:latest    container_name: redis-sentinel-3    command: redis-sentinel /usr/local/etc/redis/sentinel.conf    ports:    - "26381:26379"    volumes:    - "/root/redis/sentinel3.conf:/usr/local/etc/redis/sentinel.conf"networks:  default:    external:      name: "master-slave_sentinel-master"

sentinel1.conf,sentinel2.conf, sentinel3.conf 初始的内容完全一样,只是会在哨兵启动重写会变得不一样,这个是由哨兵自动完成的

port 26379dir /tmpsentinel monitor mymaster 192.168.1.254 6379 2sentinel auth-pass mymaster 123456sentinel down-after-milliseconds mymaster 30000sentinel parallel-syncs mymaster 1sentinel failover-timeout mymaster 10000sentinel deny-scripts-reconfig yes

3,springboot整合,及测试程序还是一样

引入依赖

    org.springframework.boot    spring-boot-starter-data-redis

application.yml

spring:  redis:    sentinel:      master: mymaster      nodes:      - "192.168.1.254:26379"      - "192.168.1.254:26380"      - "192.168.1.254:26381"    host: 192.168.1.254    password: 123456    jedis:      pool:        min-idle: 8        max-active: 100        max-wait: 3000        max-idle: 100

测试程序,3个线程模拟并发插入数据,一共3000条

@Testpublic void testRedisMasterSlave() throws Exception {        ValueOperations valueOperations = redisTemplate.opsForValue();        ExecutorService es = Executors.newFixedThreadPool(3);        for (int j = 0; j < 3; j++) {                es.submit(() -> {                        for (int i = 0; i < 1000; i++) {                                try {                                        String threadName = Thread.currentThread().getName();                                        valueOperations.set(threadName + i, i + "", 30L, TimeUnit.MINUTES);                                        TimeUnit.MILLISECONDS.sleep(200L);                                } catch (InterruptedException e) {                                        System.out.println("error: " + e.getMessage());                                }                        }                });        }        es.shutdown();        es.awaitTermination(30L, TimeUnit.MINUTES);}

准备完成,分别启动redis( master-slave/docker-compose.yml),哨兵(sentinel/docker-compose.yml)

执行junit测试程序,并在中途停掉redis-master节点

2019-10-06 21:50:24.199  INFO 128256 --- [pool-1-thread-1] io.lettuce.core.EpollProvider            : Starting without optional epoll library2019-10-06 21:50:24.201  INFO 128256 --- [pool-1-thread-1] io.lettuce.core.KqueueProvider           : Starting without optional kqueue library2019-10-06 21:51:11.141  INFO 128256 --- [xecutorLoop-1-6] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was /192.168.1.254:63792019-10-06 21:51:13.161  WARN 128256 --- [ioEventLoop-4-4] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /192.168.1.254:63792019-10-06 21:51:17.440  INFO 128256 --- [xecutorLoop-1-7] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.1.254:63792019-10-06 21:51:19.450  WARN 128256 --- [ioEventLoop-4-2] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /192.168.1.254:63792019-10-06 21:51:23.741  INFO 128256 --- [xecutorLoop-1-8] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.1.254:63792019-10-06 21:51:25.748  WARN 128256 --- [ioEventLoop-4-8] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /192.168.1.254:63792019-10-06 21:51:30.840  INFO 128256 --- [xecutorLoop-1-3] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.1.254:63792019-10-06 21:51:32.848  WARN 128256 --- [ioEventLoop-4-6] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /192.168.1.254:63792019-10-06 21:51:38.041  INFO 128256 --- [xecutorLoop-1-7] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.1.254:63792019-10-06 21:51:40.050  WARN 128256 --- [ioEventLoop-4-2] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /192.168.1.254:63792019-10-06 21:51:44.241  INFO 128256 --- [xecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.1.254:63792019-10-06 21:51:44.248  INFO 128256 --- [ioEventLoop-4-4] i.l.core.protocol.ReconnectionHandler    : Reconnected to 192.168.1.254:6380

控制台打印的消息由6379端口,切换到了6380端口,证明哨兵已经完成主备切换了。

接下来再把redis-master节点重新启动,查看容器启动日志

2019-10-05T19:05:51.594625998Z 1:S 05 Oct 2019 19:05:51.594 * Before turning into a replica, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.2019-10-05T19:05:51.594679191Z 1:S 05 Oct 2019 19:05:51.594 * REPLICAOF 192.168.1.254:6380 enabled (user request from 'id=4 addr=172.23.0.1:43460 fd=9 name=sentinel-36a0e6b8-cmd age=10 idle=0 flags=x db=0 sub=0 psub=0 multi=3 qbuf=153 qbuf-free=32615 obl=36 oll=0 omem=0 events=r cmd=exec')2019-10-05T19:05:51.594683850Z 1:S 05 Oct 2019 19:05:51.594 # CONFIG REWRITE failed: Permission denied2019-10-05T19:05:51.961959923Z 1:S 05 Oct 2019 19:05:51.961 * Connecting to MASTER 192.168.1.254:63802019-10-05T19:05:51.961989715Z 1:S 05 Oct 2019 19:05:51.961 * MASTER <-> REPLICA sync started2019-10-05T19:05:51.961995348Z 1:S 05 Oct 2019 19:05:51.961 * Non blocking connect for SYNC fired the event.2019-10-05T19:05:51.962964412Z 1:S 05 Oct 2019 19:05:51.962 * Master replied to PING, replication can continue...2019-10-05T19:05:51.963959151Z 1:S 05 Oct 2019 19:05:51.963 * Trying a partial resynchronization (request d0c6a5694d17b9337656d0ef009aa580e0743431:1).2019-10-05T19:05:51.967159605Z 1:S 05 Oct 2019 19:05:51.966 * Full resync from master: bfcd3bb8bbfb2393ded951443e9e2100ed490548:1339112019-10-05T19:05:51.967200123Z 1:S 05 Oct 2019 19:05:51.966 * Discarding previously cached master state.2019-10-05T19:05:52.064097244Z 1:S 05 Oct 2019 19:05:52.062 * MASTER <-> REPLICA sync: receiving 51791 bytes from master2019-10-05T19:05:52.064114578Z 1:S 05 Oct 2019 19:05:52.062 * MASTER <-> REPLICA sync: Flushing old data2019-10-05T19:05:52.064124761Z 1:S 05 Oct 2019 19:05:52.062 * MASTER <-> REPLICA sync: Loading DB in memory2019-10-05T19:05:52.064128120Z 1:S 05 Oct 2019 19:05:52.063 * MASTER <-> REPLICA sync: Finished with success

发现节点已经主动找到当前master节点192.168.1.254:6380,并进行全量复制了。

再进入哨兵节点查看slave节点信息

127.0.0.1:26379> sentinel slaves mymaster1)  1) "name"    2) "192.168.1.254:6379"    3) "ip"    4) "192.168.1.254"    5) "port"    6) "6379"    7) "runid"    8) "d4d7ce3f1cc4d5c6cca2345318e4dcfebe12fcce"    9) "flags"   10) "slave"   11) "link-pending-commands"   12) "0"   13) "link-refcount"   14) "1"   15) "last-ping-sent"   16) "0"   17) "last-ok-ping-reply"   18) "872"   19) "last-ping-reply"   20) "872"   21) "down-after-milliseconds"   22) "30000"   23) "info-refresh"   24) "2519"   25) "role-reported"   26) "slave"   27) "role-reported-time"   28) "5867007"   29) "master-link-down-time"   30) "0"   31) "master-link-status"   32) "ok"   33) "master-host"   34) "192.168.1.254"   35) "master-port"   36) "6380"   37) "slave-priority"   38) "100"   39) "slave-repl-offset"   40) "1526467"2)  1) "name"    2) "192.168.1.254:6381"    3) "ip"    4) "192.168.1.254"    5) "port"    6) "6381"    7) "runid"    8) "2fecd472915d77b55d230c339f5982491ee55d69"    9) "flags"   10) "slave"   11) "link-pending-commands"   12) "0"   13) "link-refcount"   14) "1"   15) "last-ping-sent"   16) "0"   17) "last-ok-ping-reply"   18) "872"   19) "last-ping-reply"   20) "872"   21) "down-after-milliseconds"   22) "30000"   23) "info-refresh"   24) "6520"   25) "role-reported"   26) "slave"   27) "role-reported-time"   28) "5940478"   29) "master-link-down-time"   30) "0"   31) "master-link-status"   32) "ok"   33) "master-host"   34) "192.168.1.254"   35) "master-port"   36) "6380"   37) "slave-priority"   38) "100"   39) "slave-repl-offset"   40) "1525639"

发现6379节点也已经加入到slave节点了,到此哨兵模式高可用方案就算完成了。

到此,关于"怎么使用docker搭建redis主从哨兵模式,并整合进springboot项目"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0