Thank you for reading this post, don't forget to subscribe!
Zookeeper — cервис-координатор, который позволяет обеспечить контроль синхронизации данных. Разработан на Java компанией Apache Software Foundation.
Как правило, Zookeeper используют для:
Создания распределенного сервера имен.
Определения лидера в других кластерных системах.
Создания распределенной конфигурации других приложений (например, Kafka, ClickHouse).
Приложение является открытым и может быть загружено с официального сайта.
Архитектурно, Zookeeper представляет клиент-серверное приложение и включает в себя следующие компоненты:
- Клиент — узел в кластере, который находится на связи с сервером, постоянно отправляя ему сигналы о своей работоспособности (heartbeat), который не должен превышать определенное значение (определяется параметром tickTime).
- Сервер — одна из нод кластера Zookeeper, которая проверяет состояние клиентов и перенаправляет запросы на один из рабочих серверов (клиентов).
- Лидер — главный сервер среди серверов кластера (ансамбля). Он отвечает за все операции записи.
- Последователь — все серверы в ансамбле, за исключением лидера. Они принимают от последнего информацию на изменение и записывают ее у себя.
- Ансамбль — кластер из серверов Zookeeper. Лидер определяется при старте служб, а если происходит разрыв соединения — на основе кворума. Поэтому минимальное количество нод в ансамбле является 3-м.
Для своей работы использует порты:
Приложение по умолчанию работает на следующих портах:
Порт | Описание |
---|---|
2181 | Порт для клиентских подключений. |
2888 | Репликация данных между нодами кластера. |
3888 | Выбор лидера между нодами кластера. |
В качестве альтернатив выделяют:
- etcd
- Consul
Подготовка системы
На всех трех нодах выполняем следующие действия.
1. Настройка времени
Нам важно, чтобы на нодах нашего кластера было одинаковое время. Для этого установим утилиту chrony:
yum install chrony
Запустим ее и разрешим автозапуск:
systemctl enable chronyd --now
2. Установка OpenJava
Zookeeper разработан на Java, поэтому выполним установку:
yum install java-11-openjdk
Смотрим версию openjdk:
java -version
Мы должны увидеть что-то на подобие:
openjdk version "11.0.13" 2021-10-19 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.13+8-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.13+8-LTS, mixed mode, sharing)
Идем дальше.
3. Настройка безопасности
Для корректной работы приложения нам нужно отключить SELinux и открыть порты в брандмауэре. Рассмотрим процессы по очереди.
Отключаем SELinux.
Выполним 2 команды:
setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config
Настройка брандмауэра.
Для работы Zookeeper требуется открыть порты:
- 2181 — для клиентских подключений.
- 2888 — репликация данных между нодами кластера.
- 3888 — выбор лидера между нодами кластера.
Для открытия портов вводим:
firewall-cmd --permanent --add-port={2181,2888,3888}/tcp
Применяем настройки:
firewall-cmd --reload
4. Установка дополнительных пакетов
Для корректной загрузки и распаковки архива, нам нужно установить некоторые утилиты и обновить корневые сертификаты. Это делается командами:
yum install ca-certificates wget tar nc
update-ca-trust
* где:
- ca-certificates — набор корневых сертификатов.
- wget — утилита для загрузки файлов по сети.
- tar — утилита для работы с архивами.
- nc — сетевая утилита, которая считывает и записывает данные из командной строки. Мы ее будем использовать для отправки команд в zookeeper.
Переходим к установке Zookeeper.
Установка, настройка и запуск Zookeeper
Установку с настройкой также будем делать на всех серверах. Так как в репозитории данного программного продукта нет, мы должны будем скачать архив релиза с сайта разработчика и распаковать его на сервере. Запуск приложения будет настроен с использованием systemd.
Установка
Как было сказано выше, установка выполняется путем распаковки архива, скачанного с официального сайта. Переходим на страницу загрузки Zookeeper. Кликаем по ссылке для перехода к последней версии Zookeeper:
Копируем ссылку для загрузки архива tar gz:
Используя скопированную ссылку, загружаем архив на все три сервера:
https://dlcdn.apache.org/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz
Создаем каталог для размещения zookeeper:
mkdir /opt/zookeeper
Распаковываем скачанный архив:
tar zxvf apache-zookeeper-*-bin.tar.gz -C /opt/zookeeper --strip-components=1
Настройка
Создаем дополнительные каталоги для логов и данных:
mkdir -p /opt/zookeeper/data /var/log/zookeeper
Создаем конфигурационный файл:
vi /opt/zookeeper/conf/zoo.cfg
1 2 3 4 5 6 7 8 9 10 11 12 |
tickTime = 2000 maxSessionTimeout = 50000 syncLimit = 5 initLimit = 300 autopurge.purgeInterval = 1 autopurge.snapRetainCount = 5 snapCount = 200000 clientPort = 2181 maxClientCnxns = 100 4lw.commands.whitelist=stat dataDir = /opt/zookeeper/data dataLogDir = /var/log/zookeeper |
* где:
- tickTime — длина тика в миллисекундах. Тик является базовой единицей времени в Zookeeper, относительно которого ведутся другие расчеты.
- maxSessionTimeout — время в миллисекундах, отведенное для взаимодействия сервера с клиентом.
- syncLimit — время в тиках, в течение которого подключенные клиенты должны синхронизировать данные. При превышении этого времени, клиент будет отброшен.
- initLimit — количество времени в тиках, которое отведено на подключение к серверу и выполнение синхронизации с ним.
- autopurge.purgeInterval — указываем интервал в часах для автоматической чистки.
- autopurge.snapRetainCount — количество последних снимков, которые нужно сохранить при выполнении автоматической чистки.
snapCount — количество записей в журнале транзакций, после которого будет запущен снимок с обнулением журнала. - clientPort — порт, на котором наше приложение будет слушать запросы клиентов.
- maxClientCnxns — число одновременных соединений, которое может сделать клиент.
- 4lw.commands.whitelist — список разрешенных команд через запятую. Данные команды можно будет отправить через telnet. В данном примере это команда для отображения статуса работы приложения.
- dataDir — путь для хранения снимков журналов базы данных.
- dataLogDir — путь, по которому zookeeper будет хранить журналы транзакций. Если не указан, то храниться будет в dataDir.
Настройка запуска
После установки приложения, настроим его запуск в качестве сервиса.
Создаем служебную учетную запись, под которой будет работать zookeeper:
useradd -r -c 'Zookeeper service' zookeeper
Зададим владельцем созданного пользователя для всех каталогов, которые мы создали:
chown -R zookeeper:zookeeper /opt/zookeeper /var/log/zookeeper
Создаем файл для юнита в systemd:
vi /etc/systemd/system/zookeeper.service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[Unit] Description=ZooKeeper Service Documentation=https://zookeeper.apache.org/ Requires=network.target After=network.target [Service] Type=forking User=zookeeper Group=zookeeper WorkingDirectory=/opt/zookeeper ExecStart=/opt/zookeeper/bin/zkServer.sh start ExecStop=/opt/zookeeper/bin/zkServer.sh stop ExecReload=/opt/zookeeperbin/zkServer.sh restart TimeoutSec=30 Restart=on-failure [Install] WantedBy=default.target |
Перечитываем конфигурацию systemd:
systemctl daemon-reload
Разрешаем автозапуск и стразу стартуем сервис:
systemctl enable zookeeper --now
Проверяем, что сервис запустился:
systemctl status zookeeper
Также можно убедиться, что приложение слушает на порту 2181:
ss -tunlp | grep :2181
Мы должны увидеть что-то на подобие:
tcp LISTEN 0 50 *:2181 *:* users:(("java",pid=2945,fd=51))
Настройка кластера
И так, мы установили и запустили приложение, но сейчас оно работает отдельно на наших серверах. Сделаем кластер.
На всех серверах открываем конфигурационный файл:
vi /opt/zookeeper/conf/zoo.cfg
Добавим строку:
…
dynamicConfigFile=/opt/zookeeper/conf/zoo.cfg.dynamic
* dynamicConfigFile указывает путь до динамического файла конфигурации, в котором могут меняться параметры "на лету".
Теперь создадим файл динамической конфигурации:
vi /opt/zookeeper/conf/zoo.cfg.dynamic
1 2 3 |
server.1=192.168.1.10:2888:3888 server.2=192.168.1.20:2888:3888 server.3=192.168.1.30:2888:3888 |
* как и говорилось в начале, у нас в кластере будет три сервера. В данном файле мы их перечисляем с присваиванием порядковых номеров.
Теперь на каждом сервере создаем свой файл со своим порядковым номером.
а) на сервере 1:
vi /opt/zookeeper/data/myid
1
б) на сервере 2:
vi /opt/zookeeper/data/myid
2
в) на сервере 3:
vi /opt/zookeeper/data/myid
3
Настройка завершена.
Перезапускаем наш сервис на всех серверах:
systemctl restart zookeeper
Для проверки состояния кластера вводим команды на всех нодах:
echo "stat" | nc localhost 2181
На двух из них мы должны увидеть:
…
Mode: follower
…
На одной:
…
Mode: leader
…