Привет всем Хабр-читателям. Про развертывание и настройку HA кластера PostgreSQL с помощью Patroni написано много полезных статей, однако я не нашел описания алгоритма его работы. В этой статье я хочу поделиться своим исследованием по данному вопросу.
1) Настройка Patroni
Вкратце напомню, что конфигурационный файл состоит из нескольких блоков:
описание: scope (имя кластера), namespace (имя директории хранилища конфигурации, где Patroni будет хранить информацию о кластере), name (имя узла кластера);
блок «log»: настройки логирования;
блок «restapi»: настройки REST API Patroni;
блок «dcs»: настройки распределенного хранилища конфигураций (Distributed Configuration Store -–DCS);
блок «raft»: настройки для алгоритма RAFT (как правило используется DCS);
блок «bootstrap» в котором указываются динамические настройки, которые будут сохранены в DCS при инициализации кластера;
блок «postgresql» в котором указываются настройки для PostgreSQL;
- блок «watchdog»: настройки watchdog (для работы требуется: chown postgres:postgres /dev/watchdog);
блок «tags» настройка тегов для узла кластера
2) Инициализация кластера
Во время инициализации в DCS создаётся директория: /<namespace>/<scope>/ (пример: /service/postgresql-cluster/)
В указанной директории создается следующая структура ключей:
|- members (директория с описанием узлов кластера)
| |- описание узла (имя, настройки подключения PostgreSQL, настройки | Patroni, статус, роль, версия Patroni, значение xlog, значение timeline, | значение ttl-ключа)
| |- …
|- config (динамическая конфигурация для кластера)
|- failover
|- history (история switchover и failover)
|- initialize (уникальный номер для данного кластера)
|- leader (узел являющий лидером и его ttl-ключ)
|- status (время uptime)
3) Запуск Patroni
В начале Patroni:
проверяет доступность DCS;
запускает PostgreSQL;
из файла конфигурации считываются параметры локальной конфигурации;
проверяет DCS на наличие директории (параметр «namespace»);
проверяет DCS на наличие директории с именем кластера (параметр «scope»);
если в DCS нет информации о кластере, то производится процедура инициализации;
если в DCS есть настройки кластера, то из DCS считывается динамическая конфигурация;
происходит применение локальной и динамической конфигурации;
если это первый узел кластера, он становиться мастер-сервером ;
если в DCS есть уже мастер и нет данных об этом узле, то в распределенное хранилище записываются его параметры;
4) Алгоритм работы Patroni
Основные параметры
loop_wait (10 сек) время ожидания
ttl (30 сек) время хранения ключа
retry_timeout (10 сек) время для повторных попыток связи с DCS
ttl >= loop_wait + 2*retry_timeout
Daemon Patroni использует цикл обработки:
Вначале цикла служба обновляет значение ttl-ключа лидера ttl-ключей каждого из узлов кластера в DCS и если не требуется выполнить других действий, то засыпает. Время, на которое засыпает Patroni равно значению loop_wait.
Если сервер становится недоступен или возникают ошибки в службе Patroni, то не обновляется значение ttl-ключа для данного узла, пока значение не достигнет 0.
В случае если истекло значение ttl-ключа узла реплики PostgreSQL, то узел исключается из кластера.
В случае если истекло значение ttl-ключа мастер узла PostgreSQL, то производятся перевыборы нового мастера из оставшихся членов кластера.
Перевыборы нового мастер-сервера PostgreSQL
В случае остановки службы PostgreSQL или истечения времени ttl-ключа на мастер-сервере производятся перевыборы нового мастера
Вначале все оставшиеся узлы опрашивают друг друга, а также узел вышедший из строя. Затем происходит сравнение значения WAL и узел, у которго будет меньшее отставание станет новым мастер-сервером.
5) Мониторинг
Для мониторинга DCS и PostgreSQL имеются шаблоны практически для большинства систем мониторинга. Для мониторинга Patroni я использую возможности его API, которое позволяет проверять статус мастер-сервера, узла реплики, а также состояния Patroni (http://{<ip-address>:<patroni_port>/health).
Спасибо за внимание, буду рад ответить на вопросы в комментариях.
Chupaka
А клиенты при этом куда подключаются?
fixed77
например на плавающий между нодами адрес. (keepalived, vip-manager)