redis はシングルプロセスで動くので、
大量のキーを走査する目的で keys *
とかやるとえらいことになるので、
代わりに scan
族を使うとよさげ、っていう話。
カーソルは0からスタートして、再度0になると1順したことになるので、全件走査はこんな感じ。
必ず count
で指定した件数が取れるわけでもないらしい。
他に set, hash, zset に対するscanもあって、使い方はだいたい同じ。
意外とググっても情報出てこないのでメモ。
python
import redis
r = redis.StrictRedis()
cr = 0
acc = 0
while True:
cr, keys = r.scan(cr, match="*", count=10000)
acc += len(keys)
print(cr, len(keys), acc)
if cr == 0:
break
print(r.dbsize())
stdout
60736 10001 10001
90528 10000 20001
827920 10001 30002
...(中略)
832503 10000 870045
864591 10000 880045
858799 10001 890046
853023 10000 900046
100191 10000 910046
529855 10001 920047
0 8407 928454
928454
redis-cli
だとこれで自動的に1件ずつscanしてくれる。
$ redis-cli --scan --pattern '*'
MONITOR
1487148044.325432 [0 172.17.0.1:35426] "SCAN" "877248" "MATCH" "*"
1487148044.325922 [0 172.17.0.1:35426] "SCAN" "320192" "MATCH" "*"
1487148044.331590 [0 172.17.0.1:35426] "SCAN" "385728" "MATCH" "*"
1487148044.332199 [0 172.17.0.1:35426] "SCAN" "70336" "MATCH" "*"
1487148044.332777 [0 172.17.0.1:35426] "SCAN" "824000" "MATCH" "*"
1487148044.333387 [0 172.17.0.1:35426] "SCAN" "496320" "MATCH" "*"
1487148044.333901 [0 172.17.0.1:35426] "SCAN" "53952" "MATCH" "*"
1487148044.349686 [0 172.17.0.1:35426] "SCAN" "381632" "MATCH" "*"
...(略)
先頭から何件か欲しい場合はパイプで head -n 1000
とかに流すとよい。
tailだと駄目だけど。
こっちの方が詳しい
けどまぁいいか。もう書いちゃったし。