UNLINK 非阻塞删除大键
UNLINK 与 DEL 的语义相同(把键从键空间移除),区别在于内存释放:UNLINK 把释放工作交给后台线程异步完成,因此删除包含数百万元素的集合时不会卡住主线程。Redis 4.0 引入它,主要针对「删一个巨大 zset 停顿数秒」这类问题。命令返回时键已经从键空间消失,其他客户端立刻查不到,但进程占用的内存要过一段时间才真正回落。
基本信息
| 语法 | UNLINK key [key ...] |
|---|---|
| 引入版本 | Redis 4.0 起 |
| 与 DEL 的差别 | 内存释放异步 |
| 键空间可见性 | 返回时即已摘除 |
| 返回值 | 被删除的键数量 |
| 观测方式 | used_memory 回落存在延迟 |
| 相关配置 | lazyfree-lazy-user-del |
典型使用场景
- 清理业务滚动的超大集合,避免删除操作阻塞其他请求
- 缓存重建前批量移除旧数据结构,控制单次阻塞时长
- 运维脚本批量删除过期明细键,需要平滑化负载
- 排查删除大键导致的延迟尖峰,用 UNLINK 验证因果
- 与 FLUSHALL ASYNC 配合做环境清理,保持主线程可用
- 自动化治理流程中删除大键,避免定时任务触发业务抖动
使用与验证
使用与验证
redis-cli MEMORY USAGE big:zset # 先评估键的规模
redis-cli UNLINK big:zset # 异步删除,不阻塞主线程
redis-cli EXISTS big:zset # 立即返回 0,键空间已摘除
redis-cli UNLINK stale:set:1 stale:set:2 # 多键一次传入
redis-cli INFO memory | grep -E 'used_memory:' # 内存回落有延迟
redis-cli CONFIG GET lazyfree-lazy-user-del # 确认 DEL 是否也异步UNLINK 与 DEL 对照
| 对比项 | DEL | UNLINK |
|---|---|---|
| 语义 | 删除键 | 删除键 |
| 内存释放 | 主线程同步完成 | 后台线程异步完成 |
| 大键阻塞 | 可能明显 | 基本消除 |
| 键空间可见性 | 返回即可见已删除 | 返回即可见已删除 |
| 版本要求 | 全版本 | Redis 4.0 及以上 |
把 lazyfree-lazy-user-del 打开后,DEL 本身也会走异步释放路径,但显式使用 UNLINK 的语义更清楚,脚本里优先写 UNLINK。
删除之后马上查看内存可能看不到回落,这不代表删除失败,先看键是否存在,再看趋势曲线。