一、问题引出
起因: redis有很多的数据类型尤其像是list , hash ,set , zset 时间复杂度为O(N)的数据类型,
执行操作: 当我们执行del的时候,大的数据类型可能会导致我们的redis阻塞几秒钟甚至是几分钟
结果: 会导致redis阻塞,也可能会造成集群的主从切换,从而导致生产环境故障
二、非阻塞删除bigkey
Redis的作者提出解决方案:非阻塞删除(参考 Lazy Redis is better Redis) 非阻塞删除,就是将删除操作放到另外一个线程(而非 Redis 主线程)去处理
新增实现的「非阻塞删除」包括以下命令:
命令 | (原来的)阻塞版本 |
---|---|
UNLINK | DEL |
FLUSHALL ASYNC | FLUSHALL |
FLUSHDB ASYNC | FLUSHDB |
三、DEL vs UNLINK
1. 源码实现
参考 Redis 源码 可以发现,DEL 和 UNLINK 分别对应不同的处理函数:
命令 | 处理函数 |
---|---|
DEL | dbSyncDelete |
UNLINK | dbAsyncDelete |
具体的实现细节请自行研读源码。
2. 耗时对比
下面我们来实际对比一下 DEL 和 UNLINK 的耗时差异。
开启 Slowlog,并将超时时间设置为0:
config set slowlog-log-slower-than 0
config get slowlog-log-slower-than 确定设置成功
创建俩个大的hash,分别执行del和unlink删除两个hash,通过slowlog获取执行的时间
参考文章:http://www.russellluo.com/2018/08/async-del-since-redis-4-0.html