Настройка High Availability Redis-кластер

Есть 2 сервера приложений(app01 и app02), на которых установлен Redis и Sentinel для мониторинга активного мастера и перевода одного из существующих слейв серверов в режим мастера в случае выхода со строя текущего мастера, а также перевода старого мастера в режим slave к вновь избранному мастеру.
Также есть третий сервер(advisor), на котором запущен только Sentinel. Этот сервер нужен для участия в голосовании и поддержки кворума при выборе нового мастера. Базы Redis он на себе содержать не будет.
Всего в наличие 3 сервера(не включая HAproxy)
Перед Redis-кластером будет настроен Haproxy, который будет мониторить состояние обоих Redis-серверов и направлять запросы клиентов ТОЛЬКО на текущий мастер
В коде приложения для Redis-запросов происходит подключение к HAproxy-серверу
Т.е. схема прохождения запроса будет выглядить так

Порядок настройки:
1.Установка Redis на серверах приложений (app01 и app02)
2.Настройка Master/Slave репликации из двух Redis-серверов(app01 и app02)
3.Настройка Sentinel на всех трех серверах(app01,app02,advisor)
4.Тестирование переключения мастера
5.Настройка HAproxy

 

1.Установка Redis на серверах приложений (app01 и app02)

Установка будет выполнена из исходного кода

 

2.Настройка Master/Slave репликации из двух Redis-серверов(app01 и app02)
Настройка конфигурационных файлов Redis
Master (app01)

Slave(app02)

protected-mode по умолчанию yes, который не разрешит подключение по сети, если
а) не указан точно интерфейс в опции bind
б) не установлен мастер-пароль в секции requirepass, который требует авторизоваться прежде чем получить доступ к редис(соответственно необходимо на slave добавить опцию masterauth mypassword)

В данном случае Redis был установлен с исходников, поэтому создадим Unit-файл
Создание Unit-файла для Redis для системы инициализации systemd

Для того,чтобы Redis, который запускается под пользователем redis, смог перезписать свой конфигурационный файл, изменим его владельца/группу на redis на обоих Redis-серверах, а также ограничим доcтуп к файлу /etc/redis/redis.conf только для redis пользователя/группы в целях безопаности(доступ к дамп-файлу /var/lib/redis/dump.rdb был ограничен на этапе установки Redis)

С точки зрения безопасности не обходимо ограничить доступ к Redis на уровне файрволла т.е. разрешить подключение к Redis,Sentinel-серверам только с app01,app02,advisor,HAProxy-серверов
В дополнение к ограничению на сетевом доступе можно использовать простую аутентифкиацию в Redis по паролю
(параметр requirepass в конфигурационном файле Redis)

Запускаем redis на мастере и слейве

Лог Redis на Slave-сервере

В этот момент на мастере Redis в логах

Проверка состояния репликации

На мастере выполняем

На Slave выполняем

Если необходимо вручную перевести роль мастера на новый сервер
Для того,чтобы из slave сделать мастер достаточно выполнить
На slave

И проверяем

Для автоматического перевода роли master на один из существующих slave-серверов используем Sentinel. Также Sentinel автоматически перенастраивает все остальные slave-сервера на новый мастер

 

3. Настройка Sentinel на всех трех серверах(app01,app02,advisor)

Настройка Sentinel на app01

Имя монитора master01(может быть произвольным). Это имя должно быть одинаковое на всех экземплярах Sentinel
Текущий Redis-мастер app01-сервер с адресом 192.168.100.1, кворум для голосования составляет 2 ноды Sentinel

Аутентифицируемся на Redis Master/Slave нодах по паролю

Кол-во миллисекунд, через которое мастер считается недоступным и начинается процедура голосования для выбора нового мастера

Создание Unit-файла для Sentinel на всех трех серверах

Создание необходимых каталогов/файлов, выставление на них корректных прав/владельца/группу на всех трех серверах

Запускаем Sentinel на app01

Логи Sentinel на app01

Проверяем состояние мастера через Sentinel(значение ключа role-reported)

Настройка Sentinel на app02

Запускаем Sentinel на app02

После чего как на app01 так и на app02 проверяем состояние мастера и убеждаемся в наличие уже двух sentinel-серверов(один из них, на котором выполняем саму команду)

Проверка/просмотр текущего мастера Redis

Настройка Sentinel на advisor

Запускаем Sentinel на advisor

Проверка состояния кворума кластера master01

Просмотр списка slave-серверов кластера master01

Просмотр списка master-серверов кластера master01

 

4. Тестирование переключения мастера

Выключаем redis на первом сервере(app01) и проверяем, что мастером стал второй сервер(app02)

Логи Redis на app02

Логи Sentinel на app02 сервере, который становится в этом момент текущим мастером

Из логов видно, что текущий мастер стал недоступен

