bigywater.tech
Redis · 27

大量 Key 同时过期

插入5万个key全部设置相同的200毫秒过期时间,追踪DBSIZE的下降轨迹,并用并发PING探测批量过期对服务响应的影响。

约110ms
5万个key完成分批清理的时间
7.55ms
整个过程观测到的最大并发延迟
分批扫描
设计上避免了瞬时批量过期造成的卡顿

做的事:5万个key,全部设置成同一个过期时间点

如果一次性给大量key设了几乎相同的TTL,到期那一刻会不会造成服务卡顿。

操作插入5万个key,全部PX 200(200毫秒后过期) 追踪之后2秒内DBSIZE的变化

验证:DBSIZE是分批下降的,不是一次性归零

记录到期前后DBSIZE随时间的完整轨迹。

结果t=0.11s DBSIZE=5239 t=0.22s DBSIZE=0 t=0.33s~2.14s DBSIZE=0(持续保持)

观测到:从"还剩5239个"到"清零",中间经过了大约110毫秒——不是瞬间从5万变成0,而是后台的过期扫描机制在分批处理这批同时到期的key,一轮一轮地清,不是一次性全扫完。

验证:批量过期期间,服务响应没有明显卡顿

用并发PING探测这段时间里服务器有没有被拖慢。

结果观测窗口(2秒)内PING次数: 284 最大单次PING延迟: 7.55 ms 平均PING延迟: 0.202 ms

整个5万个key批量过期的过程中,并发PING的最大延迟只有7.55毫秒——不算完全无感知,但远远没有到"卡顿"的程度(对照本系列讲DEL大key时测出的819毫秒阻塞,这个数字小了100多倍)。

这背后的设计是:Redis的主动过期扫描每一轮只处理一小批采样的key(默认每轮处理有限数量、并且有的时间预算上限,超过预算就主动让出控制权给其它命令),哪怕同一时刻有5万个key一起到期,也不会让某一次扫描操作占用主线程太久。这也是为什么"批量设置相同的绝对过期时间"(比如很多业务喜欢把TTL都设成"今天午夜")通常不需要过度担心——的Redis设计已经把这种场景考虑进去了,用分批处理平滑了瞬时压力,不会引发的服务抖动。

分步演示:大量key同时过期的时间轨迹

每一步都是本文上面用redis-py跑出来的原始结果。

5万个key同时过期,是分批平滑处理的
这一步新验证的观测

    本文用到的工具

    • 本机 Redis 8.10.1 单节点,5万个key统一200ms TTL
    • DBSIZE轮询 + 并发PING探测:追踪批量过期的时间轨迹和对服务的影响
    京ICP备2026067502号-1京公网安备11010502063487号