Есть сообщение о команде Redis, чтобы получить все доступные ключи, но я хотел бы сделать это с Python.
Как это сделать?
Есть сообщение о команде Redis, чтобы получить все доступные ключи, но я хотел бы сделать это с Python.
Как это сделать?
scan()
превосходит keys()
для большого количества клавиш, потому что он дает вам итератор, который вы можете использовать, а не пытаться загрузить все ключи в память.
У меня было 1B записей в моем redis, и я никогда не мог получить достаточно памяти, чтобы сразу вернуть все ключи.
СКАНИРОВАНИЕ КЛЮЧЕЙ ONE-BY-ONE
Вот фрагмент python, использующий scan()
, чтобы получить все ключи из хранилища, соответствующие шаблону, и удалить их один за другим:
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
for key in r.scan_iter("user:*"):
# delete the key
r.delete(key)
СКАНИРОВАНИЕ В БЛОКАХ
Если у вас есть очень большой список ключей для сканирования - например, более чем > 100 тыс. ключей - будет более эффективно сканировать их в пакетах, например:
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)
Я сравнивал этот script и обнаружил, что использование размера пакета 500 в 5 раз быстрее, чем сканирование ключей один за другим. Размер партии 500, казалось, был оптимальным для локального использования на моем Macbook Pro, он может отличаться по сети. Я тестировал размер партии 10, 100, 500, 1000 и 10000. Свяжитесь со мной, если вы хотите посмотреть, как я сравнивал ее.
Обратите внимание, что если вы используете метод scan()
или keys()
, операция не является атомарной и может завершиться неудачно.
ОПРЕДЕЛЕННО ИЗБЕГАЙТЕ С ИСПОЛЬЗОВАНИЕМ XARGS НА КОМАНДЕ-ЛИНИИ
Я не рекомендую этот пример, который я нашел неоднократно в другом месте. Он не будет работать для ключей unicode и невероятно медленен для даже умеренного количества клавиш:
redis-cli --raw keys "user:*"| xargs redis-cli del
В этом примере xargs создает новый процесс redis-cli для каждого ключа! Хлоп.
Я сравнил этот подход в 4 раза медленнее, чем первый пример python, где он удалял каждый ключ один за другим и в 20 раз медленнее, чем удалялся партиями по 500.
Да, используйте keys()
из модуля StrictRedis:
>>> import redis
>>> r = redis.StrictRedis(host=YOUR_HOST, port=YOUR_PORT, db=YOUR_DB)
>>> r.keys()
Предоставление нулевого шаблона будет извлекать все из них. В соответствии со связанной страницей:
клавиши (рисунок = '*')
Возвращает список совпадающих шаблонов
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 - количество элементов внутри коллекции.