連接池構建與核心配置
private static JedisPool jedisPool;
public static JedisPool getPool() {
if (jedisPool == null) {
synchronized (JedisUtil.class) {
if (jedisPool == null) {
JedisPoolConfig cfg = new JedisPoolConfig();
cfg.setMaxTotal(1024); // 最大連接數
cfg.setMaxIdle(50); // 最大空閒連接
cfg.setMinIdle(10); // 最小空閒連接
cfg.setMaxWaitMillis(5000); // 獲取連接超時 5s
cfg.setTestOnBorrow(true); // 借用時驗證 (PING)
cfg.setTestOnReturn(false); // 歸還時不驗證 (性能)
cfg.setTestWhileIdle(true); // 空閒檢測
cfg.setTimeBetweenEvictionRunsMillis(30000); // 檢測間隔 30s
cfg.setMinEvictableIdleTimeMillis(60000); // 空閒 60s 可被驅逐
jedisPool = new JedisPool(cfg, "127.0.0.1", 6379, 3000, null, 0);
}
}
}
return jedisPool;
}
// 正確歸還 (Jedis 3.x+ 實現了 AutoCloseable)
public static void close(Jedis jedis) {
if (jedis != null) jedis.close(); // 實際歸還池中
}
模板封裝:消除重複 try-finally (參考 JdbcTemplate)
@FunctionalInterface
public interface RedisCallback {
T execute(Jedis jedis);
}
public class RedisTemplate {
private final JedisPool pool;
public RedisTemplate(JedisPool pool) { this.pool = pool; }
public T execute(RedisCallback callback) {
Jedis jedis = pool.getResource();
try {
return callback.execute(jedis);
} finally {
jedis.close(); // 異常也歸還
}
}
}
// 使用
RedisTemplate rt = new RedisTemplate(getPool());
String val = rt.execute(jedis -> jedis.get("key"));
rt.execute(jedis -> {
jedis.lpush("queue", "task1");
return null;
});
五大數據結構常用操作速查
String (字符串)
jedis.set("name", "Alice");
jedis.append("name", " Smith"); // 拼接
jedis.incr("counter"); // 原子增長
jedis.mset("k1","v1","k2","v2"); // 批量設置
List (列表)
jedis.lpush("tasks", "A", "B"); // 左入
jedis.rpush("tasks", "C"); // 右入
List all = jedis.lrange("tasks", 0, -1); // 全取
jedis.ltrim("tasks", 0, 99); // 保留前 100
jedis.lpop("tasks"); // 左出 (隊列)
Hash (散列)
jedis.hset("user:1", "name", "Bob");
jedis.hset("user:1", "age", "25");
Map map = jedis.hgetAll("user:1");
jedis.hincrBy("user:1", "age", 1); // 年齡 +1
jedis.hkeys("user:1"); jedis.hvals("user:1");
Set (集合)
jedis.sadd("tags", "java", "redis");
jedis.sismember("tags", "java"); // 存在性 O(1)
jedis.sinter("tags1", "tags2"); // 交集
jedis.sunion("tags1", "tags2"); // 並集
jedis.sdiff("tags1", "tags2"); // 差集
Sorted Set (有序集合)
jedis.zadd("rank", 100, "Alice");
jedis.zadd("rank", 95, "Bob");
jedis.zrange("rank", 0, -1); // 分數升序
jedis.zrevrange("rank", 0, -1); // 分數降序
jedis.zscore("rank", "Alice"); // 獲取分數
jedis.zrank("rank", "Alice"); // 獲取排名 (0-based)
jedis.zrem("rank", "Bob"); // 移除
生產環境建議
- 啟用
TestOnBorrow + TestWhileIdle 確保連接可用。
- 根據 QPS 設置
MaxTotal,監控 NumActive/NumIdle 指標。
- 使用
RedisTemplate 統一異常處理與資源釋放。
- Key 設計加前綴 (如
biz:module:key) 便於管理。
- 大 Key 拆分、熱 Key 緩存、Lua 腳本保證原子性。