web-dev-qa-db-fra.com

Obtenez toutes les clés de la base de données Redis avec python

Il y a un article sur une commande Redis pour obtenir toutes les clés disponibles, mais j'aimerais le faire avec Python.

Une façon de faire ça?

49
tscizzle

scan() est supérieur à keys() pour un grand nombre de clés car il vous donne un itérateur que vous pouvez utiliser plutôt que d'essayer de charger toutes les clés en mémoire.

J'avais un disque 1B dans mes disques durs et je ne pouvais jamais avoir assez de mémoire pour rendre toutes les clés à la fois.

TOUCHES DE BALAYAGE UNE PAR UNE

Voici un extrait de code python) utilisant scan() pour obtenir toutes les clés du magasin correspondant à un modèle et les supprimer un par un:

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

BALAYAGE EN LOTS

Si vous avez une très longue liste de clés à analyser - par exemple, supérieures à> 100 000 clés - il sera plus efficace de les analyser par lots, comme ceci:

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)

J'ai analysé ce script et trouvé qu'utiliser une taille de lot de 500 était 5 fois plus rapide que de numériser des clés une par une. Une taille de lot de 500 semblait optimale s’exécutant localement sur mon Macbook Pro, elle pouvait différer sur un réseau. J'ai testé des tailles de lots de 10, 100, 500, 1000 et 10000. Contactez-moi si vous souhaitez voir comment je l'ai comparé.

Notez que, que vous utilisiez la méthode scan() ou keys(), l'opération n'est pas atomique et pourrait échouer en cours de route.

EVITER DEFINITIVEMENT D'UTILISER XARGS SUR LA LIGNE DE COMMANDE

Je ne recommande pas cet exemple que j'ai trouvé répété ailleurs. Cela ne fonctionnera pas pour les clés Unicode et est incroyablement lent, même pour un nombre modéré de clés:

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

Dans cet exemple, xargs crée un nouveau processus redis-cli pour chaque clé! beurk.

J'ai comparé cette approche à 4 fois plus lente que la première python exemple où elle supprimait chaque clé une à une et 20 fois plus lentement que la suppression par lots de 500.

81
Patrick Collins

Oui, utilisez keys() du module StrictRedis:

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

Donner un motif nul ira tous les chercher. Selon la page liée:

clés (modèle = '*')

Retourne une liste de clés correspondant au motif

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

en utilisant la bibliothèque Pyredis

commande d'analyse

Disponible depuis 2.8.0.

Complexité temporelle: O(1) pour chaque appel. O(N)) pour une itération complète, y compris un nombre suffisant d'appels de commande pour que le curseur revienne à 0. N est le nombre d'éléments contenus dans la collection.

9
Black_Rider