redis实际采用惰性删除与定期删除结合的策略:惰性删除在访问键时检查并清理过期数据,定期删除则默认每100ms随机抽查部分过期键进行清理,兼顾内存回收及时性与cpu性能。

Redis定期删除的默认行为会影响Session过期及时性
Redis默认每100ms执行一次定期删除(active expiration),每次最多检查20个带过期时间的key,并清理其中已过期的。这对普通缓存够用,但Session场景下容易出问题:大量用户登录后只写入不读取(比如后台定时任务生成会话),这些session键就只能靠惰性删除触发——而它们可能永远不被访问,变成“僵尸会话”,持续占用内存。
你看到used_memory_human不断上涨、mem_fragmentation_ratio升高,往往就是这类冷过期键堆积所致。
- 定期删除不是全量扫描,它随机抽样,漏掉是常态
- Session键名通常有规律(如
sess:abc123),但Redis不利用这个特征优化扫描 - 默认配置下,一个过期的
session平均要等数秒甚至更久才被真正清理
调整hz参数能加快定期删除节奏
hz是Redis服务器配置项,控制定时任务的基准频率(单位:次/秒)。默认值为10,即每100ms执行一轮包括过期检查在内的后台任务。提高它可让定期删除更积极——但不是无代价的。
批量分析录音转写,输出多维度拓客报告。触发词:录音分析、总结、音频总结、拜访记录总结。当用户提及「分析录音」「看看录音数据」「最近的录音」「通话记录」且意图为批量统计/分析时触发。仅出现「录音」或「拜访」时需结合上下文,若仅查看单条详情则不触发。
- 将
hz设为20或30,意味着每33–50ms就检查一次过期键,显著缩短僵尸Session驻留时间 - 注意:该值不能超过100,否则CPU占用会明显上升;线上建议先从20起步,观察
redis-cli info cpu中的used_cpu_sys变化 - 修改方式:在
redis.conf中添加hz 20,然后重启Redis(热重载不支持hz) - 不推荐在共享Redis实例上盲目调高
hz,尤其当它还承载大量缓存或排行榜时
配合active-expire-effort提升单次清理能力
仅调高hz还不够。Redis每次定期删除的“工作量”还受active-expire-effort控制(默认值为1,范围1–10)。它决定每次检查时最多遍历多少个数据库分片、每个分片最多检查多少key。
- 把
active-expire-effort设为3或5,相当于让每次检查更“用力”,在同样100ms窗口内清理更多过期Session - 该参数支持运行时动态修改:
CONFIG SET active-expire-effort 3 - 和
hz不同,它不会增加调度频率,只影响单次任务深度,因此CPU开销增幅更可控 - 若Session数据集中在某1–2个db(如
SELECT 0),此参数效果最明显
真正关键的是避免依赖纯自动清理
无论怎么调hz和active-expire-effort,Redis的定期删除机制始终是概率性的——它不保证某个过期Session在TTL结束后1秒内消失。生产环境里,最稳妥的做法是主动干预。
- 在应用层加一层轻量级清理:例如每天凌晨用
SCAN匹配sess:*,对TTL返回-2的key执行DEL(注意别用KEYS) - 给Session键加统一
prefix(如session:),方便后续批量操作和监控 - 禁用
touch(即设resave: false且saveUninitialized: false),防止本已过期的Session因无效touch被续命 - 定期用
redis-cli --bigkeys或MEMORY USAGE抽查Session键大小,避免单个会话膨胀到KB级
自动清理机制只是兜底,真正的稳定性来自设计时就放弃对“Redis会准时删掉一切”的幻想。










