Redis 4.0 非阻塞删除

栏目: 数据库 · 发布时间: 6年前

内容简介:一直以来,Redis 都是单线程的(参考大部分 Redis 命令的执行速度都很快,所以不是问题;但也有一些命令,比如以

一、要解决的问题

一直以来,Redis 都是单线程的(参考 FAQ )。这种模型使得 Redis 简单、高效,但缺点也很明显:如果执行一个比较耗时的命令,那么在该命令执行期间,整个 Redis 服务都将被阻塞(无法并发地执行其他命令)。

大部分 Redis 命令的执行速度都很快,所以不是问题;但也有一些命令,比如 ZUNIONSTORELRANGESINTER ,以及臭名昭著的 KEYS ,根据处理数据集大小的不同,可能会阻塞 Redis 数秒或几分钟。

DEL 命令为例,当被删除的 key 是 list、set、sorted set 或 hash 类型时,时间复杂度为 O(M),其中 M 是 key 中包含的元素的个数。

二、非阻塞删除

Redis 的作者 Salvatore Sanfilippo 自己也意识到了上述问题,并提出了对应的解决方案:非阻塞删除(参考 Lazy Redis is better Redis )。简而言之,「非阻塞删除」就是将删除操作放到另外一个线程(而非 Redis 主线程)去处理。

最终「非阻塞删除」在 Redis 4.0 中得以实现(参考 Redis 4.0 release notes ),从此 Redis 开启了 “多线程” 时代。

新增实现的「非阻塞删除」包括以下命令:

命令 (原来的)阻塞版本
UNLINK DEL
FLUSHALL ASYNC FLUSHALL
FLUSHDB ASYNC FLUSHDB

三、DEL vs UNLINK

1. 源码实现

参考 Redis 源码 可以发现, DELUNLINK 分别对应不同的处理函数:

命令 处理函数
DEL dbSyncDelete
UNLINK dbAsyncDelete

具体的实现细节请自行研读源码。

2. 耗时对比

下面我们来实际对比一下 DELUNLINK 的耗时差异。

开启 Slow log

设置 Slow log 记录每条命令的耗时(参考 SLOWLOG ):

127.0.0.1:6379> CONFIG SET slowlog-log-slower-than 0
OK
127.0.0.1:6379> CONFIG GET slowlog-log-slower-than
1) "slowlog-log-slower-than"
2) "0"

创建两个大 hash

准备一个 Lua 脚本:

local bulk = 1000
local fvs = {}
local j
for i = 1, ARGV[1] do
  j = i % bulk
  if j == 0 then
    fvs[2 * bulk - 1] = "field" .. i
    fvs[2 * bulk] = "value" .. i
    redis.call("HMSET", KEYS[1], unpack(fvs))
    fvs = {}
  else
    fvs[2 * j - 1] = "field" .. i
    fvs[2 * j] = "value" .. i
  end
end
if #fvs > 0 then
  redis.call("HMSET", KEYS[1], unpack(fvs))
end
return "OK"

将上述脚本保存为 huge_hmset.lua ,然后借助该脚本创建两个大 hash(参考 how to load lua script from file for redis ),分别为 hash1hash2 ,它们各自拥有 100 万个 field:

$ redis-cli --eval huge_hmset.lua hash1 , 1000000
"OK"
$ redis-cli --eval huge_hmset.lua hash2 , 1000000
"OK"

上述操作会在 Slow log 中产生大量 HMSET 命令,这里先清除掉:

127.0.0.1:6379> SLOWLOG RESET
OK

DEL hash1

127.0.0.1:6379> DEL hash1
(integer) 1
(0.63s)

UNLINK hash2

127.0.0.1:6379> UNLINK hash2
(integer) 1

查看 Slow log

127.0.0.1:6379> SLOWLOG GET 2
1) 1) (integer) 5089
   2) (integer) 1534653951
   3) (integer) 17
   4) 1) "UNLINK"
      2) "hash2"
   5) "127.0.0.1:56560"
   6) ""
2) 1) (integer) 5088
   2) (integer) 1534653948
   3) (integer) 630305
   4) 1) "DEL"
      2) "hash1"
   5) "127.0.0.1:56560"
   6) ""

耗时对比结果:

命令 耗时
DEL hash1 630305 us
UNLINK hash2 17 us

值得注意的是: UNLINK 执行如此之快,并非使用了什么快速算法,而是因为它将真正的删除操作异步化了。


以上所述就是小编给大家介绍的《Redis 4.0 非阻塞删除》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Ruby元编程

Ruby元编程

[意] Paolo Perrotta / 廖志刚、陈睿杰 / 华中科技大学出版社 / 2012-1-10 / 56.00元

《Ruby元编程》以案例形式循序渐进讲解Ruby对象模型原理和高级应用技巧,堪称动态语言的设计模式。书中讲述的各种Ruby编程模式,完全可以应用于其他动态语言(甚至静态语言)。本书不仅适合Ruby程序员阅读,也适合对动态编程 语言和面向对象编程感兴趣的读者阅读。所有对程序设计理论感兴趣的人都能从中获益。Ruby之父松本行弘作序推荐。一起来看看 《Ruby元编程》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码