redis 哨兵(主从)

主配置文件内容

port 8001
appendonly no
bind 192.168.59.129
requirepass "123456"
maxmemory 200mb
masterauth "123456"

另外两从配置文件

port 8002
appendonly no
bind 192.168.59.129
requirepass "123456"
maxmemory 200mb
masterauth "123456"
slaveof 192.168.59.129 8001
port 8003
appendonly no
bind 192.168.59.129
requirepass "123456"
maxmemory 200mb
masterauth "123456"

slaveof 192.168.59.129 8001

写一个启动脚本和停止脚本

start.sh

/home/redis-4.0.10/src/redis-server /home/redis-sentinel/redis8001.conf &
/home/redis-4.0.10/src/redis-server /home/redis-sentinel/redis8002.conf &
/home/redis-4.0.10/src/redis-server /home/redis-sentinel/redis8003.conf &

stop.sh

ps -ef | grep redis | grep -v grep | cut -c 9-15 | xargs kill -9

停止脚本的功能为,查询所有redis的pid,然后kill、如果服务器上面有不需要停止的redis不能这样用,这个会杀掉所有redis进程

执行start.sh 输出内容如下:

查看目前redis的启动状态 

启动完成之后、查询8001 8002 8003的状态

从信息看到8001为主redis 8002 8003为从redis

接下来配置哨兵

哨兵配置文件

sentinel monitor mymaster 192.168.59.129 8001 1
bind 192.168.59.129  
port 26879
sentinel failover-timeout mymaster 6000
sentinel auth-pass mymaster 123456

配置简单解析:第一行设置监控的实例名“mymaster” ip port + quorum , quorum为投票数量,当哨兵为集群的时候(比如哨兵为5个,那么设置值为3,如果哨兵为3个,那么设置值为2 ) 比如哈:有5个哨兵集群,并且quenum = 3,那么当5个哨兵中的3个哨兵都连接不上主redis的时候(并且时间达到了第四行配置的毫秒),他们3个就认为主redis挂了,然后就会对从redis进行选举,选举一个做主redis、当之前挂掉的主redis重新起来之后,就会降级为新的主redis的从redis.(我这里测试就是用了一个哨兵,所以quorum值也设置为1了)

最后一行配置 :因为主从redis都配置了密码所以,哨兵需要授权才能连接上主redis,这个设置为主redis的授权密码:

sentinel auth-pass mymaster 123456

接下来启动哨兵

/home/redis-4.0.10/src/redis-sentinel ./sentinel-single.conf &

从启动log中,能看到目前监控的主redis以及quorum值,当前的从redis等信息、(另外哨兵是不需要设置监控的从redis的,哨兵连接上主redis之后,会自动获取到从redis的信息)

接下来手动让主redis宕掉,模拟生产环境的情况

哨兵监测到8001已经宕掉了,然后选取了8003作为新的主redis

查看验证一下,是否现在8003为主reids

# Replication
role:master
connected_slaves:1
slave0:ip=192.168.59.129,port=8002,state=online,offset=158245,lag=1
master_replid:16cb18086466e4e40dc91e7dcb8f39b29712a9cc
master_replid2:e0d50a2843d0af2cd4304e4c415eb1131685fdbb
master_repl_offset:158245
second_repl_offset:149189
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:158245

查看8003目前是猪redis,从redis为8002(8001已经宕掉了),下面再讲8001启动,再查看信息

8003(主redis)信息如下

哨兵的日志

最后贴上 java 端 (spring boot)调用哨兵redis的代码

配置文件:SentinelRedisConfigurer.java


@Configuration
public class SentinelRedisConfigurer {

