ElastiCache - миграция данных из t1. * / T2. * В m3. * - PullRequest
0 голосов
/ 07 сентября 2018

В настоящее время у меня есть кластер Redis с типом экземпляра cache.t2.micro

. У нет опции для автоматического резервного копирования данных Redis в s3 .тип экземпляра, а также нельзя выполнить команду BGSAVE , поскольку она ограничена, как описано здесь

Я заметил, что данные с узлов полностью удаляются, если основной узел вкластер Redis перезагружается, или версия движка Redis изменяется с более низкой на более высокую версию (т.е. с 3.x до 4.x), хотя они утверждают, что это лучшее усилие.

Также для этого создаются снимкиТип экземпляра не поддерживается, как описано здесь

Единственный вариант, о котором я могу подумать, - это использовать команду DUMP и получить сериализованную версию ключа и архива.эти данные для всех DBS и затем восстановите их обратно в новый кластер, используя команду RESTORE .Но это, вероятно, не лучший способ сделать это, так как он не масштабируется и, в конечном счете, для больших наборов данных потребуется некоторое время.

Также для ключей с включенным TTL мне придется запуститькоманда TTL, получить TTL (что является дополнительными издержками).

Но команда DUMP выдает ошибку Версия полезной нагрузки DUMP или неверная контрольная сумма , которая исключает эту опцию (Неудивительно, что эта командане ограничен)

Есть ли другой способ сделать резервную копию и восстановить в этом случае, кроме чтения всех ключей и их значения?

Спасибо.


РЕДАКТИРОВАТЬ:

Так что я знаю, что это не лучший способ сделать это, но это то, что я мог придумать.

TL; DR

Считывает все ключи и мигрирует из одного кластера в другой.

Это не должно быть проблемой для кластеров с конфигурацией.больше, чем t2. *

код:

import traceback
from redis import Redis
import itertools

def migrate_to_another_redis_node(source_node, source_node_port_no, dest_node, dest_node_port_no):
'''
migrates the keys from one redis node to the other
:param source_node: source redis node url
:param source_node_port_no: source redis node port number
:param dest_node: destination redis node url
:param dest_node_port_no: destination redis node port number
:return: True/False
'''
    try:
        total_keys_migrated = 0
        for db in range(16):
             source_redis_client = Redis(source_node, source_node_port_no, db=db)
             dest_redis_client = Redis(dest_node, dest_node_port_no, db=db)
             for key in source_redis_client.keys('*'):
                 key_type = source_redis_client.type(key).decode()
                 if key_type == 'string':
                     value = source_redis_client.get(key)
                     dest_redis_client.set(key, value)
                 elif key_type == 'list':
                     values = source_redis_client.lrange(key, 0, -1)
                     dest_redis_client.rpush(key, *values)
                 elif key_type == 'hash':
                     key_value_pairs = source_redis_client.hgetall(key)
                     dest_redis_client.hmset(key, key_value_pairs)
                 elif key_type == 'set':
                     values = source_redis_client.smembers(key)
                     dest_redis_client.sadd(key, *values)
                 elif key_type == 'zset':
                     values = list(itertools.chain(*source_redis_client.zrange(key, 0, -1, withscores=True)))
                     dest_redis_client.zadd(key, *values)
                 ttl = source_redis_client.ttl(key)
                 if ttl:
                     dest_redis_client.expire(key, ttl)
                 total_keys_migrated += 1
        print('total keys migrated is {}'.format(total_keys_migrated))
        return True
   except:
        error = traceback.format_exc()
        print(error)
   return False

Выше работает независимо от типа ключа.
Производительность: Вышеуказанное перенесено на ~ 4000 ключей за 2 секунды,

...