Featured image of post Redis Migration Script

Redis Migration Script

Скрипт для миграции Redis баз между серверами

Старый способ

Иногда нужно мигрировать данные из одного Redis в другой, или между базами другого. Ранее, я мог перенести данные с сервера на сервер только через полный бекап, но это не позволяет мигрировать данные между базами. Всё равно, приведу здесь этот алгоритм.

  1. Зайти в исходный Redis и сделать Save
1
2
3
REDISCLI_AUTH="password" 
redis-cli CONFIG GET DIR
redis-cli SAVE

Первая команда выведет путь к папке, где будет лежать дамп.

  1. Добавить к целевому Redis аргументы для отключения AppendOnly и перезапустить его
1
2
--dbfilename dump.rdb
--appendonly no
  1. Скопировать дамп в целевой Redis и выполнить его загрузку
1
2
REDISCLI_AUTH="password" 
redis-cli BGREWRITEAOF
  1. Перевести целевой Redis в AppendOnly режим убрав ранее добавленные ключи

Зачем мигрировать данные между базами?

В старом кластере у меня два сервиса, у каждого свой Redis. В любом Redis есть по умолчанию 16 баз, почему бы не использовать №0 для сервиса А и №2 - для сервиса Б? Вот тут то ты и сталкиваешься с задачей миграции из базы в базу.

Новый способ

Основан на MIGRATE. Скрипт представлен ниже. Преимущества этого способа - тоже.

  1. Можно мигрировать между базами
  2. Не нужно перезапускать Redis-ы
  3. Не нужно копировать бекапы
  4. Есть проверка после переноса путём вычисления хеш суммы учитывая так же и содержимое ключей
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/env sh
set -e

SRC_HOSTNAME='source-redis-hostname'
SRC_PORT='6379'
SRC_PASSWORD='password'
SRC_DATABASE='0'
DEST_HOSTNAME='destination-redis-hostname'
DEST_PORT='6379'
DEST_PASSWORD='password'
DEST_DATABASE='1'

main() {
  migrate | xargs -0 printf 'migration status: %s'
  CHECKSUM="$(mktemp)"
  hash --no-auth-warning -h "${SRC_HOSTNAME}" -p "${SRC_PORT}" \
    -a "${SRC_PASSWORD}" -n "${SRC_DATABASE}" | tee "${CHECKSUM}" | xargs -0 printf 'source checksum: %s'
  CHECKSUM_VERIFY="${CHECKSUM}" hash --no-auth-warning -h "${DEST_HOSTNAME}" -p "${DEST_PORT}" \
    -a "${DEST_PASSWORD}" -n "${DEST_DATABASE}" | xargs -0 printf 'target checksum validation: %s'
  rm -f "${CHECKSUM}"
}

hash() {
  EXTRA_ARGS="${@}"
  redis-cli ${EXTRA_ARGS} --raw --scan | \
  sed -r 's/"/\\"/g; s/^(.+)$/GET "\1"/g;' | \
  redis-cli ${EXTRA_ARGS} | sort | \
  if [ -f "${CHECKSUM_VERIFY}" ]; then
    sha256sum -c "${CHECKSUM_VERIFY}"
  else
    sha256sum -
  fi
}

migrate() {
  AUTH="--no-auth-warning -h ${SRC_HOSTNAME} -p ${SRC_PORT} -a ${SRC_PASSWORD} -n ${SRC_DATABASE}"
  redis-cli ${AUTH} --raw --scan | \
  tr '\n' '\0' | \
  xargs -0 redis-cli ${AUTH} \
    MIGRATE "${DEST_HOSTNAME}" "${DEST_PORT}" "" "${DEST_DATABASE}" 5000 \
    COPY REPLACE AUTH "${DEST_PASSWORD}" KEYS
}

main
Licensed under Apache License, Version 2.0
Обновлено Dec 01, 2023 14:46 +0200
All rights reserved
Создано при помощи Hugo
Тема Stack, дизайн Jimmy