这篇文章主要介绍“怎么使用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-master networks: sentinel-master:
这里还是使用配置文件,加多了两个配置项,用于宣布ip和端口给哨兵,防止哨兵取容器内网ip
redis-master.conf
port 6379 requirepass 123456 # 防止重启后,作为从节点加入集群时认证失败 masterauth 123456 # 宣布给哨兵的ip,如不配置,哨兵会取容器内部ip,这样客户端就无法访问了 slave-announce-ip 192.168.1.254 # 宣布给哨兵的端口 slave-announce-port 6379
redis-slave-1.conf
port 6379 requirepass 123456 slaveof 192.168.1.254 6379 masterauth 123456 slave-announce-ip 192.168.1.254 slave-announce-port 6380
redis-slave-2.conf
port 6379 requirepass 123456 slaveof 192.168.1.254 6379 masterauth 123456 slave-announce-ip 192.168.1.254 slave-announce-port 6381
2,哨兵编排文件,sentinel/docker-compose.yml
# Example sentinel.conf can be downloaded from http://download.redis.io/redis-stable/sentinel.conf version: "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 26379 dir /tmp sentinel monitor mymaster 192.168.1.254 6379 2 sentinel auth-pass mymaster 123456 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 10000 sentinel deny-scripts-reconfig yes
3,springboot整合,及测试程序还是一样
引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
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条
@Test public void testRedisMasterSlave() throws Exception { ValueOperations<String, String> 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 library 2019-10-06 21:50:24.201 INFO 128256 --- [pool-1-thread-1] io.lettuce.core.KqueueProvider : Starting without optional kqueue library 2019-10-06 21:51:11.141 INFO 128256 --- [xecutorLoop-1-6] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was /192.168.1.254:6379 2019-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:6379 2019-10-06 21:51:17.440 INFO 128256 --- [xecutorLoop-1-7] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was 192.168.1.254:6379 2019-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:6379 2019-10-06 21:51:23.741 INFO 128256 --- [xecutorLoop-1-8] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was 192.168.1.254:6379 2019-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:6379 2019-10-06 21:51:30.840 INFO 128256 --- [xecutorLoop-1-3] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was 192.168.1.254:6379 2019-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:6379 2019-10-06 21:51:38.041 INFO 128256 --- [xecutorLoop-1-7] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was 192.168.1.254:6379 2019-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:6379 2019-10-06 21:51:44.241 INFO 128256 --- [xecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was 192.168.1.254:6379 2019-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 denied 2019-10-05T19:05:51.961959923Z 1:S 05 Oct 2019 19:05:51.961 * Connecting to MASTER 192.168.1.254:6380 2019-10-05T19:05:51.961989715Z 1:S 05 Oct 2019 19:05:51.961 * MASTER <-> REPLICA sync started 2019-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:133911 2019-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 master 2019-10-05T19:05:52.064114578Z 1:S 05 Oct 2019 19:05:52.062 * MASTER <-> REPLICA sync: Flushing old data 2019-10-05T19:05:52.064124761Z 1:S 05 Oct 2019 19:05:52.062 * MASTER <-> REPLICA sync: Loading DB in memory 2019-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 mymaster 1) 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项目”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。