永不过期缓存需配合主动更新机制,否则数据 stale;应拆分物理永存与逻辑过期,用 HSET 存 expireAt 时间戳,读时判断并异步重建,且所有 DB 写路径必须同步更新或删除缓存。

热点 Key 永不过期能缓解缓存击穿,但不是“设个永不过期”就完事——它必须配合主动更新机制,否则数据会彻底 stale。
为什么单纯 SET 一个永不过期 key 会出问题
Redis 里不设 EX 或 PX 参数,确实能让 key 永久存在,但这也意味着:数据库改了数据,缓存永远不会自动同步。用户看到的永远是冷启动那一刻写入的旧值。
- 常见错误现象:
GET hot_user_profile:1001一直返回 3 天前的头像 URL,而数据库里早更新了 - 适用场景:仅限变更极低频、容忍分钟级延迟的配置类数据(如系统开关、灰度比例)
- 真实业务中,商品详情、用户资料等高频更新数据绝不能只靠“永不过期”扛
SET 永不过期 + HASH 存逻辑过期时间的实操写法
把“物理永存”和“逻辑过期”拆开:key 本身不过期,但 value 里嵌一个 expireAt 字段,由业务代码判断是否该刷新。
每小时自动在推特搜索中国、加密货币、国际热点、美国热点、特朗普等话题的热度信息,提取前十热点,依据 X 平台真实算法权重(开源代码数据)为每个热点生成高曝光推文或线程。用户提及“推特热点”“Twitter热点”“推特搜索”“热点推文”“生成推文”“社交媒体监控”“Twitter监控”等关键词时触发。
- 写入示例:
redis-cli -p 6379 HSET hot_article:123 title "AI厨电新国标解读" content "..." expireAt 1743589200
(expireAt是 Unix 时间戳) - 读取时先
HGETALL,检查expireAt是否小于当前时间;过期则触发异步重建,原线程直接返回旧数据 - 注意:不要用
String存 JSON 后解析——Redis 原生命令无法原子操作 JSON 字段,容易出现并发写覆盖
用 SETNX 配合后台线程做无锁重建的关键细节
逻辑过期方案里,“谁来触发重建”比“怎么存”更重要。直接在请求线程里同步查库重建,等于把压力又导回 DB。
- 正确做法:读到逻辑过期后,用
SETNX hot_article:123:rebuild_lock 1 EX 30尝试抢锁;抢到则立即 spawn 后台线程执行queryFromDB()+HSET更新,然后释放锁 - 没抢到锁的请求,不做任何等待,直接返回缓存旧值——这是性能和一致性的关键取舍
- 容易踩的坑:
EX 30必须设,否则锁残留;后台线程异常退出时没清理锁,会导致后续所有请求都跳过重建
真正要盯住的不是过期策略,而是更新入口是否唯一
再完善的永不过期+逻辑过期方案,如果数据库更新路径不止一条(比如运营后台直连 DB、MQ 消费更新、定时任务补数),缓存就一定会不一致。
必须确保:所有写 DB 的通道,都同步调用一次 DEL hot_article:123 或 HSET hot_article:123 expireAt ...。漏掉任意一个,缓存就变成“伪实时”。

