Проверка наличия кол-ва нод,которые должны принять участие в выборе нового мастера – т.е кворум должен быть удовлетворен – минимум 2 ноды(из имеющихся 3-х нод с Sentinel)

Выбор нового мастера

В качестве нового мастера выбирается app02(192.168.100.2)(на нем выполняется команда slaveof-noone)
А сервер app01 переводится в режим slave(failover-state-reconf-slaves)

Переключение активного мастера с app01(192.168.100.1) на app02(192.168.100.2)

App01(192.168.100.1) сервер переводится/настраивается как slave и помечается как недоступный в данный момент

Sentinel на каждом sentinel-сервере обновляет свой конфигурационный файл sentinel.conf, указывая в нем нового мастера(192.168.100.2)

Т.е вместо строки

будет строка

А также перестраиваит все имеющиейся слейвы(в данном случае только бывший мастер 192.168.100.1,который автоматически становится слейвом) на работу c новым мастером

Путем динамического изменения конфигурационного файла sentinel.conf
Заменяя строку

на строку

А также помечает, что данный слейв пока выключен/недоступен

Как происходит автоматический перевод активного мастера в слейв, а слейв в мастер?
При переводе слейв->мастер на слейве выполняется команда

При переводе мастер->слейв на бывшем мастере выполняется команда

Т.е.

Лог Sentinel на app01

Лог sentinel на advisor

Проверка текущего мастера

App02 стал Redis-master, а app01 – Redis-slave и помечен как выключен
После включения redis на app01 он помечается как активный slave и реплицирует данные с Redis-master(app02)

Логи Redis на app01

Логи Redis на app02

Логи Sentinel на app01

Логи Sentinel на app02

Логи Sentinel на advisor

Настройка haproxy на работу с кластером

Haproxy будет проверять оба Redis-инстанса и определять текущего мастера (по наличию в ответе от Redis-сервера роли мастер expect string role:master)
И передавать запросы клиентов только текущему Redis-мастеру.
A slave-сервер буде отмечен в Haproxy как недоступный для передачи на него запросов клиентов(выброшен с кластера)
При переключении роли мастера( за этим следит и выполняет Sentinel) HAproxy начнет отправлять запросы на новый мастер, а старый мастер, который автоматически будет назначен как Slave сентинелом, будет выброшен с HAProxy-кластера автоматически.

Несколько полезных Redis-параметров связанных с репликацией

По умолчанию Redis будет запрещать запись,если последняя операция сохранения на диск закончилась неуспешно. После восстановления успешного сохранения на диск, автоматически будет разрешена запись в Redis

Если slave теряет доступ к мастеру или во время, когда репликация еще в процессе, slave может работать/действовать в одном из двух режимов
А) По умолчанию, slave все еще отвечает на запросы(команды) клиентов, возможно, отдавая уже устаревшие данные

Б)Slave отвечает на все запросы клиентов(кроме запросов типа INFO и SLAVEOF) ошибкой типа
«SYNC with master in progress»

Должен ли slave принимать запросы на запись
Начиная с версии 2.6 по умолчанию запрещено Slave-серверу принимать запросы на запись т.е.используется режим read-only

Репликация в Redis
1.Redis-репликация асинхронная. При этом можно настроить мастер, чтобы он не принимал запросы на запись, если к нему не подключено меньше, чем определенно количество slave-серверов или отставание больше или равное определенного кол-ва секунд, которое считается от последнего ping полученного от slave-сервера.
По умолчанию эта возможность отключена(min-slaves-to-write установлена в ноль, а min-slaves-max-lag в 10)
Данные опции закомментированы по умолчанию(т.е не применяются)

Также для отключения этой возможности можно установить один из параметров в значение 0
2.Redis-slave могут выполнять частичную синхронизацию/пересинхронизацию(вместо полной) с мастером, если репликация потеряна/остановлена/разломана в течение относительно небольшого периода времени. Параметры repl-backlog-size определяет размер буфера, который содержит в себе данные для slave-серверов во время того, как slave-сервера отключены от мастера.
При восстановлении связи между мастером и слейвом(когда слейв хочет переподключиться снова) может не требоваться полная ресинхронизация, а использоваться частичная ресинхронизация

Backlog выделяется один раз, как только появляется подключенный slave
Время, по истечению которого, backlog-буфер очищается определяется параметром
repl-backlog-ttl. Если необходимо никогда не очищать этот буфер, то устанавливаем значение этого параметра в ноль

3.Репликация автоматический процесс и не требует пользовательского вмешательства.
Slave будет автоматически пытаться подключиться к мастери синхронизироваться с ним.

Если мастер защищен паролем(на мастере установлен параметр requirepass), то для успешной синхронизации Slave должен аутентифицироваться у мастера, иначе мастер откажет слейву в его запросах.

