生产环境清理 BigKey 不能直接用 DEL,因 O(N) 时间复杂度会阻塞主线程;String 类型推荐 UNLINK,集合类型须用 SCAN 配合 HDEL/LTRIM/SREM/ZREMRANGEBYRANK 分批删除。

生产环境清理 BigKey 不能直接用 DEL,尤其对 Hash、List、Set、ZSet 类型——单次删除耗时长,会阻塞主线程,引发超时和雪崩。必须用 SCAN 配合对应类型的安全删除命令,分批释放内存。
为什么不能直接 DEL 大 Key
DEL 删除集合类 BigKey 的时间复杂度是 O(N),N 是元素个数。比如一个含 200 万成员的 ZSet,DEL 可能卡住主节点几百毫秒甚至数秒,期间所有请求排队等待。Redis 单线程模型下,这是高危操作。
String 类型 BigKey 清理
String 类型相对简单,优先使用 UNLINK(Redis 4.0+),它把删除动作异步化,不阻塞主线程:
-
UNLINK key_name—— 推荐首选,立即返回,后台回收内存 - 若版本低于 4.0,可用
DEL,但需确认该 key 确实不再被访问,且业务可容忍短时延迟
集合类型 BigKey 渐进式清理(Hash/List/Set/ZSet)
核心思路:用 SCAN 类命令分片遍历 + 对应类型批量删除子项,避免一次性加载全量数据。每轮只处理少量元素,控制执行时间在毫秒级。
-
Hash:用
HSCAN key cursor COUNT 100迭代 field,配合HDEL key f1 f2 ...批删(每次最多 1000 个 field) -
List:用
LTRIM key start end逐步截断,例如LTRIM key 1000 -1保留后 N 个,再LTRIM key 0 0清空剩余;或用LPOP/RPOP循环弹出(适合小流量场景) -
Set:用
SSCAN key cursor COUNT 500获取成员,再SREM key m1 m2 ...批删 -
ZSet:用
ZSCAN key cursor COUNT 500或ZREMRANGEBYRANK key 0 99分段移除(推荐后者,更高效)
安全执行的关键细节
实际操作中容易忽略但至关重要的几点:
- 务必在从节点或业务低峰期运行扫描脚本,避免加重主节点负载
- SCAN 的
COUNT参数只是提示值,建议设为 100~500,兼顾速度与压力;太大会增加单次响应时间,太小则往返次数过多 - 脚本中需检查游标是否返回 0,作为遍历结束标志;未结束前不可提前退出
- 删除过程中注意监控
used_memory_peak和evicted_keys,防止触发驱逐或 OOM - 禁止在脚本里用
KEYS *或DEBUG OBJECT,它们都会阻塞服务


















