调大 hz 能加快过期 key 清理,因其提高 Redis 定期扫描过期 key 的频率,单位时间内检查更多 slot,更快摘除已过期 key。

为什么调大 hz 能加快过期 key 清理?
Redis 默认每秒执行 10 次定时任务(hz=10),其中一项就是扫描数据库里带过期时间的 key,尝试删除已过期的。但这个扫描是「惰性+定期」混合策略:每次只扫一小部分(默认 20 个 slot),且不保证立刻删净。当大量 key 在同一秒内集中过期(比如用 EXPIRE 批量设了相同 TTL),而 hz 太小,后台扫描跟不上过期速度,就会导致内存短暂冲高——这些 key 还没被清理,却已逻辑过期。
调大 hz(比如设为 100)会让 Redis 更频繁地触发过期扫描,单位时间内检查的 slot 更多,从而更快把已过期 key 从内存中摘除。
调整 hz 的实操要点和风险
修改方式很简单,在 redis.conf 中设置:
hz 100
或运行时动态生效(需 Redis ≥ 5.0):
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
CONFIG SET hz 100
但要注意几个关键限制:
-
hz并非越大越好:上限是 500,超过会被自动截断;实际建议不超过 100,否则 CPU 占用明显上升,尤其在高并发写入场景下可能挤占主线程资源 - 它只影响「定期删除」部分,不影响「惰性删除」——即客户端访问一个已过期 key 时仍会当场删掉,这部分行为不变
- 该参数对 AOF 重写、RDB 保存等后台任务无直接影响,但高频定时任务可能略微推迟其他后台操作的调度时机
- 集群模式下需逐节点配置,
CONFIG SET不会自动同步到其他节点
比调 hz 更治本的替代方案
单纯调 hz 是“加速清垃圾”,但若源头产生垃圾太快(比如每秒写入 10 万个 10 秒 TTL 的临时 token),再快的清理也追不上。更稳的做法是组合使用:
- 用
EXPIREAT替代EXPIRE,把过期时间错开:比如当前时间戳 +rand(8,12)秒,避免雪崩式过期 - 改用
SCAN+PEXPIRE主动轮询管理生命周期,把控制权拿到应用层,避开 Redis 后台扫描的不确定性 - 评估是否真需要 Redis 存储:短生命周期数据优先考虑本地缓存(如 Caffeine)或带 TTL 的消息队列(如 Kafka compact topic),减少 Redis 内存压力
如何验证 hz 调整是否生效?
别只看配置文件或 CONFIG GET hz,重点观察实际效果:
- 监控
expired_keys指标(用INFO stats查):调大后单位时间增量应更平滑,峰值下降 - 对比
used_memory_peak_human和used_memory_human差值:内存尖峰幅度收窄说明过期清理更及时 - 注意
evicted_keys是否上升——如果因hz过高抢走 CPU,导致请求延迟升高、连接堆积,反而可能触发 LRU 驱逐,那就得往回调
真正难的不是改那个数字,而是判断你的 key 过期模式是否适合靠频率硬扛;很多线上问题,改完 hz 看似缓解,一周后又复现,往往是因为没动数据生成逻辑本身。

















