bigywater.tech
Redis · 19

DEL、UNLINK、异步释放

建一个423MB的大hash,对比DEL和UNLINK的自身耗时,以及测量它们对并发客户端造成的阻塞影响,看异步释放到底省在哪。

4250倍
UNLINK比DEL快的自身耗时倍数
819ms
DEL阻塞其它并发客户端的最大延迟
0.81ms
UNLINK期间几乎无感知的并发延迟

做的事:一个423MB的大key,测两种删除方式

DEL和UNLINK看起来都是"删掉这个key",的区别在删除这个动作本身花了多久、以及花的时间算在谁头上。

建的keyHSET 500万个字段到bighash_del MEMORY USAGE bighash_del → :423441162字节(约423MB)

验证:DEL要0.85秒,UNLINK只要0.2毫秒

同样大小的key,分别复制一份,一个用DEL一个用UNLINK。

结果DEL耗时: 0.8499 s UNLINK耗时: 0.0002 s

差了约4250倍。DEL 是同步命令,Redis要在这一条命令里,把这500万个字段占用的内存逐个释放干净,才能返回"OK"。UNLINK 则只做了一件很小的事:把这个key从主键值字典里摘除、立刻返回,真正释放内存这件"体力活",交给了一个独立的后台线程慢慢做。

验证:DEL卡住了其它并发客户端819毫秒

Redis是单线程处理命令的,DEL的0.85秒不是"这一个连接等了0.85秒"这么简单。

结果DEL期间,另一个并发连接的PING,观测到的最大单次延迟: 819.49 ms UNLINK期间,同样并发PING观测到的最大单次延迟: 0.81 ms

验证了:DEL在执行那0.85秒的内存释放工作时,Redis主线程整个被占住,其它所有客户端的所有请求(哪怕只是一个PING)都要排队等这条DEL执行完,819.49毫秒的延迟就是付出的代价。UNLINK因为真正耗时的释放工作被挪到了后台线程,主线程几乎立刻就能继续处理下一个客户端的请求,并发PING的延迟几乎感觉不到。

这就是为什么线上要删除一个很大的key(几十万字段的hash、几百万元素的set等)时,官方和社区都强烈建议用 UNLINK 而不是 DEL——DEL删大key会变成一次"全服卡顿"事件,UNLINK能把这份代价隔离到后台,不影响其它客户端的实时请求。(对于很小的key,两者几乎没有区别,DEL本身就很快。)

分步演示:大key删除对整个Redis的影响

每一步都是本文上面用423MB大hash跑出来的原始结果。

DEL卡住全服819毫秒,UNLINK几乎无感知
这一步新验证的结果

    本文用到的工具

    • 本机 Redis 8.10.1 单节点,423MB/500万字段的大hash
    • DEL vs UNLINK:对比同步与异步释放
    • 并发PING探测:测量DEL对其它客户端的阻塞影响
    京ICP备2026067502号-1京公网安备11010502063487号