Redis无冷数据识别能力,需人工定义冷标准(如IDLETIME≥86400)、定位冷键(SCAN+业务前缀,禁用KEYS)、安全删除(UNLINK分批,禁用FLUSH);maxmemory-policy仅兜底,删后须查mem_fragmentation_ratio。

直接说结论:Redis 本身没有“冷数据识别”能力,所谓手动批量清理冷数据,本质是“你定义冷、你找冷键、你删冷键”——三步缺一不可,漏掉任何一步都可能误删热数据或卡死服务。
怎么定义“冷数据”?别信直觉,得靠真实访问痕迹
Redis 不记录访问时间戳,TTL 只管过期不管冷热。OBJECT IDLETIME key 是唯一能查“多久没被访问过”的命令,但它有严重限制:只对未设置 EXPIRE 的 key 有效;且返回值是近似值(精度受 hz 配置影响),不是精确秒数。
- 生产环境建议阈值设为 ≥ 86400(24 小时),避免把刚缓存的中间态数据误判为冷数据
- 不要用
KEYS *扫全库查IDLETIME——会阻塞主线程,尤其在大实例上可能超时甚至触发 failover - 正确做法是结合业务日志或监控(如慢查询、AOF rewrite 频次)圈定疑似冷数据的 key 前缀,再针对性扫描
怎么安全批量删?UNLINK 比 DEL 更靠谱
DEL 是同步删除,遇到大 value(比如 10MB 的 hash)会卡住 Redis 主线程几百毫秒;UNLINK 把实际内存释放交给后台线程,主线程只做 key 标记,响应几乎无感。
- 单删:用
UNLINK key替代DEL key - 批量删(推荐):
SCAN分批 +UNLINK管道,例如一次扫 1000 个 key:redis-cli --scan --pattern "cache:order:*" | xargs -n 1000 redis-cli unlink
- 绝对不用
FLUSHDB或FLUSHALL——它们不区分冷热,清的是整个库,等同于重启缓存,后端必然雪崩
为什么不能只靠 maxmemory-policy 自动淘汰?
maxmemory-policy(比如 allkeys-lru)只在内存真正打满时才触发,而“内存告急”往往发生在达到阈值前:比如从 70% 突增到 95%,但还没触发淘汰,此时写入变慢、延迟飙升,必须人工干预。
-
volatile-lru类策略只淘汰带过期时间的 key,如果冷数据没设 TTL,它永远不碰 - LRU/LFU 依赖访问频率统计,冷数据若长期没被访问,其 LRU clock 值可能已老化,反而不如新写入的热数据“优先级低”
- 自动策略是兜底,不是主动治理——就像消防栓不能代替定期清理易燃物
最常被忽略的一点:删完冷数据后,务必用 INFO memory 看 mem_fragmentation_ratio。如果这个值 > 1.5,说明内存碎片高,光删 key 不解决根本问题,得考虑重启实例或启用 activedefrag yes(但后者有 CPU 开销)。









