必须设过期时间的键包括临时凭证类、缓存结果类和会话与状态类;应选用setex/psetex等原子命令避免过期被清除,通过随机偏移防止集中过期,并配合allkeys-lru淘汰策略兜底。

关键不是“设了过期时间就万事大吉”,而是让过期机制真正起效,同时匹配业务真实生命周期。
明确哪些键必须设过期时间
不是所有键都需要过期,但以下几类必须设:
- 临时凭证类:如登录 token、短信验证码、防重 key。这类数据天然有时效性,不设过期就是内存泄漏源头。
- 缓存结果类:如接口响应、商品详情页 HTML 片段、聚合计算结果。它们依赖上游数据新鲜度,过期时间应略短于源数据变更周期。
- 会话与状态类:如购物车、用户行为埋点临时桶、分布式锁的占位 key。业务逻辑本身定义了其有效窗口(例如“30分钟未操作清空购物车”)。
而用户基本信息、配置字典等长期有效的数据,可不设过期时间,但需确保有其他机制(如主动更新)保障一致性。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
选对命令,避免过期被意外清除
很多键“没过期”是因为设置方式出错,导致过期时间被覆盖或忽略:
- 用 SETEX 或 PSETEX 替代
SET + EXPIRE组合。前者是原子操作,避免中间状态(如 SET 成功但 EXPIRE 失败)。 - 避免对已存在 key 频繁调用
SET。Redis 规定:任何写命令(如 SET、HSET、LPUSH)都会清除原有 key 的过期时间,除非显式再调用 EXPIRE。 - 若需更新值又保留原有过期时间,改用 GETSET(字符串)或带
XX选项的命令,并在更新后立即EXPIRE原 key。
控制过期时间粒度与分布
过期时间不合理,会导致两种极端问题:
- 集中过期:大量 key 在同一秒过期,触发 Redis 定期删除密集扫描,可能拖慢响应、加剧内存抖动。解决办法是加随机偏移,比如基础过期时间设为 300 秒,再叠加 ±30 秒扰动。
- 精度错配:验证码用秒级(EXPIRE)足够;但高频限流令牌桶若要求 100ms 级失效,就得用 PEXPIRE 或 PEXPIREAT,否则精度丢失导致防刷失效。
- 业务脱节:比如支付订单锁 key 设 2 小时,但实际支付流程超时仅 15 分钟——多出的 105 分钟纯属内存浪费,还可能阻塞后续合法请求。
配合内存淘汰策略兜底
即使所有 key 都设了过期时间,仍可能因访问稀疏、定期删除漏删,导致过期 key 残留。这时需靠内存淘汰策略守最后一道关:
- 生产环境推荐配置 maxmemory-policy allkeys-lru。它不区分是否带过期时间,只按最近最少使用淘汰,能有效防止冷门过期 key 占据内存。
- 避免使用
noeviction(默认策略),否则内存满时直接报错,服务不可用。 - 监控
evicted_keys指标。如果该值持续增长,说明过期+淘汰双机制仍压不住数据增长,需回查业务是否误存长周期数据或过期时间设得过长。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










