redis哨兵模式的使用
步骤 1:搭建 Redis 哨兵集群环境(前提条件)
操作:
- 部署 1 个主节点(Master)
- 部署至少 2 个从节点(Slave),并配置为复制主节点数据
- 部署至少 3 个哨兵节点(Sentinel),配置监控主节点
解释:
- 哨兵模式的核心是通过哨兵节点监控 Redis 主从集群
- 3 个哨兵是为了满足分布式系统中的 "多数原则",避免脑裂问题
- 哨兵节点之间会相互通信,共同判断主节点是否故障并进行故障转移
- 从节点的作用是在主节点故障时作为候选节点被选举为新主节点
步骤 2:在 Java 项目中引入 Redis 客户端依赖
操作:
在项目的pom.xml
文件中添加 Jedis 依赖:
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.7.0</version>
</dependency>
解释:
- Jedis 是 Redis 官方推荐的 Java 客户端之一,支持哨兵模式
- 选择合适的版本很重要,需与 Redis 服务器版本兼容(一般新版本兼容旧版本)
- 该依赖会自动引入 Jedis 所需的所有核心类和方法
步骤 3:配置哨兵节点信息
操作:
// 创建哨兵节点集合
Set<String> sentinels = new HashSet<>();
sentinels.add("192.168.1.100:26379"); // 哨兵1地址:端口
sentinels.add("192.168.1.101:26379"); // 哨兵2地址:端口
sentinels.add("192.168.1.102:26379"); // 哨兵3地址:端口String masterName = "mymaster"; // 主节点名称
解释:
- 哨兵节点集合包含所有哨兵的地址和端口,客户端通过这些哨兵获取主节点信息
masterName
是主节点的逻辑名称,必须与哨兵配置文件中sentinel monitor
指令指定的名称一致- 客户端不需要直接配置主从节点地址,而是通过哨兵动态发现
步骤 4:配置连接池参数
操作:
String password = "redisPassword"; // Redis访问密码
int timeout = 3000; // 连接超时时间(毫秒)
int maxTotal = 100; // 最大连接数
int maxIdle = 20; // 最大空闲连接数
int minIdle = 5; // 最小空闲连接数
解释:
password
:如果 Redis 服务器配置了密码验证,需要填写对应密码timeout
:设置连接超时时间,避免长时间等待无响应的连接- 连接池参数用于控制连接的创建和管理:
maxTotal
:限制最大并发连接数,防止连接过多导致 Redis 服务器压力过大maxIdle
:保持适当的空闲连接,减少频繁创建连接的开销minIdle
:确保有基础数量的空闲连接可用,提高响应速度
步骤 5:创建 JedisSentinelPool 实例
操作:
JedisSentinelPool sentinelPool = new JedisSentinelPool(masterName, sentinels,password,timeout,maxTotal,maxIdle,minIdle
);
解释:
JedisSentinelPool
是 Jedis 提供的用于支持哨兵模式的连接池类- 它内部会通过哨兵节点获取当前的主节点信息
- 当主节点发生故障并完成故障转移后,它会自动发现新的主节点
- 连接池会管理所有 Jedis 连接,负责连接的创建、复用和回收
步骤 6:从连接池获取 Jedis 实例并执行操作
操作:
Jedis jedis = null;
try {// 从连接池获取Jedis实例(自动连接到当前主节点)jedis = sentinelPool.getResource();// 执行Redis操作jedis.set("testKey", "Hello Redis Sentinel");String value = jedis.get("testKey");System.out.println("获取值:" + value);
} catch (Exception e) {e.printStackTrace();
} finally {// 释放资源if (jedis != null) {jedis.close();}
}
解释:
sentinelPool.getResource()
会从连接池获取一个可用的 Jedis 实例,该实例已连接到当前的主节点- 通过 Jedis 实例可以执行各种 Redis 命令(如 set、get 等)
jedis.close()
并不是真正关闭连接,而是将连接归还给连接池,供其他请求复用- 使用 try-finally 结构确保连接一定会被归还,避免连接泄漏
步骤 7:应用关闭时关闭连接池
操作:
// 在应用程序关闭时调用
sentinelPool.close();
解释:
- 当应用程序停止时,需要关闭连接池以释放所有资源
- 在 Spring 等框架中,可以通过
@PreDestroy
注解或实现DisposableBean
接口来自动执行关闭操作 - 连接池关闭后,所有内部管理的连接都会被正确关闭
步骤 8:(可选)整合 Spring 框架
操作:
创建配置类管理JedisSentinelPool
:
@Configuration
public class RedisConfig {@Value("${redis.sentinel.master}")private String masterName;@Value("${redis.sentinel.nodes}")private String sentinelNodes;@Bean(destroyMethod = "close")public JedisSentinelPool jedisSentinelPool() {Set<String> sentinels = new HashSet<>(Arrays.asList(sentinelNodes.split(",")));JedisPoolConfig poolConfig = new JedisPoolConfig();// 配置连接池参数...return new JedisSentinelPool(masterName, sentinels, poolConfig);}
}
解释:
- 在 Spring 项目中,通过配置类将
JedisSentinelPool
声明为 Bean,由 Spring 容器管理其生命周期 - 使用
@Value
注解从配置文件读取参数,便于配置管理和环境切换 destroyMethod = "close"
确保 Spring 容器关闭时自动调用连接池的 close () 方法
通过以上步骤,Java 项目就能正确使用 Redis 哨兵模式,实现对 Redis 集群的高可用访问。当主节点发生故障时,整个过程对应用程序是透明的,无需人工干预即可自动切换到新的主节点。