Какой у вас опыт работы с Patroni?

«Какой у вас опыт работы с Patroni?» — вопрос из категории Базы данных, который задают на 24% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Настраивал и поддерживал высокодоступные кластеры PostgreSQL с Patroni в production-среде в течение 3 лет. Основной стек: Patroni + etcd + PgBouncer + monitoring.

Архитектура типичного кластера:

┌─────────────────────────────────────────────────┐
│                Load Balancer (HAProxy)          │
│           read-write       read-only            │
└───────────────┬──────────────────┬──────────────┘
                │                  │
        ┌───────▼──────┐   ┌───────▼──────┐
        │  Patroni 1   │   │  Patroni 2   │
        │  (Leader)    │   │  (Replica)   │
        │  PostgreSQL  │   │  PostgreSQL  │
        └───────┬──────┘   └───────┬──────┘
                │                  │
        ┌───────▼──────────────────▼──────┐
        │         etcd Cluster (3 nodes)  │
        │    для распределенного консенсуса│
        └──────────────────────────────────┘

Конфигурация Patroni (/etc/patroni/patroni.yml):

scope: postgres-prod
namespace: /service/
name: pg-node-1

restapi:
  listen: 0.0.0.0:8008
  connect_address: 10.0.1.10:8008
  authentication:
    username: "{{ patroni_api_user }}"
    password: "{{ patroni_api_password }}"

etcd:
  hosts:
    - etcd1:2379
    - etcd2:2379
    - etcd3:2379
  protocol: http
  retry_timeout: 10
  ttl: 30

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      use_slots: true
      parameters:
        max_connections: 100
        shared_buffers: 128MB
        wal_level: logical
        hot_standby: "on"
        archive_mode: "on"
        archive_command: 'cp %p /var/lib/postgresql/wal/%f'

postgresql:
  listen: 0.0.0.0:5432
  connect_address: 10.0.1.10:5432
  data_dir: /var/lib/postgresql/14/main
  bin_dir: /usr/lib/postgresql/14/bin
  pgpass: /var/lib/postgresql/.pgpass
  authentication:
    replication:
      username: replicator
      password: "{{ replication_password }}"
    superuser:
      username: postgres
      password: "{{ postgres_password }}"

watchdog:
  mode: required
  device: /dev/watchdog
  safety_margin: 5

Решаемые задачи:

  1. Автоматический failover — при падении лидера Patroni выбирает новую ноду за 30-60 секунд
  2. Репликация — настройка синхронной/асинхронной репликации с контролем лага
  3. Switchover — плановое переключение без простоя:
    patronictl switchover postgres-prod --master pg-node-1 --candidate pg-node-2
  4. Мониторинг — экспорт метрик в Prometheus (endpoint /metrics), алерты на:
    • Смену лидера
    • Лаг репликации > threshold
    • Нет кворума в etcd
  5. Интеграция с PgBouncer — автоматическое обновление pgbouncer.ini при смене лидера

Проблемы и решения:

  • Split-brain — предотвращаем через watchdog и правильные таймауты
  • Network partitions — настройка ttl и retry_timeout согласно сетевой задержке
  • Большие WAL файлы — использование pg_rewind вместо полного перебилда реплик