56.04K
AI
Категория: Базы данныхБазы данных

Управление высокодоступными кластерами PostgreSQL с помощью Patroni

1.

Управление высокодоступными
кластерами PostgreSQL с помощью
Patroni
Пошаговое руководство по созданию отказоустойчивых СУБД решений на основе etcd
Мастер-класс разработчиков Patroni
Авторы: Алексей Клюкин, Александр Кукушкин (Zalando)

2.

Традиционный HA приводит к Split-Brain при сбоях
сети
Разделяемые хранилища
(Corosync/Pacemaker)
• Использование SAN, DRBD или LVM для
монтирования дисков на резервный сервер [9].
Простые асинхронные скрипты
мониторинга
VS
• Скрипты опрашивают мастер по сети и
переключают реплику при его недоступности [13].
• Крайне высокая сложность конфигурации и
администрирования [10].
• В реальном мире сеть нестабильна, происходят
кратковременные всплески [14].
• Риск 'забывания' настроек со временем, что ведет
к ошибкам во время реальных аварий [10].
• Изолированная реплика считает мастер упавшим
и делает promote себе [14].
• Отсутствие гибкости при масштабировании
количества реплик [11].
• Оригинальный мастер продолжает писать
данные: возникает split-brain [14].
Мастер-класс Patroni | Слайд 2

3.

Шаблон Bot обеспечивает консенсус через etcd
1. Управляющий бот
• Рядом с каждым PostgreSQL на
узле запускается демон Patroni
(на Python) [19, 24].
• Бот полностью управляет
локальным инстансом СУБД [19,
20].
• Бот общается с
распределенным хранилищем
конфигурации (DCS) [19].
Мастер-класс Patroni | Слайд 3
2. Атомарный лок
лидера
3. Автоматические
выборы
• Текущий мастер регулярно (раз
в 30 сек) обновляет ключ лидера
в DCS [20].
• При падении мастера ключ
лидера экспайрится в DCS [21].
• Ключ лидера имеет TTL (время
жизни), по истечении которого он
исчезает [20].
• Здоровые реплики узнают об
исчезновении лидера и
опрашивают WAL-позиции друг
друга [21].
• Обновление выполняется
атомарно через алгоритмы
консенсуса (Raft) [22, 23].
• Реплика с максимальным WAL
пытается создать ключ лидера и
делает promote [21, 22].

4.

Слоты репликации защищают WAL от ротации при
перезапусках
Пошаговый запуск первого
кластера
• Первый запущенный узел Patroni проверяет etcd и
видит, что кластера нет [27].
• Выполняет initdb, забирает ключ инициализации и
становится мастером [27].
• Второй узел видит лидера в etcd и запускает
pg_basebackup для клонирования [28].
• Реплика запускается и начинает стримить данные с
мастера [28].
Мастер-класс Patroni | Слайд 4
Механизм слотов репликации
• Patroni автоматически создает слот репликации для
каждой реплики [29].
• Слот гарантирует, что мастер не удалит WAL-файлы,
даже если реплика временно отключена [29, 30].
• Без слотов отключенная реплика отстанет и потребует
полной переинициализации [29].
• Внимание: если реплика отключена надолго, WALфайлы могут переполнить диск мастера! [30]

5.

Утилита patronictl и REST API обеспечивают полный
мониторинг
Инструмент / Эндпоинт
Тип запроса / Действие
Что возвращает / Описание
patronictl list
Командная строка (CLI)
Показывает роли нод (LDR/TLR), IP-адреса, статус СУБД и отставание
репликации (Lag) [33].
GET /master
REST API (HTTP)
Возвращает статус 200 OK, только если узел является живым мастером с
активным локом лидера [76, 77].
GET /replica
REST API (HTTP)
Возвращает 200 OK на здоровой реплике. Используется для балансировки
read-only запросов [77].
GET /config
REST API (HTTP)
Позволяет просматривать и динамически менять глобальную конфигурацию
кластера в DCS [78].
Мастер-класс Patroni | Слайд 5

6.

