前置redis单例基本搭建参考博客:redis基础服务搭建

redis集群主要修改配置:主从复制
1. 主机配置
复制一份redis.conf成redis-6379.conf。修改配置:

	```
	#演示方便,开放ip连接
	bind 0.0.0.0
	#后台运行
	daemonize yes
	#pid文件
	pidfile /var/run/redis_6379.pid
	#日志文件
	logfile "6379.log"
	```



2. 从机配置
	复制一份redis.conf成redis-6380.conf。修改配置:
	```
		#设置所有ip都可访问
		bind 0.0.0.0
		#端口
		port 6380
		#是否后台方式启动
		daemonize yes
		#每个服务一个pid,存放地址
		pidfile /var/run/redis_6380.pid
		#日志文件设置
		logfile "6380.log"
		#slaveof表示作为从库的配置,设置主库地址端口(主写从复制读)
		slaveof 127.0.0.1 6379
		#主库密码(没有设置不用写)
		requirepass 654321
		#从库只能读不能写(主从配置)
		slave-read-only yes
		#单台服务器做集群需要修改,名称不能一致
		dbfilename dump-6379.rdb
	```
3. 启动服务(进入redis根目录)执行命令:我这里文件名为redis-6379.conf、redis-6380.conf、redis-6381.conf存放在根目录
	```
	[root@VM_235_253_centos redis-4.0.9]# ./src/redis-server redis-6379.conf
	[root@VM_235_253_centos redis-4.0.9]# ./src/redis-server redis-6380.conf
	[root@VM_235_253_centos redis-4.0.9]# ./src/redis-server redis-6381.conf
	```

4. 查看redis的信息  查看redis的信息
	主库信息
	```
	[root@VM_235_253_centos redis-4.0.9]# ./src/redis-cli -p 6379 -a 654321 info replication# Replication
	```
	其中-p 6379表示指定端口
	-a 654321表示指定端口的密码,没有可以不加此参数
	replication表示主从的信息
	```
	# Replication
	#主库
	role:master
	#2从库
	connected_slaves:2
	slave0:ip=119.29.76.169,port=6381,state=online,offset=207209,lag=1
	slave1:ip=119.29.76.169,port=6380,state=online,offset=207209,lag=1
	master_replid:59f3ac708c36d91887f61d92d48a0ea8ac397fe5
	master_replid2:0000000000000000000000000000000000000000
	master_repl_offset:207209
	second_repl_offset:-1
	repl_backlog_active:1
	repl_backlog_size:1048576
	repl_backlog_first_byte_offset:1
	repl_backlog_histlen:207209
	```
	查看6380从库信息
	```
	[root@VM_235_253_centos redis-4.0.9]# ./src/redis-cli -p 6380 -a 654321 info replication
	# Replication
	#从库
	role:slave
	#主库地址
	master_host:119.29.76.169
	#主库端口
	master_port:6379
	master_link_status:up
	master_last_io_seconds_ago:1
	master_sync_in_progress:0
	slave_repl_offset:233021
	slave_priority:100
	slave_read_only:1
	connected_slaves:0
	master_replid:59f3ac708c36d91887f61d92d48a0ea8ac397fe5
	master_replid2:0000000000000000000000000000000000000000
	master_repl_offset:233021
	second_repl_offset:-1
	repl_backlog_active:1
	repl_backlog_size:1048576
	repl_backlog_first_byte_offset:1
	repl_backlog_histlen:233021
	```

配置哨兵:

  1. 复制根目录下sentinel.conf配置文件
  2. 修改主要配置
			#设置哨兵服务端口
			port 26379
			#设置后台启动
			daemonize yes
			#文件地址存放地址
			dir /opt/redis-4.0.11/data
			#Sentinel去监视一个名为mymaster 的主redis实例,这个主实例的IP地址为本机地址127.0.0.1,端口号为6379,而将这个主实例判断为失效至少需要2个 Sentinel进程的同意,只要同意Sentinel的数量不达标,自动failover就不会执行
			sentinel monitor mymaster 127.0.0.1  6379 2
			#设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
			# sentinel auth-pass <master-name> <password>
			#指定了Sentinel认为Redis实例已经失效所需的毫秒数。当实例超过该时间没有返回PING,或者直接返回错误,那么Sentinel将这个实例标记为主观下线。只有一个 Sentinel进程将实例标记为主观下线并不一定会引起实例的自动故障迁移:只有在足够数量的Sentinel都将一个实例标记为主观下线之后,实例才会被标记为客观下线,这时自动故障迁移才会执行
			sentinel down-after-milliseconds mymaster 30000
			#指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长
			sentinel parallel-syncs mymaster 1
			#如果在该时间(ms)内未能完成failover操作,则认为该failover失败
			sentinel failover-timeout mymaster 180000
			#指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,但是很常用
			# sentinel notification-script <master-name> <script-path>
  1. 启动哨兵:两个配置文件在根目录分别为sentinel-26379.conf、sentinel-26380.conf

     	```
     	[root@VM_235_253_centos redis-4.0.9]# ./src/redis-sentinel sentinel-26379.conf
     	[root@VM_235_253_centos redis-4.0.9]# ./src/redis-sentinel sentinel-26380.conf
     	```
    

Spring boot 配置:

  1. 引入redis包
 <dependency>
	            <groupId>org.springframework.boot</groupId>
	            <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>
  1. application.yml Spring配置
spring:
  redis:
    #有密码则需要设置
    password: 654321
	#这里只需要配置哨兵即可
    sentinel:
      master: mymaster
      nodes: 119.xx.xx.xxx:26379,119.xx.xx.xxx:26380
  1. redis序列化
/**
 * redis序列化配置
 * @author 50238
 */
@Configuration
public class RedisConfig {
    /**
     * redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类
     *
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 使用Jackson2JsonRedisSerialize 替换默认序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        // 设置value的序列化规则和 key的序列化规则
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

}

最后测试代码:

@RunWith(SpringRunner.class)
@SpringBootTest
public class BlogApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void contextLoads() {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("open", "String");
        System.out.println(valueOperations.get("open"));
    }
}

使用redis工具也可以看到确实主从做了复制,复制信息等可以从redis日志中也可以看到。
Redis哨兵-实现Redis高可用

10-07 18:28