Gun*_*K K 5 redis stackexchange.redis
我已经理解了 REDIS SCAN 中 COUNT 的含义。但是, REDIS COUNT 的理想值是多少?
默认值为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命令。该命令返回:
在我的机器上运行了几次,有 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)