Я сталкивался с такой проблемой при работе с поддержкой redis-clustering для нашего собственного проекта. Я обнаружил проблему с командой redis-trib reshard
. Он работает нормально, если в слотах, которые мигрируют с одного мастера на другой, нет ключей.
Но у redis-5 (все еще развивающегося, еще не стабильного) есть свой
'redis-cli', у которого нет проблем с переносом команд, я думаю. Только для младших версий 5 это происходит.
Если вы посмотрите на официальные документы для redis, скажем, redisconfiguration и redis cluster reharding , вы найдете то, что они делают внутренне для повторной передачи.
Поэтому я решил эту проблему, выполнив эти задачи, запустив сценарий bash вместо команды redis-trib reshard
.
Предположим, вы хотите переназначить некоторые слоты от главного узла к другому главному узлу. Мы назовем узел с текущим владельцем хеш-слота исходный узел , а узел, на который мы хотим перенести целевой узел .
Для каждого слота выполните следующие шаги:
Помните, что порядок этих шагов здесь важен согласно официальным документам Redis.
- Отправьте
CLUSTER SETSLOT <slot> IMPORTING <source-node-id>
на узел назначения , чтобы установить слот на , импортируя состояние.
- Отправьте
CLUSTER SETSLOT <slot> MIGRATING <destination-node-id>
на исходный узел , чтобы установить слот в мигрирующее состояние.
Получите ключи из исходного узла с помощью команды CLUSTER GETKEYSINSLOT и переместите их в целевой узел , используя следующую команду MIGRATE команда.
MIGRATE target_host target_port key target_database_id timeout
В Redis Cluster нет необходимости указывать базу данных, отличную от 0, но MIGRATE - это общая команда, которая может использоваться для других задач, не связанных с Redis Cluster.
- Когда процесс миграции окончательно завершится, используйте
CLUSTER SETSLOT <slot> NODE <destination-node-id>
в обоих исходных узлах и целевых узлах , чтобы снова установить для слота их нормальное состояние. Эта же команда обычно отправляется всем остальным узлам, чтобы избежать ожидания естественного распространения новой конфигурации по кластеру.
Простой пример сценария bash для этого также приведен здесь:
source-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