web-dev-qa-db-ja.com

pythonでRedisデータベースのすべてのキーを取得する

利用可能なすべてのキーを取得するRedisコマンドについての投稿がありますが、Pythonでそれをやりたいです。

これを行う方法はありますか?

49
tscizzle

scan()は、多数のキーに対してkeys()よりも優れています。これは、すべてのキーをメモリにロードしようとするのではなく、使用できる反復子を提供するためです。

Redisに1Bレコードがあり、一度にすべてのキーを返すのに十分なメモリを確保できませんでした。

スキャンキーを1つずつ

パターンに一致するストアからすべてのキーを取得し、それらを1つずつ削除するためにscan()を使用するpythonスニペット)は次のとおりです。

_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倍高速であることがわかりました。 Macbook Proでローカルに実行する場合、バッチサイズ500は最適と思われますが、ネットワークによって異なる場合があります。 10、100、500、1000、10000のバッチサイズをテストしました。ベンチマークの方法を確認したい場合は、ご連絡ください。

scan()またはkeys()メソッドのどちらを使用しても、操作はアトミックではなく、途中で失敗する可能性があることに注意してください。

コマンドラインでXARGSを使用することは絶対に避けてください

他の場所で繰り返されるこの例をお勧めしません。 Unicodeキーでは機能せず、中程度の数のキーでも非常に遅くなります。

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

この例では、xargsはすべてのキーに対して新しいredis-cliプロセスを作成します!うわぁ。

このアプローチをベンチマークして、最初のpythonの場合、すべてのキーを1つずつ削除し、500のバッチで削除するより20倍遅い例よりも4倍遅くなるようにしました。

81
Patrick Collins

はい、StrictRedisモジュールの keys() を使用します。

>>> import redis
>>> r = redis.StrictRedis(Host=YOUR_Host, port=YOUR_PORT, db=YOUR_DB)
>>> r.keys()

Nullパターンを指定すると、それらすべてが取得されます。リンクされているページごとに:

keys(pattern = '*')

パターンに一致するキーのリストを返します

42
fedorqui
import redis
r = redis.Redis("localhost", 6379)
for key in r.scan_iter():
       print key

pyredisライブラリを使用する

スキャンコマンド

2.8.0以降で使用可能。

時間の複雑さ:O(1)すべての呼び出しに対して。 O(N)は、カーソルが0に戻るための十分なコマンド呼び出しを含む、完全な反復を行います。Nは、コレクション内の要素の数です。

9
Black_Rider