Как развернуть полноценный кластер Redis? Часть 2 | OTUS
Запланируйте обучение с выгодой в Otus!
-15% на все курсы до 22.11 Забрать скидку! →
Выбрать курс

Как развернуть полноценный кластер Redis? Часть 2

Linux_Deep_29.3_2_site-5020-cfb15a.png

Всем привет, это заключительная часть статьи, где подробно описывается развёртывание Redis-кластера. Начало смотрите здесь.

Итак, изначально было принято решение описать каждый сервис отдельно для удобного их размещения на нодах кластера. Docker-compose.yml будет выглядеть следующим образом:

 redis-master:
   image: username/redis-master:0.1
   ports:
     - mode: host
       protocol: tcp
       published: 6379
       target: 6379
   deploy:
     replicas: 1
     endpoint_mode: dnsrr
     placement:
       constraints:
         - node.labels.redis-master == true
   networks:
     redis-net:
       aliases:
         - redis-master

В данном примере описан сервис redis-master. В секции ports мы описываем какой режим сети использовать (в нашем случае host позволяет напрямую использовать сеть ноды кластера), какие порты контейнера мы выносим из контейнера.

Endpoint_mode: dnsrr означает, что мы принудительно выключаем mesh-сеть, которая по умолчанию работает в Docker swarm. Отключения mesh-сети являются крайне важным моментом в нашем сетапе. Если бы она была включена, то подключаясь к порту 6379 к любой ноде кластера, клиент был бы автоматически смаршрутизирован в любой доступный нам контейнер и не факт, что он бы подключился именно к мастеру.

Более подробно о типе сетей в Docker swarm вы можете ознакомиться по данной ссылке. Aliases — на всякий случай ещё раз указываем сетевой алиас нашего сервиса. Networks — указываем, к какой сети будет присоединен наш сервис, в данном случае к redis-net. Placement constraints позволяет нам ограничить размещение нашего сервиса, в данном случае мы используем ограничение по тегам, которые выставили ранее.

Секция, описывающая redis-slave, выглядит следующим образом:

 redis-slave-1:
   image: mrgreyves/redis-slave:0.1
   ports:
     - mode: host
       protocol: tcp
       published: 6379
       target: 6379
   deploy:
     replicas: 1
     endpoint_mode: dnsrr
     placement:
       constraints:
         - node.labels.redis-slave-1 == true
   depends_on:
     - redis-master
   networks:
     - redis-net

Основные отличия в описании redis-slave заключаются в директиве depend_on. Она позволяет указать зависимость в запуске сервисов. Slave будет запущен только после того, как запустится redis-master.

Секция, описывающая redis-sentinel:

 redis-sentinel-1:
   image: mrgreyves/redis-sentinel:0.6
   ports:
     - mode: host
       protocol: tcp
       published: 5000
       target: 5000
   deploy:
     replicas: 1
     endpoint_mode: dnsrr
     placement:
       constraints:
         - node.labels.redis-sentinel-1 == true
   depends_on:
     - redis-master
   networks:
     redis-net:

Все директивы мы уже разобрали немного ранее. И вот, настал тот торжественный момент, когда мы с вами можем запустить наш кластер. Для это воспользуемся следующей командой:

docker stack deploy --compose-file=docker-compose-v2.yml redis

--compose-file= — указываем, какой именно файл использовать. Redis — название нашего стака.

Также хочу отметить, что образы, которые мы создавали ранее, мы запушили в публичный репозиторий на docker hub. Если же вы используете приватный, необходимо использовать дополнительную опцию --with-registry-auth и не забыть перед этим залогиниться в нужном реджестри командой docker login.

Для проверки нашего стака используем команду:

docker stack services redis

Если всё прошло хорошо, то вывод будет следующим:

22222-20219-2f105b.png

Убедимся, что redis-master действительно master. Для это подключаемся любым клиентом к ноде, на которой он запущен, и воспользуемся командой INFO. Нас интересует секция Replication, если в ней указано role:master, то всё прошло хорошо.

