Redis作为高性能内存数据库,在运行过程中依赖后台的定期任务来完成过期键清理、哈希表重哈希、客户端超时关闭等操作。这些任务的触发节奏由配置文件中的hz参数控制,它直接决定了服务器每秒钟进行定期任务轮询的次数。理解并合理调整hz,是保障Redis稳定高效运行的重要一环。

一、hz参数的基本作用
在Redis的源码设计中,事件循环每次进入之前都会根据hz值计算是否需要执行一次周期性任务。hz的默认值为10,含义是每秒执行10次定期任务,也就是大约每100毫秒运行一轮。每一轮中,Redis会抽取部分设置了过期时间的键进行检查,也会视情况触发其他后台维护逻辑。
之所以采用这种分轮次、抽样检查的方式,而不是一次性扫描所有键,是为了避免主线程被过长操作阻塞。hz越大,抽样和处理的频次越高,过期数据被发现和删除的速度也就越快;hz越小,后台任务间隔拉长,系统空闲时间更多,但脏数据可能留存更久。
二、何时需要考虑调整hz
大多数小型应用使用默认hz等于10已经足够,因为数据量不大,即使偶尔延迟清理也无明显感知。但当单个实例承载海量键、且过期键生成速度很快时,默认的十次每秒可能来不及处理,导致内存中堆积不少本应失效的键,进而引发内存占用偏高。
另外在写请求非常密集、且大量使用带TTL的缓存场景下,如果希望缓存失效更接近真实过期时间,避免“过期了却还占着内存”的情况,就可以适度上调hz。反之,如果Redis运行在CPU资源紧张、且对过期精度不敏感的离线分析环境,适当降低hz有助于减少不必要的计算开销。
三、hz调整的具体方法
最直接的方式是修改Redis配置文件redis.conf中的hz项,例如改为20或30,然后重启实例使配置生效。若不希望重启,也可以通过命令行执行config set hz 20进行动态设置,该修改在运行时立即生效,但重启后会恢复为配置文件中的值,因此持久化调整仍需改文件。
需要注意的是,hz并不是越大越好。官方文档指出,hz的最大值可设到500,但每提升一档都会增加主线程在定期任务上的时间占比。一般建议生产环境不超过100,常见优化区间在10到50之间。调整后应观察info stats中的expired_keys增长与used_memory变化,并结合CPU使用率判断是否合理。
四、hz与其他参数的协同
除了hz,Redis还提供了dynamic-hz功能,开启后(默认开启)服务器会根据客户端数量自动微调hz,在连接多时提升频率、连接少时回落,从而平衡响应与开销。若手动设置了hz,dynamic-hz仍会在该值基础上做有限浮动,不会突破设定上限。
此外,active-expire-effort参数控制了每轮过期检查的积极程度,取值1到10。当hz提高后配合较高的effort,能进一步加快清理,但同样消耗更多CPU。实际调优中应将hz与effort、maxmemory-policy一并考虑,才能形成完整的过期与内存管理方案。
| hz值 | 每秒任务轮数 | 适用场景 | 潜在风险 |
|---|---|---|---|
| 10(默认) | 10 | 普通缓存、数据量中等 | 高频过期时清理滞后 |
| 20到50 | 20到50 | 大键量、高写入缓存 | CPU占用小幅上升 |
| 100以上 | 100以上 | 极大量过期键且CPU充裕 | 主线程负担明显加重 |
五、调整前后的观察要点
每次改动hz后,建议通过redis-cli的info命令重点查看expired_stale_perc、expired_time_cap_reached_count等指标,了解过期循环是否触顶时间限制。若发现cap_reached频繁增长,说明单轮任务已吃满时间,继续加hz收益有限。
同时也要监控latency monitor中的事件延迟,确认定期任务没有造成可感知的命令卡顿。只有将过期效率、内存回收与访问延迟三者放在一起评估,才能确认hz调整真正起到了优化定期任务频率的作用,而不是单纯增加了系统负载。