专业的JAVA编程教程与资源

网站首页 > java教程 正文

Redis 过期键删除策略全景实战_redis过期清除策略

temp10 2025-10-23 11:36:08 java教程 1 ℃ 0 评论

Redis 过期键删除策略全景实战


一、为什么需要过期键?

Redis 是内存数据库,数据无限增长会导致内存耗尽。因此 Redis 提供了键过期与删除机制,确保内存可控。
常见应用场景有:

  • 验证码、临时缓存(短生命周期数据)
  • Session / Token 管理(自动过期失效)
  • 缓存雪崩防护(TTL 加随机)
  • 数据热点控制(避免缓存击穿)

二、过期键删除的三种策略

策略

Redis 过期键删除策略全景实战_redis过期清除策略

触发方式

优点

缺点

Redis 是否采用

定时删除

定时器到期立即删

内存释放及时

占用 CPU 过大

惰性删除

客户端访问时检查

CPU 友好

内存可能浪费

定期删除

后台定期随机抽查

折中 CPU+内存

参数调优复杂

内存淘汰

内存不足时触发

保证可写入

删除未过期键

(补充机制)

Redis 实际采用 惰性删除 + 定期删除,并在内存不足时触发 淘汰策略


三、Java 中设置过期时间

Jedis jedis = new Jedis("localhost", 6379);

// 1. 设置值并指定过期时间(秒)
jedis.setex("user:1001", 60, "Tom");

// 2. 设置毫秒过期
jedis.psetex("user:1002", 3000, "Jerry");

// 3. 给已有键设置过期时间
jedis.set("order:12345", "pending");
jedis.expire("order:12345", 3600); // 1 小时

// 4. 查看剩余 TTL
System.out.println("TTL user:1001 = " + jedis.ttl("user:1001"));

四、惰性删除示例

惰性删除在 访问键时 才会触发。

jedis.setex("temp:data", 5, "123"); // 5 秒过期

try { Thread.sleep(6000); } catch (InterruptedException e) { }

String val = jedis.get("temp:data"); // null,Redis 自动删除
System.out.println("Value after expire: " + val);

五、定期删除示例

Redis 后台线程会定期扫描部分键。
可通过 INFO stats 查看统计数据:

String info = jedis.info("stats");
System.out.println(info); // 含 expired_keys、evicted_keys 等指标

如果想调整清理频率,可在 redis.conf 中修改:

hz 50   # 提高后台任务频率(默认 10)

六、大对象删除:DEL vs UNLINK

  • DEL:同步删除,可能阻塞 Redis。
  • UNLINK:异步删除,适合大对象。
// 构建一个大 Hash
for (int i = 0; i < 100000; i++) {
    jedis.hset("big:hash", "field" + i, String.valueOf(i));
}

// 异步删除(推荐)
jedis.unlink("big:hash");

七、缓存雪崩防护(TTL 随机化)

如果大量缓存同时过期,可能导致雪崩。解决办法是给 TTL 加上随机值:

import java.util.Random;

Random rand = new Random();
int ttl = 300 + rand.nextInt(60); // 300~360 秒

jedis.setex("cache:user:1001", ttl, "cached-data");

八、Session / Token 管理示例

常见的用户认证场景:

// 登录后生成 Token(30 分钟有效)
String token = "abcd1234";
jedis.setex("token:" + token, 1800, "user:1001");

// 校验 Token
String userId = jedis.get("token:" + token);
if (userId != null) {
    System.out.println("Token 有效, userId = " + userId);
} else {
    System.out.println("Token 已过期");
}

九、监控过期与淘汰情况

// 获取 Redis stats
String stats = jedis.info("stats");

// 打印过期和淘汰指标
for (String line : stats.split("\n")) {
    if (line.contains("expired_keys") || line.contains("evicted_keys")) {
        System.out.println(line.trim());
    }
}

输出示例:

expired_keys:12034
evicted_keys:456

十、应用启示

  • 验证码/临时数据 → 使用 setex,惰性删除即可
  • 高并发缓存 → TTL 加随机,避免雪崩
  • 大对象删除 → UNLINK 而不是 DEL
  • Session/Token → Redis 过期机制天然适合
  • 生产必配 → maxmemory-policy(如 allkeys-lru)
  • 监控必做 → 定期关注 expired_keys、evicted_keys

十一、总结

Redis 的过期机制并不是“立即删除”,而是多策略协同:
惰性删除 + 定期删除 → 保证性能与内存之间的平衡
内存淘汰策略 → 保证系统在高压下仍能运行

在 Java 开发中,通过 Jedis 很容易实现 TTL 控制,同时结合业务特点(如防雪崩、Session 管理、大对象异步删除),能构建更稳定的缓存体系。


本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表