Утилита pg_rewind автоматически разрешает SplitBrain
Провокация Split-Brain в реальной
жизни
• Если демон Patroni на мастере аварийно остановлен
(или завис), но СУБД Postgres продолжает работать [39,
41].
• Реплика не видит лок в etcd, делает promote и
становится новым мастером [36].
• Клиенты продолжают писать данные на старый
мастер, создавая расхождение транзакций [40, 41].
• Старый мастер уходит вперед по своей шкале
времени (timeline) [42].
Мастер-класс Patroni | Слайд 6
Автоматическое разрешение
ситуации
• При восстановлении Patroni обнаруживает, что узел
отстал и потерял роль лидера [41].
• Выполняет немедленный shutdown (immediate
shutdown) старого мастера [41].
• Запускает crash recovery в single-user режиме для
достижения согласованности [42].
• Запускает pg_rewind: утилита откатывает
несинхронизированные коммиты старого мастера до
точки разделения и подключает его как реплику [42, 43].

7.

Изменения SIGHUP применяются на лету, а
max_connections требует рестарта
Параметры без перезагрузки
(SIGHUP)
Параметры с рестартом
(pending_restart)
• Например, параметр 'work_mem' или
'maintenance_work_mem' [49, 51].
• Например, параметр 'max_connections' или
'shared_buffers' [51, 74].
• Редактируется глобально через команду 'patronictl editconfig' [49].
• При изменении Patroni выставляет флаг
'pending_restart: true' на узлах кластера [53].
• Patroni обновляет конфигурацию в DCS и отправляет
сигнал SIGHUP всем узлам [50].
• СУБД продолжает работать, Patroni оставляет
решение о перезагрузке администратору [52].
• Параметры применяются одновременно на всем
кластере без отключения клиентов [50, 51].
• Администратор выполняет безопасный перезапуск
через 'patronictl restart' в непиковое время [54, 106].
Мастер-класс Patroni | Слайд 7

8.

Формула TTL > loop_wait + 2 * retry_timeout
предотвращает потерю лидера
Базовое уравнение стабильности лидера:
TTL > loop_wait + 2 * retry_timeout
loop_wait (Интервал
сна)
• Время в секундах, на которое
засыпает демон Patroni перед
новой итерацией цикла проверки
роли СУБД [58].
• Обычно составляет 10 секунд
[60].
Мастер-класс Patroni | Слайд 8
retry_timeout
(Таймаут сети)
• Время ожидания ответов от DCS
при попытках записи или
продления лока лидера [59].
• Должно позволять сгладить
кратковременные всплески [64].
TTL (Время жизни
ключа)
• Период экспирации ключа
лидера в etcd [58].
• Если нарушить формулу
(сделать TTL меньше loop_wait),
мастер начнет циклически терять
и перезабирать лок [59, 61].

9.

Локальный patroni.yaml переопределяет глобальную
конфигурацию etcd
Приоритет
Источник конфигурации
Поведение и Описание
1 (Высший)
ALTER SYSTEM (PostgreSQL)
Параметры, заданные внутри СУБД, имеют абсолютный приоритет, но
действуют строго локально [73].
2
Локальный patroni.yaml
Параметры, прописанные на конкретном узле. Переопределяют настройки
etcd [73]. Полезно при разном объеме RAM [67].
3
Глобальный DCS (etcd/Consul)
Параметры, хранящиеся в ключе /config. Применяются ко всему кластеру
одновременно [68, 69].
4 (Низший)
Секция Bootstrap (YAML)
Используется ОДИН раз при инициализации абсолютно нового кластера.
После этого игнорируется [65, 67].
Мастер-класс Patroni | Слайд 9

10.

Интеграция HAProxy и confd перенаправляет
клиентов на мастер
HAProxy (TCP
балансировка)
• HAProxy опрашивает все узлы
Patroni через REST API [83].
• Только текущий мастер
возвращает HTTP статус 200 OK
[83].
• Реплики возвращают статус 503
Service Unavailable [77].
• Трафик на запись идет
исключительно на активный
мастер [83].
Мастер-класс Patroni | Слайд 10
Динамический confd
• confd следит за изменениями
топологии кластера в etcd [85].
• При смене IP или ролей узлов
confd на лету перегенерирует
конфиг HAProxy/PgBouncer [85,
86].
• Автоматически
перезапускает/перечитывает
балансировщик (reload) без
простоя [86].
PgBouncer (Пул
соединений)
• PgBouncer умеет ставить
клиентские соединения на паузу
[88].
• При failover соединение
зависает на пулере, а не падает
с ошибкой [88].
• После переключения на новый
мастер транзакции
продолжаются прозрачно для
клиентов [88].

