Python redis keys count

Получить все ключи в базе данных Redis с помощью Python

Есть сообщение о команде Redis для получения всех доступных ключей, но я бы хотел сделать это с помощью Python. Как это сделать?

Ответы (5)

Используйте 1_ scan_iter() превосходит keys() для большого количества ключей, потому что дает вам итератор, который вы можете использовать, вместо того, чтобы пытаться загрузить все ключи в память. В моем Redis было 1B записей, и я никогда не мог получить достаточно памяти, чтобы вернуть все ключи сразу. ПОТОЛОЧНОЕ СКАНИРОВАНИЕ КЛЮЧЕЙ Вот фрагмент кода 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 было в 5 раз быстрее, чем сканирование ключей по одному. Я протестировал партии разных размеров (3,50,500,1000,5000) и обнаружил, что размер партии 500 кажется оптимальным. Обратите внимание, что независимо от того, используете ли вы метод scan_iter() или keys() , операция не является атомарной и может завершиться неудачно. ОБЯЗАТЕЛЬНО ИЗБЕГАЙТЕ ИСПОЛЬЗОВАНИЯ XARG В КОМАНДНОЙ СТРОКЕ Я не рекомендую этот пример, который я встречал где-либо еще. Это не сработает для ключей Unicode и невероятно медленно даже для умеренного количества ключей:

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

В этом примере xargs создает новый процесс redis-cli для каждого ключа! плохо. Я проверил, что этот подход в 4 раза медленнее, чем в первом примере Python, где он удалял каждый ключ один за другим, и в 20 раз медленнее, чем удаление партиями по 500.

Читайте также:  Copy Text From Input Field

Я продолжаю получать redis.exceptions.ResponseError: unknown command ‘SCAN’ при повторении r.scan_iter (). Есть идеи, почему? Я еще не нашел ответа. — person BringBackCommodore64; 13.03.2017

@ BringBackCommodore64 Ваша версия Redis слишком старая, установите новую. — person piokuc; 12.11.2017

@piokuc Ну, я не обновлял свой Redis, но ваша догадка кажется очевидной! — person BringBackCommodore64; 14.11.2017

@ BringBackCommodore64 Это не догадка. У меня была такая же проблема, обновление решило ее. Не могу вспомнить версию, которая у меня не поддерживала SCAN, но ей было несколько лет. Любая последняя версия Redis должна быть в порядке. — person piokuc; 15.11.2017

@LeiYang redis поиск позволяет использовать глобусы / подстановочные знаки. Итак, mykey *, user_ , user:. redis.io/commands/keys — person Patrick Collins; 24.01.2020

@PatrickCollins есть идеи, как передать кодек во время чтения? — person roottraveller; 17.02.2020

izip_longest был переименован в zip_longest в Python 3 stackoverflow.com/questions/38634810/ — person NealWalters; 27.10.2020

Раздел сканирования партиями здесь вводит в заблуждение. Вероятно, у вас лучшая производительность, но это не связано с получением ключей, о чем идет речь. Лучшая производительность, которая у вас есть, вероятно, связана с удалением ключей партиями, а не 1 на 1. — person scdekov; 22.12.2020

>>> import redis >>> r = redis.StrictRedis(host=YOUR_HOST, port=YOUR_PORT, db=YOUR_DB) >>> r.keys() 

Имейте в виду, что использование этой команды не рекомендуется на производственных серверах. Если у вас много ключей, ваш экземпляр Redis не ответит ни на один другой запрос во время обработки этого запроса, что может занять довольно много времени. — person Pascal Le Merrer; 08.03.2014

Рассмотрите возможность добавления ссылки на команду SCAN , поскольку теперь это предпочтительный способ получить все ключи с временной сложностью O (1) для каждого запроса. (и O (N) для всех запросов) — person Kirill Zaitsev; 08.03.2014

Читайте также:  Zakupki gov ru epz main public document view html sectionid 920

r.keys() работает довольно медленно, когда вы пытаетесь сопоставить шаблон, а не просто возвращаете все ключи. Рассмотрите возможность использования scan , как предложено в ответе ниже — person cnikolaou; 27.04.2017

@KonstantineNikolaou Я уведомил ОП, и он с радостью отказался от моего ответа, чтобы принять другой. Спасибо за сообщение, я использовал это так давно, но теперь мне не хватает внимания к теме, чтобы проверить, что лучше. — person fedorqui ‘SO stop harming’; 27.04.2017

Не используйте клавиши (). Вместо этого используйте scan (). С дополнительным преимуществом сопоставления с образцом. — person Saman Hamidi; 28.04.2021

@SorousParsa, если вы поддерживаете вариант scan() , тогда проголосуйте за другой ответ. Фактически, мой был принят, и я попросил ОП принять другой. На мой взгляд, голосование против этого как такового не совсем соответствует тому, что этот ответ бесполезен. — person fedorqui ‘SO stop harming’; 28.04.2021

@ fedorqui’SOstopharming ‘действительная точка. Я действительно проголосовал за принятый ответ. — person Saman Hamidi; 01.05.2021

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 — количество элементов внутри коллекции.

Я хотел бы добавить пример кода для ответа Патрика и других.
Здесь показаны результаты как с использованием ключей, так и с помощью метода scan_iter. И обратите внимание, что Python3 использует zip_longest вместо izip_longest. Приведенный ниже код просматривает все ключи и отображает их. Я установил размер партии в качестве переменной на 12, чтобы уменьшить результат. Я написал это, чтобы лучше понять, как работает группировка ключей.

import redis from itertools import zip_longest \# connection/building of my redisObj omitted here \# iterate a list in batches of size n def batcher(iterable, n): args = [iter(iterable)] * n return zip_longest(*args) result1 = redisObj.get("TestEN") print(result1) result2 = redisObj.get("TestES") print(result2) print("\n\nLoop through all keys:") keys = redisObj.keys('*') counter = 0 print("len(keys)=", len(keys)) for key in keys: counter +=1 print (counter, "key=" +key, " value=" + redisObj.get(key)) print("\n\nLoop through all keys in batches (using itertools)") \# in batches of 500 delete keys matching user:* counter = 0 batch_counter = 0 print("Try scan_iter:") for keybatch in batcher(redisObj.scan_iter('*'), 12): batch_counter +=1 print(batch_counter, "keybatch=", keybatch) for key in keybatch: if key != None: counter += 1 print(" ", counter, "key=" + key, " value=" + redisObj.get(key)) 
Loop through all keys: len(keys)= 2 1 key=TestES value=Ola Mundo 2 key=TestEN value=Hello World Loop through all keys in batches (using itertools) Try scan_iter: 1 keybatch= ('TestES', 'TestEN', None, None, None, None, None, None, None, None, None, None) 1 key=TestES value=Ola Mundo 2 key=TestEN value=Hello World 

Обратите внимание, что команды redis являются однопоточными, поэтому выполнение keys () может блокировать другие действия redis. См. Отличный пост, который объясняет это более подробно: Производительность SCAN и KEYS в Redis

Читайте также:  Статические классы java что это

Источник

Оцените статью