Далее подключаемся к следующей ноде и воспользуемся аналогичной командой. Если мы видим, что role:slave, то значит, что у нас всё хорошо.

А теперь начинается самая интересная часть: мы будем ломать наш кластер и сделаем это слегка в софтовом режиме, а именно: просто удалим сервис redis-master. Для этого в docker-compose.yml просто меняем количество реплик на 0 и деплоимся.

Логи redis sentinel будут следующими:

1:X 02 Feb 10:50:58.299 * +slave slave 10.0.3.18:6379 10.0.3.18 6379 @ mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:50.291 # +sdown master mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:50.363 # +odown master mymaster 10.0.3.16 6379 #quorum 2/2
1:X 02 Feb 12:03:50.363 # +new-epoch 1
1:X 02 Feb 12:03:50.363 # +try-failover master mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:50.367 # +vote-for-leader 37e8f4093969307733548e1948c184a1a69c2552 1
1:X 02 Feb 12:03:50.374 # 289730ac61e05b7edc005c348088625db26d3983 voted for 37e8f4093969307733548e1948c184a1a69c2552 1
1:X 02 Feb 12:03:50.381 # 6428c92d37154089ce67a33123f3fd0b86afe4e6 voted for 37e8f4093969307733548e1948c184a1a69c2552 1
1:X 02 Feb 12:03:50.422 # +elected-leader master mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:50.422 # +failover-state-select-slave master mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:50.485 # +selected-slave slave 10.0.3.17:6379 10.0.3.17 6379 @ mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:50.485 * +failover-state-send-slaveof-noone slave 10.0.3.17:6379 10.0.3.17 6379 @ mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:50.549 * +failover-state-wait-promotion slave 10.0.3.17:6379 10.0.3.17 6379 @ mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:51.440 # +promoted-slave slave 10.0.3.17:6379 10.0.3.17 6379 @ mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:51.440 # +failover-state-reconf-slaves master mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:51.512 * +slave-reconf-sent slave 10.0.3.18:6379 10.0.3.18 6379 @ mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:52.447 * +slave-reconf-inprog slave 10.0.3.18:6379 10.0.3.18 6379 @ mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:52.447 * +slave-reconf-done slave 10.0.3.18:6379 10.0.3.18 6379 @ mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:52.510 # -odown master mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:52.510 # +failover-end master mymaster 10.0.3.16 6379
1:X 02 Feb 12:03:52.511 # +switch-master mymaster 10.0.3.16 6379 10.0.3.17 6379
1:X 02 Feb 12:03:52.511 * +slave slave 10.0.3.18:6379 10.0.3.18 6379 @ mymaster 10.0.3.17 6379
1:X 02 Feb 12:03:52.511 * +slave slave 10.0.3.16:6379 10.0.3.16 6379 @ mymaster 10.0.3.17 6379
1:X 02 Feb 12:03:55.563 # +sdown slave 10.0.3.16:6379 10.0.3.16 6379 @ mymaster 10.0.3.17 6379

Из них мы видим, что зафиксировано падение мастера:

+sdown master mymaster 10.0.3.16 6379

И начался выбор нового мастера, который впоследствии стал успешно выбран:

+elected-leader master mymaster 10.0.3.16 6379

После этого мы подключаемся к соседней ноде и командой INFO проверяем его роль. Если роль — master, значит переключение произошло успешно.

Полезная заметка? Напишите в комментариях!

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
1 комментарий
0

а можно как-то подключаться к swarm redis из локальной сети, так чтобы sentinel выдавал адрес мастера, как адрес ноды на которой он крутится, а не адрес контейнера? Приложение коннектится ConnectionMultiplexer.Connect("172.17.6.45:5000,serviceName=mymaster")(адрес ноды в локальной сети), запрашивает адрес мастера и получает 10.0.0.x:6379

Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто
Черная пятница в Otus! ⚡️
Скидка 15% на все курсы до 22.11 →