	@Bean(value = "sentinelConnnectionFactory")
	public RedisConnectionFactory sentinelConnnectionFactory() {
		Set<String> clusterNodes = new HashSet<>();
		clusterNodes.add("192.168.59.129:26879"); //指定哨兵的ip:port

		RedisSentinelConfiguration configuration = new RedisSentinelConfiguration("mymaster", clusterNodes);//设置住redis名称(就是哨兵配置里面配置的名称)
		configuration.setPassword(RedisPassword.of("123456")); //设置授权密码
		
		return new LettuceConnectionFactory(configuration);
	}
	@Bean(value="sentinelTemplate")
	public RedisTemplate<String, String> sentinelTemplate(@Qualifier("sentinelConnnectionFactory") RedisConnectionFactory factory){
		StringRedisTemplate redisTemplate = new StringRedisTemplate();
		redisTemplate.setConnectionFactory(factory);
		Jackson2JsonRedisSerializer<Object> jsonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
		
		ObjectMapper om = new ObjectMapper();
		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
		jsonSerializer.setObjectMapper(om);
		
		redisTemplate.setValueSerializer(jsonSerializer);
		return redisTemplate;
	}
}

测试代码 TestSentinel.java

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SentinelRedisConfigurer.class)
public class TestSentinel {

	@Resource(name = "sentinelTemplate")
	private RedisTemplate<String, String> template1;
	@Resource(name = "sentinelConnnectionFactory")
	private RedisConnectionFactory sentinelConnnectionFactory;
	
	private String key = "hello8";
	@Test
	public void test1() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(true) {
					try {
						Thread.sleep(1000);
						template1.opsForValue().set(key, "world");
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
				while(true) {
					try {
						Thread.sleep(1000);
						System.out.println(template1.opsForValue().get(key));
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		});
		t1.start();
		try {
			t1.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

启动之后、输入日志:

当停止主redis之后会在一段时间内会输出错误日志(这段时间内,哨兵还没有选举出主redis所以会输出错误日志),然后又可以正常访问了(哨兵已经选举出新的主redis)

key:hello874, value: world74
key:hello875, value: world75
key:hello876, value: world76
key:hello877, value: world77
key:hello878, value: world78
key:hello879, value: world79
key:hello880, value: world80
key:hello881, value: world81
key:hello882, value: world82
key:hello883, value: world83
key:hello884, value: world84
key:hello885, value: world85
2018-07-24 11:17:27.421  INFO 15500 --- [xecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was /192.168.59.129:8003
2018-07-24 11:17:28.430  WARN 15500 --- [ioEventLoop-4-4] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /192.168.59.129:8003
2018-07-24 11:17:32.919  INFO 15500 --- [xecutorLoop-1-7] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.59.129:8003
2018-07-24 11:17:33.936  WARN 15500 --- [ioEventLoop-4-6] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /192.168.59.129:8003
2018-07-24 11:17:38.118  INFO 15500 --- [xecutorLoop-1-3] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.59.129:8003
2018-07-24 11:17:39.129  WARN 15500 --- [ioEventLoop-4-6] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /192.168.59.129:8003
2018-07-24 11:17:43.318  INFO 15500 --- [xecutorLoop-1-5] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.59.129:8003
2018-07-24 11:17:44.328  WARN 15500 --- [ioEventLoop-4-2] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /192.168.59.129:8003
2018-07-24 11:17:48.518  INFO 15500 --- [xecutorLoop-1-6] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.59.129:8003
2018-07-24 11:17:49.534  WARN 15500 --- [ioEventLoop-4-4] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /192.168.59.129:8003
2018-07-24 11:17:57.817  INFO 15500 --- [xecutorLoop-1-7] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.59.129:8003
2018-07-24 11:17:58.828  WARN 15500 --- [ioEventLoop-4-6] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /192.168.59.129:8003
2018-07-24 11:18:15.218  INFO 15500 --- [xecutorLoop-1-8] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 192.168.59.129:8003
2018-07-24 11:18:15.238  INFO 15500 --- [ioEventLoop-4-8] i.l.core.protocol.ReconnectionHandler    : Reconnected to 192.168.59.129:8001
key:hello886, value: world86
key:hello887, value: world87
key:hello888, value: world88
key:hello889, value: world89
key:hello890, value: world90
key:hello891, value: world91
key:hello891, value: world91
key:hello892, value: world93
key:hello893, value: world93
key:hello894, value: world94
key:hello895, value: world95
key:hello896, value: world96
key:hello897, value: world97
key:hello898, value: world98

猜你喜欢

转载自blog.csdn.net/vipagain/article/details/81168508