项目地址:

一、Redis哨兵模式连接原理

(一)哨兵模式核心原理

  1. 监控机制:哨兵节点定期检查主节点和从节点的健康状态
  2. 故障检测:当主节点不可达时,哨兵集群通过投票机制确认故障
  3. 自动故障转移
    • 选举新的主节点(从从节点中选择)
    • 更新其他从节点配置指向新主节点
    • 通知客户端新的主节点地址
  4. 配置中心:客户端从哨兵获取当前主节点信息

(二)Spring Boot连接流程

1
2
3
4
5
6
7
8
9
graph TD
A[Spring Boot应用] --> B[连接哨兵集群]
B --> C[查询当前主节点]
C --> D[建立Redis连接]
D --> E[执行读写操作]
E --> F{主节点故障?}
F -- 是 --> G[哨兵通知新主节点]
G --> C
F -- 否 --> E

二、Spring Boot详细配置步骤

(一)添加依赖

1
2
3
4
5
6
7
8
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId> <!-- 推荐使用Lettuce客户端 -->
</dependency>

(二)配置文件(application.yml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
spring:
redis:
password: your_redis_password # 如果有密码
sentinel:
master: mymaster # 哨兵配置的主节点名称
nodes: # 哨兵节点列表
- 192.168.1.10:26379
- 192.168.1.11:26379
- 192.168.1.12:26379
lettuce:
pool: # 连接池配置
max-active: 8
max-idle: 8
min-idle: 2
max-wait: -1ms

(三)高级配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
@Configuration
public class RedisConfig {

@Bean
public RedisConnectionFactory redisConnectionFactory(
@Value("${spring.redis.sentinel.nodes}") List<String> nodes,
@Value("${spring.redis.sentinel.master}") String master,
@Value("${spring.redis.password}") String password) {

RedisSentinelConfiguration config = new RedisSentinelConfiguration()
.master(master)
.sentinelPassword(password); // 哨兵密码(如果需要)

// 添加哨兵节点
for (String node : nodes) {
String[] parts = node.split(":");
config.sentinel(parts[0], Integer.parseInt(parts[1]));
}

// 配置连接池
LettucePoolingClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
.poolConfig(getPoolConfig())
.build();

return new LettuceConnectionFactory(config, clientConfig);
}

private GenericObjectPoolConfig<?> getPoolConfig() {
GenericObjectPoolConfig<?> poolConfig = new GenericObjectPoolConfig<>();
poolConfig.setMaxTotal(8);
poolConfig.setMaxIdle(8);
poolConfig.setMinIdle(2);
poolConfig.setMaxWait(Duration.ofSeconds(30));
return poolConfig;
}

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);

// 使用JSON序列化
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

return template;
}
}

(四)故障转移处理最佳实践

  1. 重试机制

    1
    2
    3
    4
    5
    6
    7
    8
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
    // ... 其他配置

    // 启用事务支持
    template.setEnableTransactionSupport(true);
    return template;
    }
  2. 哨兵连接健康检查

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Component
    public class SentinelHealthCheck implements ApplicationRunner {

    @Autowired
    private RedisConnectionFactory connectionFactory;

    @Override
    public void run(ApplicationArguments args) {
    try (RedisConnection connection = connectionFactory.getConnection()) {
    connection.ping(); // 测试连接
    } catch (Exception e) {
    throw new IllegalStateException("Redis哨兵连接失败", e);
    }
    }
    }

三、关键注意事项

  1. 网络配置

    • 确保Spring Boot服务器能访问所有哨兵节点
    • 防火墙开放哨兵端口(默认26379)和Redis端口(默认6379)
  2. 哨兵配置一致性

    1
    2
    # 检查哨兵配置
    redis-cli -h 192.168.1.10 -p 26379 sentinel master mymaster
  3. 连接验证

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @SpringBootTest
    class RedisSentinelTest {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Test
    void testConnection() {
    redisTemplate.opsForValue().set("test_key", "value");
    assertEquals("value", redisTemplate.opsForValue().get("test_key"));
    }
    }
  4. 故障转移模拟测试

    • 手动停止主节点:redis-cli -p 6379 DEBUG SEGFAULT
    • 观察日志:哨兵选举新主节点的过程
    • 验证应用自动重连:检查Spring Boot日志是否有连接错误和恢复信息

四、生产环境建议

  1. 哨兵部署

    • 至少3个哨兵节点(满足多数投票)
    • 部署在不同物理服务器上
  2. 客户端配置优化

    1
    2
    3
    4
    5
    6
    7
    8
    spring:
    redis:
    lettuce:
    shutdown-timeout: 200ms
    cluster:
    refresh:
    adaptive: true # 动态刷新拓扑视图
    period: 15s # 刷新间隔
  3. 监控指标

    1
    2
    3
    4
    5
    // 添加监控
    @Bean
    public LettuceMetricsCollector metricsCollector() {
    return new LettuceMetricsCollector();
    }
    • 通过Micrometer导出指标到Prometheus/Grafana
  4. 安全加固

    1
    2
    3
    4
    5
    spring:
    redis:
    sentinel:
    password: sentinel_password # 哨兵独立密码
    ssl: true # 启用TLS加密

通过以上配置,Spring Boot应用可以稳定连接Redis哨兵集群,自动处理故障转移,实现高可用数据访问。实际部署时需根据业务负载调整连接池参数和超时设置。