[Перед боем] Удалите 4000W KEYs из Redis с помощью Python

Redis задняя часть база данных Python
В этой статье в основном рассматриваются следующие две операции Redis и его реализация Python, каталог:
  • СКАНИРОВАНИЕ команда
  • команда УДАЛ
  • Использование СКАНИРОВАНИЯ Python
  • Использование Python DEL
  • Дисплей достижений

СКАНИРОВАНИЕ команда

Команда SCAN и связанные с ней команды SSCAN, HSCAN и ZSCAN используются для постепенного перебора набора элементов:
  • SCAN используется для перебора ключей базы данных в текущей базе данных.
  • SSCAN используется для перебора элементов в ключе коллекции.
  • HSCAN используется для перебора пар ключ-значение в хеш-ключах.
  • ZSCAN используется для перебора элементов в отсортированном наборе (включая оценки элементов и оценки элементов).
Вышеуказанные четыре столбца команд поддерживают инкрементную итерацию, каждое выполнение возвращает небольшое количество элементов, поэтому все они могут использоваться в производственных средах, не похожие на команды KEYS, SMEMBERS, которые могут заблокировать сервер.

Однако команды инкрементной итерации не лишены недостатков:
Например, с помощью команды SMEMBERS можно вернуть все элементы, содержащиеся в данный момент в заданном ключе, но для команд инкрементной итерации, таких как SCAN, поскольку ключ может быть изменен во время инкрементной итерации ключа кучи, инкрементная команда может предложить только ограниченные гарантии на возвращаемые элементы.

Поскольку команды scan, sscan, hscan и zscan очень похожи, следует помнить:
  • Первым параметром команд SSCAN, HSCAN и ZSCAN всегда является ключ базы данных;
  • Команде SCAN не требуются никакие ключи базы данных в первом аргументе — она перебирает все ключи базы данных в текущей базе данных.

Основное использование команды SCAN
Команда SCAN представляет собой итератор на основе курсора:
Каждый раз, когда вызывается команда SCAN, пользователю будет возвращен новый курсор, и пользователю необходимо использовать этот новый курсор в качестве параметра курсора команды SCAN в следующей итерации, чтобы продолжить предыдущий процесс итерации.
Когда параметр курсора команды SCAN установлен в 0, сервер начинает новую итерацию, а когда сервер возвращает пользователю курсор со значением 0, итерация заканчивается.
Пример:
redis 127.0.0.1:6379> scan 0
1) "17"
2)  1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
    10) "key:7"
    11) "key:1"

redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"
В приведенном выше примере первая итерация использует 0 в качестве курсора для запуска первой итерации.
Вторая итерация использует курсор, возвращенный на первой итерации, то есть: 17.
Как видно из примера, возвращаемое значение команды SCAN представляет собой двухэлементный массив, первый элемент — новый курсор, а второй элемент — также массив, содержащий содержащиеся элементы.
При втором вызове команды SCAN возвращается курсор 0, что означает завершение итерации и полный обход всей коллекции.
Этот процесс называется полной итерацией.

Чтобы упростить содержание, добавьте три пункта:
  1. Поскольку команда SCAN использует курсор только для записи статуса итерации, во время процесса итерации, если элементы набора данных увеличиваются или уменьшаются, если он уменьшается, не гарантируется, что элемент не будет возвращен; увеличено, его возврат не гарантируется; в этом случае один и тот же элемент может быть возвращен несколько раз. Таким образом, операция, выполняемая над элементами, возвращаемыми итерацией, предпочтительно может повторяться много раз (идемпотент).
  2. Команда инкрементной итерации не гарантирует количество элементов, возвращаемых каждой итерацией (не просканированных), но мы можем использовать параметр COUNT, чтобы в определенной степени настроить поведение команды. Значение параметра COUNT по умолчанию равно 10. При повторении достаточно большой базы данных, заданного ключа, хеш-ключа или отсортированного заданного ключа, реализованного хэш-таблицей, если пользователь не использует параметр ПОИСКПОЗ, число, возвращаемое командой, равно обычно то же, что и Опция COUNT указывает то же самое или немного больше (😓), закодированное как целочисленный набор (intset: небольшой набор целочисленных значений) или закодированный как сжатый список (ziplist: небольшой хэш различных значений) или небольшой отсортированный набор), он проигнорирует значение, заданное параметром COUNT, и вернет все элементы набора данных пользователю на первой итерации.
  3. Вариант ПОИСКПОЗ, просто посмотрите на пример, как показано ниже
