La valeur par défaut est 10
. Cela signifie que la commande ramènera plus ou moins 10 clés , peut être inférieur si les clés sont peu remplies dans les emplacements de hachage ou filtrées par le MATCH
modèle. Cela pourrait être plus si certaines clés partagent un emplacement de hachage. Quoi qu'il en soit, le travail effectué est proportionnel au COUNT
paramètre.
Redis est monothread. Une des raisons SCAN
a été introduit est de permettre de parcourir toutes les clés sans bloquer le serveur pendant longtemps, en procédant par étapes successives.
Et c'est précisément le critère pour décider ce qui est un bon numéro. Pendant combien de temps êtes-vous prêt à bloquer votre serveur Redis en exécutant un SCAN
commande. Plus le COUNT
est élevé , plus le bloc est long.
Utilisons un script Lua pour avoir une idée du COUNT
impacter. Utilisez-le sur votre environnement pour obtenir les résultats en fonction des ressources de votre serveur.
Le script 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
Ici, nous utilisons Redis TIME
commande. La commande renvoie :
- temps unix en secondes
- microsecondes
Quelques exécutions dans ma machine, avec 1 million de clés :
COUNT TIME IN MICROSECONDS
10 37
100 257
1000 1685
10000 14438
Notez que ces temps n'incluent pas le temps utilisé pour lire à partir du socket et pour mettre en mémoire tampon et envoyer la réponse. Les temps réels seront plus grands. Le temps qu'il faut une fois hors de Redis, y compris le temps de déplacement sur le réseau, n'est pas le temps que votre serveur Redis est bloqué.
Voici comment j'ai appelé le script Lua et les résultats :
> 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"