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

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

一,在主机上搭建redis

整体redis和哨兵架构均为3节点(1主2从)

默认容器启动为bridge模式,这样哨兵取到的主节点ip为容器内网ip,客户端无法访问容器内网,故需要使用宿主机网络模式编排(network_mode:“host”)

宿主机外网IP,192.168.1.254

1,(redis编排文件)master-slave/docker-compose.yml

version: "3"
services:
  master:
    image: redis:latest
    container_name: redis-master
    command: redis-server --requirepass 123456 --port 6379
    ports:
    - "6379"
    network_mode: "host"
  slave1:
    image: redis:latest
    container_name: redis-slave-1
    command: redis-server --port 6380 --slaveof 192.168.1.254 6379 --requirepass 123456 --masterauth 123456
    depends_on:
    - master
    ports:
    - "6380"
    network_mode: "host"
  slave2:
    image: redis:latest
    container_name: redis-slave-2
    command: redis-server --port 6381 --slaveof 192.168.1.254 6379 --requirepass 123456 --masterauth 123456
    depends_on:
    - master
    ports:
    - "6381"
    network_mode: "host"

在当前目录下使用命令启动:docker-compose up -d

共三台redis,其中master(6379),slave(6380,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"
    volumes:
    - "/root/redis/sentinel1.conf:/usr/local/etc/redis/sentinel.conf"
    network_mode: "host"
  sentinel2:
    image: redis:latest
    container_name: redis-sentinel-2
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    ports:
    - "26380"
    volumes:
    - "/root/redis/sentinel2.conf:/usr/local/etc/redis/sentinel.conf"
    network_mode: "host"
  sentinel3:
    image: redis:latest
    container_name: redis-sentinel-3
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    ports:
    - "26381"
    volumes:
    - "/root/redis/sentinel3.conf:/usr/local/etc/redis/sentinel.conf"
    network_mode: "host"

在当前目录下使用命令启动:docker-compose up -d

共三台哨兵,端口分别为26379, 26380, 26381

其中三个哨兵配置文件内容除了端口不同,其他内容均相同

/root/redis/sentinel1.conf

port 26379 # 其他两节点分别为26380, 26381
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

#第三行表示Redis监控一个叫做mymaster的运行在192.168.1.254:6379的master,投票达到2则表示master以及挂掉了。  
#第四行设置主节点的认证密码  
#第五行表示在一段时间范围内sentinel向master发送的心跳PING没有回复则认为master不可用了。 
#第六行的parallel-syncs表示设置在故障转移之后,同时可以重新配置使用新master的slave的数量。数字越低,更多的时间将会用故障转移完成,但是如果slaves配置为服务旧数据,你可能不希望所有的slave同时重新同步master。因为主从复制对于slave是非阻塞的,当停止从master加载批量数据时有一个片刻延迟。通过设置选项为1,确信每次只有一个slave是不可到达的。
#第七行表示10秒内mymaster还没活过来,则认为master宕机了。

这是启动后的容器列表:

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

二,整合springboot项目

1,引入依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>

2,配置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,使用RedisTemplate操作redis

	@Autowired
	RedisTemplate<String, String> redisTemplate;
	
	@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);
	}

这里使用3个线程模拟并发写入redis,在写的过程中,停掉master,查看控制台输出日志

2019-10-06 18:52:51.949  INFO 128972 --- [pool-1-thread-1] io.lettuce.core.EpollProvider            : Starting without optional epoll library
2019-10-06 18:52:51.951  INFO 128972 --- [pool-1-thread-1] io.lettuce.core.KqueueProvider           : Starting without optional kqueue library
2019-10-06 18:53:55.979  INFO 128972 --- [xecutorLoop-1-8] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was /192.168.1.254:6379
2019-10-06 18:53:57.992  WARN 128972 --- [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 18:54:02.277  INFO 128972 --- [xecutorLoop-1-7] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.1.254:6379
2019-10-06 18:54:04.286  WARN 128972 --- [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 18:54:08.577  INFO 128972 --- [xecutorLoop-1-4] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.1.254:6379
2019-10-06 18:54:10.587  WARN 128972 --- [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 18:54:15.678  INFO 128972 --- [xecutorLoop-1-3] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.1.254:6379
2019-10-06 18:54:17.687  WARN 128972 --- [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 18:54:22.877  INFO 128972 --- [xecutorLoop-1-7] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.1.254:6379
2019-10-06 18:54:24.885  WARN 128972 --- [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 18:54:29.078  INFO 128972 --- [xecutorLoop-1-1] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.1.254:6379
2019-10-06 18:54:29.085  INFO 128972 --- [ioEventLoop-4-4] i.l.core.protocol.ReconnectionHandler    : Reconnected to 192.168.1.254:6380

可以看到在18:53:55.979,已经连不上主节点了(6379),之后一直在重连,直到18:54:29.085才连上,但是这时候的节点已经变了(6380),证明哨兵已经可以自动切换主节点了。

再看redis中的数据,一共3000条数据,一条没丢,证明即使在切换主备的过程中,数据也不会丢

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

接着启动刚停掉的redis-master节点,发现已经启动不了了,报错

2019-10-05T16:00:57.899358510Z 1:S 05 Oct 2019 16:00:57.897 * Connecting to MASTER 192.168.1.254:6380
2019-10-05T16:00:57.899381586Z 1:S 05 Oct 2019 16:00:57.897 * MASTER <-> REPLICA sync started
2019-10-05T16:00:57.899385377Z 1:S 05 Oct 2019 16:00:57.897 * Non blocking connect for SYNC fired the event.
2019-10-05T16:00:57.899388194Z 1:S 05 Oct 2019 16:00:57.898 * Master replied to PING, replication can continue...
2019-10-05T16:00:57.899391119Z 1:S 05 Oct 2019 16:00:57.898 * (Non critical) Master does not understand REPLCONF listening-port: -NOAUTH Authentication required.
2019-10-05T16:00:57.899401303Z 1:S 05 Oct 2019 16:00:57.898 * (Non critical) Master does not understand REPLCONF capa: -NOAUTH Authentication required.
2019-10-05T16:00:57.899404228Z 1:S 05 Oct 2019 16:00:57.898 * Partial resynchronization not possible (no cached master)
2019-10-05T16:00:57.899406828Z 1:S 05 Oct 2019 16:00:57.898 # Unexpected reply to PSYNC from master: -NOAUTH Authentication required.
2019-10-05T16:00:57.899409536Z 1:S 05 Oct 2019 16:00:57.898 * Retrying with SYNC...
2019-10-05T16:00:57.899412136Z 1:S 05 Oct 2019 16:00:57.899 # MASTER aborted replication with an error: NOAUTH Authentication required.

这时候已经作为从节点连接新主节点了,但是授权认证失败,因为之前主节点根本就没有配置slaveof,这里我以为哨兵会自动加上slaveof配置,但是没有,难道是没有使用配置文件的缘故?

已经找到原因,并且在这篇中完全实现了

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