Запуск Apache ZooKeeper в кластере

Сервис Apache ZooKeeper применяется в качестве сервера метаданных и конфигураций сервисов и часто используется для реализации механизма поиска сервисов (Service Discovery). Например, в Apache Kafka, популярном инструменте для организации обмена сообщениями в распределенных системах, до версии 4.0 ZooKeeper может использоваться в качестве хранилища метаданных кластера. Как и любой другой компонент распределённой системы ZooKeeper желательно запускать в кластере для обеспечения отказоустойчивости системы, чему посвящена данная статья.

Я преднамеренно вынес тему запуска ZooKeeper в отдельную статью, так как из Apache Kafka поддержка ZooKeeper будет удалена с релизом версии 4.0, но ZooKeeper может использоваться и в других ваших проектах.

Установка и запуск ZooKeeper

Для начала работы с ZooKeeper нужно скачать дистрибутив с официального сайта проекта. Скачайте и распакуйте архив с ZooKeeper в любую удобную для вас директорию. Для запуска достаточно скопировать шаблон файла настроек conf/zoo_sample.cfg в conf/zoo.cfg и выполнить следующую команду:

По умолчанию в ZooKeeper включён интерфейс администратора, и после запуска вы можете открыть в браузере страницу http://localhost:8080/commands для доступа к командам.

Если посмотреть на файл конфигурации, то он достаточно простой:

Локальный кластер ZooKeeper

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

  • Создать директорию данных для каждого сервиса
  • В директории данных каждого сервиса создать файл myid с уникальным идентификатором сервиса (от 0 до 255)
  • Создать копию директории conf для каждого сервиса и добавить в zoo.cfg список сервисов, входящих в кластер

Описание сервиса выглядит следующим образом: server.{id}={host}:{quorum_port}:{leader_election_port}{;client_port}, ниже приведён для наглядности файл настроек первого сервиса:

conf/i1/zoo.cfg

Порт для клиентских соединений можно указывать как в свойстве clientPort, так и в конце server, отделяя его при помощи ;. Сервис использует запись server со своим идентификатором для определения, какие порты он должен прослушивать для обмена данными кворума (2888) и выбора лидера (3888). Остальные записи server используются для взаимодействия с другими сервисами.

Конечно же, узлы кластера лучше разворачивать на отдельных физических или виртуальных серверах, а в последнем случае желательно, чтобы виртуальные серверы были расположены на разных физических.

Файлы настроек двух остальных сервисов будут аналогичны:

conf/i2/zoo.cfg

conf/i3/zoo.cfg

Теперь нужно запустить все три экземпляра командами:

Теперь можно проверить состояние участников кворума, отправив команды stat или srvr при помощи nc или telnet:

Сервис, являющийся лидером кворума, в Mode будет иметь значение leader, остальные — follower.

Кластер ZooKeeper в Docker

Для запуска ZooKeeper в контейнерах доступен официальный образ zookeeper. Настроить сервис можно как файлом свойств, который должен быть смонтирован в /conf/zoo.cfg, так и при помощи переменных окружения.

Переменные окружения начинаются с префикса ZOO_ и повторяют свойства из файла свойств в верхнем регистре и знаком _ для разделения слов, например 4lw.commands.whitelist соответствует переменная окружения ZOO_4LW_COMMANDS_WHITELIST. Идентификатор сервиса указывается при помощи переменной ZOO_MY_ID, а список сервисов — при помощи ZOO_SERVERS.

Пример запуска кворума ZooKeeper из трёх экземпляров в Docker:

Для межсервисного взаимодействия я использовал в этом примере ip-адрес хост-системы 172.17.0.1, если у вас он отличается, то замените адрес на свой.

В Docker Compose кворум ZooKeeper будет выглядеть следующим образом: