Използвайте scan_iter()
scan_iter()
е по-добър от keys()
за голям брой ключове, защото ви дава итератор, който можете да използвате, вместо да се опитвате да заредите всички ключове в паметта.
Имах 1B записи в моя redis и никога не можах да получа достатъчно памет, за да върна всички ключове наведнъж.
СКАНИРАНЕ НА КЛЮЧОВЕ ЕДИН ПО ЕДИН
Ето фрагмент на 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()
метод, операцията не е атомна и може да се провали частично.
КАТЕГИЧНО ИЗБЯГВАЙТЕ ИЗПОЛЗВАНЕТО НА XARGS В КОМАНДНИЯ ред
Не препоръчвам този пример, който намерих повторен другаде. Ще се провали за уникод ключове и е невероятно бавен дори за умерен брой ключове:
redis-cli --raw keys "user:*"| xargs redis-cli del
В този пример xargs създава нов redis-cli процес за всеки ключ! това е лошо.
Сравних този подход, за да бъде 4 пъти по-бавен от първия пример на python, където изтрива всеки ключ един по един и 20 пъти по-бавен от изтриването на партиди от 500.