11.

Теги nofailover и callbacks адаптируют поведение
узлов кластера
Управляющие теги в patroni.yaml
• Прописываются строго в локальном
конфигурационном файле узла [91].
• nofailover: true — нода никогда не станет мастером
(полезно для удаленных дата-центров) [91].
• noloadbalance: true — исключает ноду из балансировки
read-only трафика [92].
• nosync: true — запрещает ноде играть роль
синхронной реплики [93].
• clonefrom: true — разрешает новым нодам делать
basebackup с этой реплики вместо мастера [92].
Мастер-класс Patroni | Слайд 11
Механизм Callbacks (Обратные
вызовы)
• Запуск внешних shell-скриптов при ключевых событиях
жизненного цикла СУБД [84].
• on_start / on_stop — вызов при запуске или остановке
PostgreSQL [84].
• on_role_change — выполняется сразу после
промотирования или понижения узла [84].
• Пример использования: скрипт динамически
перевешивает виртуальный IP (VIP) на новый мастер
[89].

12.

Режим Pause блокирует failover на время
обслуживания кластера
Синхронная репликация в Patroni
• Параметр synchronous_mode: true включает строгое
подтверждение транзакций репликой [119].
• Patroni автоматически выбирает лучшую реплику и
прописывает в 'synchronous_standby_names' [119, 124].
• Режим strict: при падении единственной реплики
запись на мастер блокируется, защищая данные от
потерь [121, 128].
• Возможность отключать синхронность для отдельных
транзакций через 'SET synchronous_commit TO local'
[122, 123].
Мастер-класс Patroni | Слайд 12
Режим обслуживания (Pause)
• Включается командой 'patronictl pause' [111].
• Patroni полностью прекращает автоматический failover
и управление ролями [111, 112].
• Позволяет отключать etcd для обновления без ухода
кластера в read-only [112].
• Администратор может свободно останавливать
Postgres или etcd вручную — Patroni не вмешается [113].

13.

Кастомные методы wal-e/wal-g разгружают мастер при
создании реплик
Инициализация реплик из
бэкапов
Custom Bootstrap и PITR
• Параметр 'create_replica_method' позволяет задать
список методов клонирования [130].
• Point-In-Time Recovery: возможность развернуть
кластер до определенного состояния во времени [135].
• Пример: сначала развернуть бэкап с помощью 'wal-e'
или 'wal-g' из S3, не нагружая мастер [129, 130].
• Patroni стягивает базовый бэкап, генерирует
'recovery.conf' с параметрами восстановления [135].
• Если кастомный метод возвращает ошибку, Patroni
пробует следующий в списке или pg_basebackup [130,
133].
• Указывается целевой timeline восстановления
(recovery_target_timeline) [135].
• Метод работает в режиме no_master, позволяя
поднять СУБД при полной гибели кластера [131].
Мастер-класс Patroni | Слайд 13
• После наката транзакций выполняется автоматический
promote [135].

14.

Выделенные диски для etcd гарантируют
отказоустойчивость кластера
Лучшие практики эксплуатации
• Используйте выделенные быстрые SSD диски для etcd
(крайне важно для стабильности Raft и исключения
ложных failover) [37].
• Никогда не удаляйте вручную директорию данных
реплики при сбоях (опыт GitLab показывает риски
стирания мастера) [108].
• Для переинициализации реплик всегда используйте
безопасную команду 'patronictl reinit' [109].
• Тщательно тестируйте параметры сети и формулу TTL
в тестовых средах перед выкатом в прод [64].
Мастер-класс Patroni | Слайд 14
Полезные ресурсы проекта
• Официальный репозиторий Patroni на GitHub:
github.com/zalando/patroni [149].
• Полная интерактивная документация:
patroni.readthedocs.io [149].
• Spilo: готовый Docker-образ с Postgres, Patroni и
инструментами резервного копирования [150].
• Zalando Postgres Operator: управление кластерами
СУБД в Kubernetes [150].
English     Русский Правила