1. ホーム
  2. python

[解決済み] PythonでRedisデータベースの全キーを取得する

2023-01-01 21:09:09

質問

Redisで利用可能なキーを全て取得するコマンドの投稿がありますが、Pythonで行いたいのです。

何か方法があれば教えてください。

どのように解決するのですか?

使用方法 scan_iter()

scan_iter() よりも優れています。 keys() の方が優れています。なぜなら、全てのキーをメモリにロードするのではなく、イテレータを使用することができるからです。

私はredisに1Bのレコードを持っていましたが、一度にすべてのキーを返すのに十分なメモリを確保することができませんでした。

キーを1つ1つスキャンする

以下のpythonのスニペットは scan_iter() を使って、パターンにマッチする全てのキーをストアから取得し、それらを一つずつ削除しています。

import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
for key in r.scan_iter("user:*"):
    # delete the key
    r.delete(key)

一括スキャン

もし、スキャンするキーのリストが非常に大きい場合、例えば、100kキーより大きい場合、このようにバッチでスキャンするのが効率的でしょう。

import redis
from itertools import izip_longest

r = redis.StrictRedis(host='localhost', port=6379, db=0)

# iterate a list in batches of size n
def batcher(iterable, n):
    args = [iter(iterable)] * n
    return izip_longest(*args)

# in batches of 500 delete keys matching user:*
for keybatch in batcher(r.scan_iter('user:*'),500):
    r.delete(*keybatch)

このスクリプトをベンチマークしたところ、バッチサイズ500を使用すると、キーを1つずつスキャンするよりも5倍速いことがわかりました。さまざまなバッチサイズ (3,50,500,1000,5000) をテストして、500 のバッチサイズが最適であることがわかりました。

を使うかどうかに関わらず scan_iter() または keys() メソッドを使用する場合、操作はアトミックではなく、途中で失敗する可能性があります。

コマンドラインでの xargs の使用は絶対に避けてください。

私は、他の場所で繰り返されているこの例をお勧めしません。ユニコードのキーでは失敗し、適度な数のキーであっても信じられないほど遅くなります。

redis-cli --raw keys "user:*"| xargs redis-cli del

この例では、xargsは全てのキーに対して新しいredis-cliプロセスを作成します!これは悪いことです。

この方法をベンチマークしてみたところ、最初のPythonの例でキーを1つずつ削除していく方法よりも4倍遅く、500個まとめて削除する方法よりも20倍遅くなりました。