Стратегии репликации в Redis
1.Disk-backed
Redis-мастер создает новый процесс, который записывает redis базу данных (RDB) на диск в виде файла . Затем этот файл передается на slave-сервера инкрементально.
2.Diskless
Является экспериментальной в данный момент
Redis-мастер создает новый процесс, который напрямую записывает RDB-файл в Slave-сокет без использования диска вообще

При Disk-backed репликации, пока RDB-файл создается/генерируется больше slave-серверов могут быть поставлены в очередь и обслужены сразу после того, как завершится дочерний процесс Redis-мастера, который создает RDB-файл для slave-серверов

При Diskless репликации, наоборот, если запущен один процесс передачи данных(синхронизации), то все вновь прибывшие slave-сервера становятся в очередь и их запросы будут обработаны после того, как закончится выполнения передачи данных текущего(запущенного) slave-сервера
При этом мастер будет ожидать определенное в параметре repl-diskless-sync-delay кол-во времени перед началом передачи данных в надежде на то, что несколько slave-серверов подключатся к нему для репликации, и RDB-передача может быть параллельной на несколько slave-серверов.
Если необходимо отключить такую задержку, то выставляем значение параметра repl-diskless-sync-delay в ноль
На медленных дисках и сетях с высокой пропусной способностью Diskless репликация работает быстрее

Слейвы посылают PING-запросы на мастер с интервалом, определенным в параметре repl-ping-slave-period

Установка таймаута репликации — используется сразу для трех состояний
Мастер недоступен с точки зрения Slave-сервера(нет передачи данных, ответа на ping-запрос)
Слейв недоступен с точки зрения мастера(REPLCONF, ACK пинги)
Массовая передача ввода/вывода в течение SYNC с точки зрения slave-сервера

Приоритет slave-сервера

Целочисленное значение,используемое Redis Sentinel для выбора нового мастера из существующих slave-серверов, когда текущий мастер не работает корректно.
Чем ниже значение приоритета, тем более предпочтительнее этот slave-сервер станет мастером(Например, из slave-серверов с приоритетом 10,25,100 Sentinel в качестве мастера выбирает сервер с приоритетом 10)
Если не обходимо, чтобы Slave-сервер никогда не стал мастером,то значение параметра
slave-priority необходимо установить в ноль

 

Redis CLI плезные команды
справка

Проверка доступности Redis-сервера

Очистка терминала

Просмотр команд и данных которые мастер посылает на slave в потоке репликации

Очистка всех ключей со всех баз данных

Просмотр Redis-статистики

По умолчанию частота просмотра каждую секунду
Изменить на частоту просмотра каждые 3 секунды

Сканирование больших ключем

Получение списка ключей

Получение списка ключей определенного шаблона

Монитоинг команд выполняемых в Redis

Мониторинг латенции Redis(время укаазно в миллисекундах)

Проверка максимальной и среднего значеия латенции

Просмотр латенции сервера(планироващика ядра, гипервизора, в случае использования виртуализации),на котором запускается Redis
Команду нужно выполнять на сервере, на котором запущен Redis
Например, запускать тест в течение 10 секунд

Проверка целостности Redis-базы данных

Создание бекапа/дампа базы Redis

Для того,чтобы обеспечить цолостность/консистентность данных при создании дампа базы Redis необходимо перед создание дампа выполнит команду SAVE, чтобы сбросит все данные,содержащиеся в памяти на диск
т.е.

Команда по выключению Redis-сервера SHUTDOWN, автоматически сохраняет данные с памяти на диск

Просмотр команд и данных которые мастер посылает на slave в потоке репликации

Выполнение симуляции LRU
Например, в конфиге Redis установлен лимит в 128Mb оперативной памяти для кеша Redis и политика очистки ключей – все ключи наименее используемые

Специальный тест выполняет GET и SET запросы с политикой 20% ключей будет запрошено 80% всех запросов. Кол-во ключей 10млн

Коэффициент пропущенных ключей состаляет около 44%, что достаточно много.Поэтому есть смысл увеличить размер оперативной памяти выделяемой под кеш Redis, например, до 512 Mb

После увеличения памяти с 128 до 512 Mb, коэффициент пропущенных ключей снизился до 4%

Источник:

https://redis.io/topics/sentinel
https://seanmcgary.com/posts/how-to-build-a-fault-tolerant-redis-cluster-with-sentinel
https://discuss.pivotal.io/hc/en-us/articles/205309388-How-to-setup-HAProxy-and-Redis-Sentinel-for-automatic-failover-between-Redis-Master-and-Slave-servers
https://discuss.pivotal.io/hc/en-us/articles/205309278-How-to-setup-Redis-Master-and-Salve-replication
https://redis.io/topics/rediscli
http://www.linux-admins.net/2014/09/deploying-haproxy-15-from-source.html

Комментирование и размещение ссылок запрещено.

Комментарии закрыты.

Яндекс.Метрика