欢迎大家来到IT世界,在知识的湖畔探索吧!
Redis 过期键删除策略全景实战
一、为什么需要过期键?
- 验证码、临时缓存(短生命周期数据)
- Session / Token 管理(自动过期失效)
- 缓存雪崩防护(TTL 加随机)
- 数据热点控制(避免缓存击穿)
二、过期键删除的三种策略
|
策略 |
触发方式 |
优点 |
缺点 |
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"));
欢迎大家来到IT世界,在知识的湖畔探索吧!
四、惰性删除示例
惰性删除在 访问键时 才会触发。
欢迎大家来到IT世界,在知识的湖畔探索吧!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);
五、定期删除示例
String info = jedis.info("stats"); System.out.println(info); // 含 expired_keys、evicted_keys 等指标
如果想调整清理频率,可在 redis.conf 中修改:
欢迎大家来到IT世界,在知识的湖畔探索吧!hz 50 # 提高后台任务频率(默认 10)
六、大对象删除:DEL vs UNLINK
- DEL:同步删除,可能阻塞 Redis。
- UNLINK:异步删除,适合大对象。
// 构建一个大 Hash for (int i = 0; i < ; i++) { jedis.hset("big:hash", "field" + i, String.valueOf(i)); } // 异步删除(推荐) jedis.unlink("big:hash");
七、缓存雪崩防护(TTL 随机化)
如果大量缓存同时过期,可能导致雪崩。解决办法是给 TTL 加上随机值:
欢迎大家来到IT世界,在知识的湖畔探索吧!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 已过期"); }
九、监控过期与淘汰情况
欢迎大家来到IT世界,在知识的湖畔探索吧!// 获取 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
十一、总结
在 Java 开发中,通过 Jedis 很容易实现 TTL 控制,同时结合业务特点(如防雪崩、Session 管理、大对象异步删除),能构建更稳定的缓存体系。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/143865.html