redis过期key未及时清理是因延迟释放机制与业务负载、配置不匹配所致;可通过调高hz参数、启用lazyfree异步删除、分散过期时间及应急惰性清理优化。

Redis中过期Key未被及时清理,导致物理内存长期居高不下,本质是“延迟释放”机制与业务负载、配置策略不匹配的结果。它不是Bug,而是设计取舍——但可优化。
检查并调高过期键扫描频率(hz参数)
Redis默认每秒执行10次过期扫描(hz=10),每次最多耗时25ms,随机抽查20个key。在高并发或大批量过期场景下,这个节奏容易滞后。
- 将hz提升至20~50(如
hz 30),可加快过期key的发现速度 - 注意:hz过高会增加CPU开销,建议结合监控观察CPU使用率变化
- 修改后需重启Redis或通过
CONFIG SET hz 30动态生效(仅限部分版本支持)
启用lazyfree异步删除机制
当大量过期key集中存在(尤其大value如hash、zset),同步删除会阻塞主线程,拖慢响应,也间接延缓后续过期检查。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 在
redis.conf中开启:lazyfree-lazy-expire yes - 该配置让Redis把过期key的内存回收移交后台线程,避免阻塞客户端请求
- 配合
lazyfree-lazy-server-del yes和lazyfree-lazy-user-del yes可进一步覆盖其他删除场景
分散过期时间,避免“过期风暴”
同一秒内成千上万key过期,会触发密集的定期删除循环,甚至反复扫描DB,加剧延迟与内存滞留。
- 设置TTL时加入随机偏移,例如原计划60分钟,改为
EX 3600 + random(0, 300)(即±5分钟) - 对批量写入的缓存(如商品列表、用户画像),按哈希或分页打散过期时间
- 避免用固定时间戳(如
EXPIREAT key 1747574400)批量设同一过期点
主动触发一次全量惰性清理(应急手段)
若已观察到内存持续高位且INFO memory中mem_clients_normal或used_memory_dataset_perc异常高,可人工辅助释放:
- 用
SCAN逐批遍历key(避免KEYS *阻塞),配合TTL判断并DEL过期key - 更安全的做法:用Lua脚本原子执行,例如
EVAL "for i, k in ipairs(redis.call('SCAN', 0, 'COUNT', 1000)) do if redis.call('TTL', k) - 生产环境建议在低峰期执行,并限制单次SCAN数量,防止超时










