Thank you for reading this post, don't forget to subscribe!
Для работы с сервисами используем три домена — redis-0.test.ru для мастера, redis-1.test.ru и redis-2.test.ru для двух слейвов.
Слейв в минимальном сетапе может быть и один, но т.к. второй сетап будет с Sentinel — то создадим сразу три инстанса.
Базовая Master-Slave репликация
В этом варианте слейвы являются read-only репликами мастера, поддерживая у себя ту же информацию, которая добавляется на мастер.
Мастер шлёт на слейвы все изменения, которые выполняются в данных — записи клиентов, обновления ключей и т.д.
В случае, если связь между мастером и слейвом обрывается — слейв пытается подключиться к мастеру и выполнить частичную сихронизацию, обновив данные с того места, на котором произошёл обрыв связи.
В случае, если частичная синхронизация невозможна — слейв запрашивает у мастера полную синхронизацию. Тогда мастер создаёт полный снапшот всех имеющихся у него данных, отправляет их на слейв, а затем продолжает слать обновления в обычном режиме.
Несколько нюансов такой репликации:
- один мастер может иметь несколько слейвов
- слейвы могут принимать подключения от других слейвов, создавая таким образом «каскад» реплицированных нод — от мастера «вверху», слейвов «в середине» и слейвов «внизу»
- категорически рекомендуется использовать persistence на мастере и слейвах во избежание потери данных, см. Safety of replication when master has persistence turned off
- слейвы по умолчанию работают в read-only режиме,
Настройка Redis Master
Устанавливаем Redis:
Редактируем /etc/redis/redis.conf
, в bind
задаём прослушивание всех интерфейсов:
Можно указать IP через пробел, например:
Другие интересные тут опции:
port 6379
— понятноslave-read-only yes
— слейвы принимают запросы только на read, на мастере роли не играетrequirepass foobared
— мастер требует авторизацию с паролем foobaredappendonly yes
иappendfilename "appendonly.aof"
— уменьшаем вероятность потери последних данных, см. Redis Persistence
Перезапускаем сервис:
Проверяем, передавая с помощью опции -a
пароль:
Проверяем статус репликации:
Добавляем данные:
Получаем их:
ОК — тут всё работает.
Настройка Redis Slave
На оставшихся двух хостах выполняем настройку слейвов.
Тут всё одинаково, просто повторяем на обоих.
Устанавливаем:
Редактируем /etc/redis/redis.conf
:
Тут:
slaveof
— указываем хост и порт мастераmasterauth
— пароль для авторизации на мастереrequirepass
— пароль для авторизации на слейве
Перезапускаем:
Проверяем лог:
Коннект к мастеру есть, синхронизация прошла — окей, проверяем данные:
На слейве данные тоже есть.
Переключение Slave => Master роли
В случае, если мастер выйдет из строя — необходимо будет выполнить переключение роли слейва, что бы он стал мастером.
Если сейчас на слейве попробовать записать данные — Redis вернёт ошибку, т.к. по умолчанию слейвы находятся в read-only режиме:
Пробуем добавить данные на слейве:
Подключаемся к слейву:
Авторизируемся:
Отключаем слейв-роль:
Проверяем статус:
Добавляем новый ключ ещё раз:
Проверяем:
Учтите, что т.к. в файле настроек /etc/redis/redis.conf
всё ещё установлен параметр slaveof
— то при рестарте эта нода снова станет слейвом.
Redis Sentinel
Теперь дополним наш кластер, и добавим Redis в режиме Sentinel, который будет мониторить статус нод, и выполнять переключение ролей автоматически.
Общая схема работы будет выгядеть так:
Тут:
- M1 = Master
- R1 = Replica 1 / Slave 1
- R2 = Replica 2 / Slave 2
- S1 = Sentinel 1
- S2 = Sentinel 2
- S3 = Sentinel 3
M1 и S1 — будут на redis-0, R1 и S2 — на redis-1, R2 и S3 — на redis-2.
Запуск Sentinel
Для запуска Sentinel используем тот же Redis-сервер, но для него создадим отдельный конфиг /etc/redis/sentinel.conf
.
Добавляем его сначала на хосте с Redis Master:
Тут:
monitor
— адрес мастер-ноды, которую будем мониторить, 2 — кол-во инстансов Sentinel для принятия решенийdown-after-milliseconds
— время, после которого мастер будет считаться упавшимfailover-timeout
— время ожидания после смены ролей слейва на мастер в случае, если мастер вышел из строяparallel-syncs
— время одновременной сихронизации слейвов после переназначения роли мастера
Запускаем:
Проверяем статус Sentinel — подключаемся на порт 26379:
Тут:
master0:name=redis-test,status=ok
— мастер работаетslaves=2
— у него два слейваsentinels=1
— пока запущен только один Sentinel
Можно получить различные данные о статусе репликации.
Например — адрес текущего мастера:
Повторяем запуск Sentinel на слейвах, используя такой же конфиг, как на мастере — в логе Sentinel на мастере должны появится сообщения о новых Sentinel инстансах:
Проверяем статус ещё раз:
sentinels=3
— окей.
Кроме всего прочего — Sentinel автоматически выполняет настройку:
Тут добавился sentinel myid fdc750c7d6388a6142d9e27b68172f5846e75d8c, и целый блок после Generated by CONFIG REWRITE.
Redis Sentinel Automatic Failover
Теперь проверим что будет, если умрёт мастер.
Сделать это можно просто убив его вручную, напрмиер через kill -9
, либо с помощью redis-cli
— отправив ему команду DEBUG
и указав либо время, на которое его надо остановить, либо сигнал, от которого ему умереть ?
В логе Sentinel на мастере:
Сейчас тут особо интересны вот эти две строки:
Sentinel выполнил автоматическую перенастройку слейва в мастер.
35.158.154.25 — старый мастер, который умер, а 3.121.223.95 — новый мастер, который раньше был первым слейвом, с именем хоста redis-1.
Проверяем запись в него:
Тогда как попытка записать данные на старом мастере, который теперь стал слейвом, приведёт к ошибке:
Либо убиваем его вообще — и посмотрим, что сделает Sentinel:
Лог:
Мастер просто перезапущен.
Команды Sentinel
COMMAND | DESCRIPTION |
---|---|
sentinel masters |
список всех мастеров и их состояния |
sentinel master |
состояние конкретного мастера |
sentinel slaves |
список всех слейвов и их состояния |
sentinel sentinels |
список всех Sentinel инстансов и их состояния |
sentinel failover |
вручную запустить процесс восстановление и замены вышедшего из строя мастера |
sentinel flushconfig |
Force Sentinel to rewrite it’s configuration on disk |
sentinel monitor |
добавить новый мастер |
sentinel remove |
удалить мастер из-под наблюдения |