REDIS 中 SCAN / HSCAN 命令的 COUNT 有推荐值吗?

Gun*_*K K 5 redis stackexchange.redis

我已经理解了 REDIS SCAN 中 COUNT 的含义。但是, REDIS COUNT 的理想值是多少?

Leo*_*llo 7

默认值为10。这意味着该命令将带回或多或少 10 个键,如果键在哈希槽中稀疏填充,或者被模式过滤掉,则可能会更少MATCH。如果某些键共享哈希槽,则可能会更多。无论如何,所做的工作与COUNT参数成正比。

Redis 是单线程的。引入的原因之一SCAN是允许通过一次执行几个步骤来检查所有密钥,而不会长时间阻塞服务器。

这正是决定什么是好数字的标准。您愿意通过运行命令来阻止您的 Redis 服务器多长时间SCAN。越高COUNT,块越长。

让我们使用Lua 脚本来感受一下影响COUNT。在您的环境中使用它来根据您的服务器资源获取结果。

Lua脚本:

local t0 = redis.call('TIME')
local res = redis.call('SCAN', ARGV[1], 'COUNT', ARGV[2])
local t1 = redis.call('TIME')
local micros = (t1[1]-t0[1])*1000000 + t1[2]-t0[2]
table.insert(res,'Time taken: '..micros..' microseconds')
table.insert(res,'T0: '..t0[1]..string.format('%06d', t0[2]))
table.insert(res,'T1: '..t1[1]..string.format('%06d', t1[2]))
return res
Run Code Online (Sandbox Code Playgroud)

这里我们使用RedisTIME命令。该命令返回:

  • UNIX 时间(以秒为单位)
  • 微秒

在我的机器上运行了几次,有 100 万个密钥:

COUNT    TIME IN MICROSECONDS
   10            37
  100           257
 1000          1685
10000         14438
Run Code Online (Sandbox Code Playgroud)

请注意,这些时间不包括用于从套接字读取以及缓冲和发送响应的时间。实际时间会更大。一次花费的时间是在Redis之外,包括网络传输的时间,但并不是你的Redis服务器被阻塞的时间。

这就是我调用Lua脚本的方式和结果:

> EVAL "local t0 = redis.call('TIME') \n local res = redis.call('SCAN', ARGV[1], 'COUNT', ARGV[2]) \n local t1 = redis.call('TIME') \n local micros = (t1[1]-t0[1])*1000000 + t1[2]-t0[2] \n table.insert(res,'Time taken: '..micros..' microseconds') \n table.insert(res,'T0: '..t0[1]..string.format('%06d', t0[2])) \n table.insert(res,'T1: '..t1[1]..string.format('%06d', t1[2])) \n return res" 0 0 5
1) "851968"
2) 1) "key:560785"
   2) "key:114611"
   3) "key:970983"
   4) "key:626494"
   5) "key:23865"
3) "Time taken: 36 microseconds"
4) "T0: 1580816056349600"
5) "T1: 1580816056349636"
Run Code Online (Sandbox Code Playgroud)