Sentinel
sentinel(哨兵) 是一种redis的解决方案,可以由多个Sentinel实例组成的Sentinel系统可以监视多个主服务器,以及这些主服务器之下的从服务器,同时如果主服务器下线之后,就会通过推举将从服务器升级为主服务器。
这里不推荐在一个机器上使用docker来搭建一个redis Sentinel系统,只要是考虑到使用docker之后,之后集成到spring boot之后,sentinel得到了一个内网地址,spring boot无法连接
redis 主从
- 修改主配置文件
port 6380
daemonize yes
logfile "6379.log"
# bind 127.0.0.1 ## 保证其他服务器可以访问
requirepass admin ## 设置密码
- 启动主Redis
redis-server redis.conf
- 修改从服务器配置文件
port 6381
daemonize yes
logfile "6379.log"
# bind 127.0.0.1 ## 保证其他服务器可以访问
slaveof 127.0.0.1 6380
# 如果 master 节点有设置密码
masterauth admin
- 启动从服务器
redis-server redis.conf
- 这时候在 主服务器插入一个数据,可以在从服务器中查询到
Redis Sentinel
在redis 主从的基础上在添加一个从服务器,只需要修改端口就可以
创建sentinel服务
-
创建一个 sentinel.conf 文件,修改文件
port 26379 sentinel myid 24eb7398b6a557496d341d1e51248b307e83b307 sentinel monitor mymaster 127.0.0.1 6379 2 # 主服务器ip sentinel down-after-milliseconds mymaster 15000 sentinel failover-timeout mymaster 80000 sentinel auth-pass mymaster admin # 主服务器密码 logfile "sentinel.log" # log文件地址 bind 0.0.0.0 # 关联地址 保证其他服务器可以访问 daemonize yes
-
启动服务
redis-sentinel sentinel.conf
-
再创建两个相同的两个sentinel 服务
-
查看日志可以看到一个主服务器,两个从服务器
Spring boot 集成 redis Sentinel
pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</exclusion>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
yml文件配置
spring:
redis:
password: admin
jedis:
pool:
#最大连接数
max-active: 1024
#最大阻塞等待时间(负数表示没限制)
max-wait: 200
#最大空闲
max-idle: 300
#最小空闲
min-idle: 10
sentinel:
master: mymaster
nodes: 127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
自定义配置
@Configuration
@EnableAutoConfiguration
public class RedisConfig {
private static Logger logger = LoggerFactory.getLogger(RedisConfig.class);
@Value("#{'${spring.redis.sentinel.nodes}'.split(',')}")
private List<String> nodes;
@Bean(name = "jedisPoolConfig")
@ConfigurationProperties(prefix="spring.redis.jedis.pool")
public JedisPoolConfig getRedisConfig(){
JedisPoolConfig config = new JedisPoolConfig();
return config;
}
@Bean(name = "sentinelConfiguration")
public RedisSentinelConfiguration sentinelConfiguration(){
RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
//配置matser的名称
redisSentinelConfiguration.master("mymaster");
redisSentinelConfiguration.setPassword("admin");
//配置redis的哨兵sentinel
Set<RedisNode> redisNodeSet = new HashSet<>();
nodes.forEach(x->{
redisNodeSet.add(new RedisNode(x.split(":")[0],Integer.parseInt(x.split(":")[1])));
});
logger.info("redisNodeSet -->"+redisNodeSet);
redisSentinelConfiguration.setSentinels(redisNodeSet);
return redisSentinelConfiguration;
}
@Bean(name = "jedisConnectionFactory")
public JedisConnectionFactory jedisConnectionFactory(@Qualifier("jedisPoolConfig")JedisPoolConfig jedisPoolConfig,@Qualifier("sentinelConfiguration") RedisSentinelConfiguration sentinelConfig) {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(sentinelConfig,jedisPoolConfig);
return jedisConnectionFactory;
}
@Bean(name = "redisTemplate")
@Primary
@ConditionalOnMissingBean
public RedisTemplate redisTemplate(@Qualifier("jedisConnectionFactory") RedisConnectionFactory factory) {
RedisTemplate redisTemplate = new RedisTemplate<>();
RedisSerializer stringSerializer = new StringRedisSerializer();
redisTemplate.setConnectionFactory(factory);
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setValueSerializer(stringSerializer);
redisTemplate.setHashKeySerializer(stringSerializer);
redisTemplate.setHashValueSerializer(stringSerializer);
return redisTemplate;
}
}
测试代码
@Api(tags = "测试")
@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private JedisPoolConfig jedisPoolConfig;
@ApiOperation(value = "测试redis")
@GetMapping("/redis")
@ResponseBody
public BaseResult testData(@RequestParam String body) {
int maxIdle = jedisPoolConfig.getMaxIdle();
redisTemplate.opsForValue().set("k1112",body);
if(redisTemplate.hasKey("k1112")){
return new BaseResult<>(200,"成功",redisTemplate.opsForValue().get("k1112"));
}
return new BaseResult<>(200,"成功","failure");
}
}