Пример:
redis 127.0.0.1:6379> sadd myset 1 2 3 foo foobar feelsgood
(integer) 6

redis 127.0.0.1:6379> sscan myset 0 match f*
1) "0"
2) 1) "foo"
   2) "feelsgood"
   3) "foobar"
Примечание. Работа по сопоставлению с образцом для элементов выполняется после того, как команда извлекает элементы из набора данных, и перед возвратом элементов клиенту, поэтому можно вернуть пустые значения.
Пример:
redis 127.0.0.1:6379> scan 0 MATCH *11*
1) "288"
2) 1) "key:911"

redis 127.0.0.1:6379> scan 288 MATCH *11*
1) "224"
2) (empty list or set)

redis 127.0.0.1:6379> scan 224 MATCH *11*
1) "80"
2) (empty list or set)

redis 127.0.0.1:6379> scan 80 MATCH *11*
1) "176"
2) (empty list or set)

redis 127.0.0.1:6379> scan 176 MATCH *11* COUNT 1000
1) "0"
2)  1) "key:611"
    2) "key:711"
    3) "key:118"
    4) "key:117"
    5) "key:311"
    6) "key:112"
    7) "key:111"
    8) "key:110"
    9) "key:113"
   10) "key:211"
   11) "key:411"
   12) "key:115"
   13) "key:116"
   14) "key:114"
   15) "key:119"
   16) "key:811"
   17) "key:511"
   18) "key:11"
Примечание. Для последней итерации указание 1000 с параметром COUNT заставляет команду сканировать больше элементов для этой итерации, таким образом возвращая больше элементов.

команда УДАЛ

Это относительно просто, удалить заданный один или несколько ключей
redis> SET name "redis"
OK
redis> SET type "key-value store"
OK
redis> SET website "redis.com"
OK
redis> DEL name type website
(integer) 3

Использование СКАНИРОВАНИЯ Python

Установите пакет Redis
pip install redis
Полный пример кода:
import redis

pool=redis.ConnectionPool(host='redis_hostname', port=6379, max_connections=100)
r = redis.StrictRedis(connection_pool=pool)

cursor_number, keys = r.execute_command('scan', 0, "count", 200000)

while True:
    if cursor_number == 0:
        # 结束一次完整的比遍历
        break
    cursor_number, keys = r.execute_command('scan', cursor_number, "count", 200000)
    # do something with keys

Сохраняю удаляемый ключ в файл, там 2.2Г, около 4000Вт, следующий шаг удалить

Использование Python DEL

Поскольку файл очень большой, мы используем небольшую хитрость, чтобы читать по частям.
with open("/data/rediskeys") as kf:
    lines = kf.readlines(1024*1024)
При вызове метода удаления небольшая хитрость — звездочка «*»
r.delete(*taskkey_list)
Давайте посмотрим на определение, чтобы было понятно:
delete method
Поместите полный код:
import redis
import time

pool=redis.ConnectionPool(host='redis_hostname', port=6379, max_connections=100)
r = redis.StrictRedis(connection_pool=pool)

start_time = time.time()
SUCCESS_DELETED = 0

with open("/data/rediskeys") as kf:
    while True:
        lines = kf.readlines(1024*1024)
        if not lines:
            break
        else:
            taskkey_list = [i.strip() for i in lines if i.startswith("UCS:TASKKEY")]
            SUCCESS_DELETED += r.delete(*taskkey_list)

        print SUCCESS_DELETED

end_time = time.time()
print end_time - start_time, SUCCESS_DELETED

Дисплей достижений

Все кончено, увидимся в следующий раз