Настройка Redis HA на AWS с помощью sentinels — redis-узлы, которые видят разные sentinels, попадают в бесконечный цикл

#amazon-web-services #redis #devops #autoscaling #redis-sentinel

#amazon-web-services #redis #devops #автоматическое масштабирование #redis-sentinel

Вопрос:

Наша настройка

  • 3x redis sentinels по одному на каждом AWS Сидней, Аризона
  • от 2 до 500 узлов redis с ведущим и несколькими подчиненными узлами, которые автоматически масштабируются по горизонтали с помощью групповых политик автоматического масштабирования AWS
  • 1x Запись ELB, которая отправляет трафик на мастер
  • 1x Чтение ELB, которое отправляет трафик на подчиненные устройства
  • 1x ELB Sentinel, который отправляет трафик на sentinels
  • 1x Фасилитатор (подробнее об этом ниже)

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

Фасилитатор

Это созданный нами демон python, который подписывается на sentinels pub / sub и прослушивает сообщения switch-master. Вот действия, которые предпринимает координатор:

  1. Обнаруживает и управляет отказоустойчивостью, инициируемой switch-master
  2. Запрашивает sentinels для нового мастера с помощью SENTINEL get-master-addr-by-name mymaster
  3. Теги old master с RedisClusterNodeRole = slave
  4. Теги новый мастер с помощью RedisClusterNodeRole = master
  5. Добавляет новый мастер в наш ELB для записи
  6. Удаляет новый мастер из нашего ELB для чтения
  7. Удаляет старый мастер из нашего ELB для записи
  8. Пытается добавить старый мастер в наш ELB для чтения (это не удастся, если сервер не работает, что нормально)

Проблема

Поскольку подчиненные устройства могут приходить и уходить несколько раз в день в зависимости от трафика, случается, что в итоге некоторые подчиненные устройства, принадлежащие sentinels из обоих кластеров, борются за одного и того же подчиненного устройства. Это происходит потому, что пулы IP-адресов являются общими для кластеров, и, насколько нам известно, идентификаторами подчиненных устройств являются их IP-адреса.

Вот как выполнить репликацию:

  1. В кэше кластера есть мастер с IP-адресом 172.24.249.152
  2. В кэше кластера есть ведущее подчиненное устройство, обеспечивающее отказоустойчивость, с IP 172.24.246.142 для управления. Узел с IP 172.24.249.152 теперь отключен
  3. Метаданные кластера расширяются, и DHCP назначает IP 172.24.249.152 (предыдущий мастер в кэше кластера)
  4. Кэш кластера увидит, что его предыдущий мастер теперь запущен, и попытается перенастроить его как slaveof 172.24.246.142 (новый мастер в кластере кэша)
  5. Метаданные кластера вызовут sdown на 172.24.246.142, а через некоторое время -sdown, за которым последует slave-reconf-отправленный ему, чтобы попытаться перенастроить его как подчиненный для кластера метаданных
  6. Кэш кластера попытается выполнить то же самое, что и метаданные кластера в пункте 5.

Sentinels навсегда застревают в этом бесконечном цикле, борясь за этот ресурс. Это происходит даже тогда, когда у нас есть только группа sentinels, управляющая обоими кластерами redis с разными основными именами. Это наводит нас на мысль, что sentinels не знают о ресурсах между разными кластерами, а просто делают то, что логично для каждого кластера в отдельности.

Решения, которые мы пробовали

  1. Запуск SENTINEL reset mymaster события after a sdown, чтобы попытаться заставить sentinels забыть об этом узле. Проблема с этим заключается в том, что он может генерировать состояние гонки, если этот кластер выполняет основной переход на другой ресурс. Мы успешно повторили это предположение и остались с несинхронизированными sentinels, когда один указывает на один мастер, а два других указывают на другой.
  2. Разделите сеть на пулы IP-адресов, по одному на кластер. Это работает, потому что IP-адреса никогда не используются повторно, но также делает работу намного менее гибкой и более сложной, когда нам нужен новый кластер. Это решение, к которому мы пришли, но мы хотели бы избежать его, если это возможно.

Идеальное решение (ы)

  1. Redis sentinel обеспечивает SENTINEL removeslave 172.24.246.142 mymaster то, что мы можем запускать каждый раз, когда на подчиненном устройстве происходит событие sdown. Это заставит этот кластер забыть, что slave когда-либо существовал, не создавая побочных эффектов, которые SENTINEL reset mymaster имеет a .

  2. Прекратите определять уникальность подчиненных устройств исключительно по IP. Возможно, добавьте временную метку запуска сервера redis или любой другой токен, который не позволяет отключенным подчиненным устройствам и новым, которые были восстановлены с тем же IP, отображаться как один и тот же узел.

Вопрос

Ребята, можете ли вы придумать какое-либо другое решение, которое не требует изменения кода redis sentinel и не требует разделения пулов IP между кластерами?