Redis cluster live reshard отказ

Мы широко используем redis-cluster в нашей производственной среде. В настоящее время у нас есть кластер из 30 узлов (15 мастеров, 15 подчиненных). Мы пытаемся увеличить кластер, для этого мы создали новые серверы и присоединили их к кластеру. пока все хорошо.

Далее - пытаемся перекроить слоты под новых мастеров. мы написали сценарий, который делает это, используя команду redis-trib reshard.

Однако миграция не выполняется на полпути (но не очень далеко от начала) с этой ошибкой: [ERR] Calling MIGRATE: ERR Target instance replied with error: BUSYKEY Target key name already exists.

Это происходит спорадически, иногда ему удается переместить некоторые слоты, прежде чем произойдет сбой, иногда сбой в первом слоте. Каждый такой сбой требует ручного исправления, что очень затрудняет выполнение операции reshard.

Мы не нашли ни конкретных примеров этого, ни идей о том, как предотвратить это, кроме миграции из-за простоя. чего мы пытаемся избежать.

Версии:
redis server 4.0.2
redis trib 3.3.3 (понижен с 4.0.2 после этой проблемы: redis cluster reshard [ERR] Calling MIGRATE: ERR Syntax error)

Нашим следующим шагом будет обновление до последней версии Redis (4.0.11), хотя мы не нашли никаких указаний в примечаниях к выпуску этой проблемы.

Надеетесь услышать, что мы делаем что-то не так и как это исправить, или redis-cluster не создан для живого ресардинга?

Спасибо


person Shlomi Sutton    schedule 31.10.2018    source источник


Ответы (1)


Я столкнулся с этой проблемой при работе с поддержкой Redis-кластеризации для нашего собственного проекта. Я обнаружил проблему с командой redis-trib reshard. Он отлично работает, если в слотах, которые переносятся с одного мастера на другой, не хранится ключ.

Но redis-5 (все еще разрабатывается, но еще не стабилен) имеет собственный `redis-cli ', который, как мне кажется, не имеет проблем с командой resharding. Только у младших версий 5 такое бывает.

Если вы посмотрите официальную документацию по redis, скажите перенастройка redis и redis cluster resharding, вы узнаете, что они делают внутри решард.

Итак, я решил проблему, выполнив эти задачи, запустив сценарий bash вместо команды redis-trib reshard.

Предположим, вы хотите перенастроить некоторые слоты с главного узла на другой главный узел. Мы назовем узел, который в настоящее время владеет хэш-слотом, исходным узлом, а узел, на который мы хотим перенести целевой узел.

Для каждого слота проделайте следующие шаги:

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

  1. Отправьте CLUSTER SETSLOT <slot> IMPORTING <source-node-id> на целевой узел, чтобы установить слот в состояние импорт.
  2. Отправьте CLUSTER SETSLOT <slot> MIGRATING <destination-node-id> на исходный узел, чтобы установить слот в состояние перенос.
  3. Получите ключи от исходного узла с помощью команды CLUSTER GETKEYSINSLOT и переместите их в целевой узел, используя следующую команду MIGRATE.

    MIGRATE target_host target_port key target_database_id timeout

    В Redis Cluster нет необходимости указывать базу данных, отличную от 0, но MIGRATE - это общая команда, которая может использоваться для других задач, не связанных с Redis Cluster.

  4. Когда процесс миграции будет окончательно завершен, используйте CLUSTER SETSLOT <slot> NODE <destination-node-id> как в исходном узле, так и в целевом узле, чтобы снова установить слот в их нормальное состояние. Эта же команда обычно отправляется всем остальным узлам, чтобы не ждать естественного распространения новой конфигурации по кластеру.

Здесь также приведен простой пример сценария bash для этого:

исходный IP: 172.17.0.5. идентификатор источника: 1f70a5107e0042a7d33a9efaf88dbdfecd78076a

IP-адрес назначения: 172.17.0.4. идентификатор-назначения: 7e428bae84697a3882ecad19bd0d13ac7ee97d02

другой главный IP: 172.17.0.7

for i in `seq 0 5460`; do
    redis-cli -c -h 172.17.0.4 cluster setslot ${i} importing 1f70a5107e0042a7d33a9efaf88dbdfecd78076a
    redis-cli -c -h 172.17.0.5 cluster setslot ${i} migrating 7e428bae84697a3882ecad19bd0d13ac7ee97d02
    while true; do
        key=`redis-cli -c -h 172.17.0.5 cluster getkeysinslot ${i} 1`
        if [ "" = "$key" ]; then
            echo "there are no key in this slot ${i}"
            break
        fi
        redis-cli -h 172.17.0.5 migrate 172.17.0.4 6379 ${key} 0 5000
    done
    redis-cli -c -h 172.17.0.5 cluster setslot ${i} node 7e428bae84697a3882ecad19bd0d13ac7ee97d02
    redis-cli -c -h 172.17.0.4 cluster setslot ${i} node 7e428bae84697a3882ecad19bd0d13ac7ee97d02
    redis-cli -c -h 172.17.0.7 cluster setslot ${i} node 7e428bae84697a3882ecad19bd0d13ac7ee97d02
done
person Shudipta Sharma    schedule 01.11.2018
comment
Это также происходит в случае redis 5 с помощью команды redis-cli для переноса некоторых слотов на новый главный и исходный узел не выполняется. - person Rishikesh Fanse; 01.06.2020
comment
На самом деле я не могу с уверенностью сказать, что этого не произойдет в случае Redis 5, но я столкнулся и решил этот способ для Redis 4 во время поддержки Redis 4 для проекта github.com/kubedb. - person Shudipta Sharma; 01.06.2020
comment
Хорошо, просто добавил, чтобы помочь другим - person Rishikesh Fanse; 01.06.2020
comment
Ответьте подробно, чтобы выяснить, в чем и где возникает проблема. Спасибо - person Rohini Choudhary; 27.11.2020