Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

stackexchange.redis - Is there any recommended value of COUNT for SCAN / HSCAN command in REDIS?

I have understood the meaning of COUNT in the case of REDIS SCAN. But, what is the ideal value for REDIS COUNT ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The default value is 10. It means the command will bring back more or less 10 keys, could be less if the keys are sparsely populated in the hash slots, or filtered out by the MATCH pattern. It could be more if some keys are sharing a hash slot. Anyhow, the work performed is proportional to the COUNT parameter.

Redis is single-threaded. One of the reasons SCAN was introduced is to allow going through all the keys without blocking the server for a long time, by going a few steps at a time.

And that's precisely the criteria to decide what's a good number. For how long are you willing to block your Redis server by running a SCAN command. The higher the COUNT, the longer the block.

Let's use a Lua script to get a sense of the COUNT impact. Use it on your environment to get the results based on your server resources.

The Lua script:

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

Here we use Redis TIME command. The command returns:

  • unix time in seconds
  • microseconds

A few runs in my machine, with 1 million keys:

COUNT    TIME IN MICROSECONDS
   10            37
  100           257
 1000          1685
10000         14438

Note these times don't include the time used to read from the socket and to buffer and send the response. Actual times will be larger. The time it takes once is out of Redis, including time traveling the network is not time your Redis server is blocked though.

This is how I called the Lua script and the results:

> EVAL "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" 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"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...