Для чего используется Patroni в PostgreSQL?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Для чего используется Patroni в PostgreSQL
Определение
Patroni — это инструмент для управления высокой доступностью (HA) кластера PostgreSQL. Он автоматически переводит резервный сервер в основной при сбое основного, без участия администратора.
Главная идея: если основной PostgreSQL упал, Patroni автоматически поднимет резервный сервер вместо него.
Проблема без Patroni
Сценарий: основной PostgreSQL упал
Производство:
┌────────────────┐
│ PostgreSQL OK │
│ (primary) │
└────────────────┘
↓
СБОЙ! 💥
↓
┌────────────────┐
│ PostgreSQL ❌ │ Основной сервер упал!
│ (primary) │
└────────────────┘
┌────────────────┐
│ PostgreSQL OK │ Резервный сервер работает,
│ (standby) │ но НЕ может писать!
└────────────────┘
❌ Приложение не может писать в БД
❌ Пользователи видят ошибки
❌ Нужен администратор для переключения
❌ RTO (Recovery Time Objective): 10+ минут
Решение без Patroni требует ручных шагов:
# 1. Администратор замечает, что primary упал (5 минут)
# 2. SSH на standby сервер
ssh admin@standby
# 3. Повысить standby до primary
pg_ctl promote -D /var/lib/postgresql/data
# 4. Обновить строку подключения в приложении
# 5. Перезагрузить приложение
# 6. Проверить, что всё работает
# Итого: 15-30 минут простоя
С Patroni (автоматическое переключение)
Производство с Patroni:
┌────────────────┐
│ PostgreSQL OK │
│ (primary) │ Patroni следит за здоровьем
│ + Patroni ✅ │
└────────────────┘
↓
СБОЙ! 💥
↓
┌────────────────┐
│ PostgreSQL ❌ │ Primary упал
│ (primary) │
└────────────────┘
┌────────────────┐
│ PostgreSQL OK │ Patroni АВТОМАТИЧЕСКИ
│ (standby→primary)│ повысил standby за 1-3 секунды
│ + Patroni ✅ │
└────────────────┘
✅ Приложение переключилось на новый primary
✅ Нет простоя для пользователей
✅ RTO (Recovery Time Objective): 1-3 секунды
Архитектура Patroni
┌─────────────────────────────────────────────────────┐
│ Distributed Consensus Store (ETCD/Consul) │
│ Хранит информацию о ком сейчас primary │
└─────────────────────────────────────────────────────┘
↑ ↑
│ │
┌────────┴─────────┐ ┌────────┴─────────┐
│ Patroni Node 1 │ │ Patroni Node 2 │
│ (Primary) │ │ (Standby) │
│ ┌────────────┐ │ │ ┌────────────┐ │
│ │ PostgreSQL │ │ │ │ PostgreSQL │ │
│ └────────────┘ │ │ └────────────┘ │
│ Heartbeat: OK │ │ Heartbeat: OK │
└──────────────────┘ └──────────────────┘
Если Primary упал → Patroni на Standby видит это → Повышает себя
Компоненты Patroni
1. Patroni Daemon — процесс на каждом PostgreSQL сервере:
# Установка Patroni
pip install patroni[etcd]
# Запуск Patroni
patroni /etc/patroni/postgresql.yml
2. ETCD (или Consul) — хранилище состояния кластера:
# ETCD хранит:
etcdctl get /patroni/primary
# → "db-primary-01" (какой сервер сейчас primary)
etcdctl get /patroni/db-primary-01/conn_address
# → "10.0.0.10:5432"
3. VIP (Virtual IP) или DNS — фиксированный адрес для подключения:
// Приложение подключается к одному адресу
const client = new Pool({
host: 'db.production.internal', // Patroni управляет этим адресом
port: 5432
});
// Patroni автоматически обновляет DNS при переключении
// Приложение даже не заметит переключения (reconnect за секунды)
Конфиг Patroni (postgresql.yml)
scope: my-postgres-cluster # Имя кластера
namespace: /patroni
etcd:
hosts:
- 10.0.0.20:2379 # ETCD сервер
- 10.0.0.21:2379
- 10.0.0.22:2379
postgresql:
data_dir: /var/lib/postgresql/data
pgpass: /var/lib/postgresql/.pgpass
listen: 0.0.0.0:5432
connect_address: 10.0.0.10:5432 # IP этого сервера
authentication:
username: patroni
password: patroni_password
parameters: # PostgreSQL конфиг
max_connections: 200
shared_buffers: 256MB
effective_cache_size: 1GB
rest_api:
listen: 0.0.0.0:8008
connect_address: 10.0.0.10:8008
ttl: 30 # Время жизни лидера (primary) в секундах
loop_wait: 10 # Интервал проверки здоровья
maximum_lag_on_failover: 1048576 # Max LAG перед failover
initdb:
- encoding: UTF8
- locale: en_US.UTF-8
Как работает автоматическое переключение
Сценарий: Primary упал
До сбоя:
┌──────────────────────┐
│ Primary (Node 1) │
│ - Пишет в ETCD │
│ - Heartbeat: OK │
└──────────────────────┘
Primary запишет в ETCD каждые 10 секунд:
etcd key: /patroni/my-cluster/leader → Node-1
TTL: 30 секунд
┌──────────────────────┐
│ Standby (Node 2) │
│ - Слушает ETCD │
│ - Heartbeat: OK │
└──────────────────────┘
Шаг 1: Primary упал
┌──────────────────────┐
│ Primary (Node 1) ❌ │ Не может писать в ETCD
└──────────────────────┘
Шаг 2: TTL истёк (30 секунд)
ETCD забывает, кто primary:
key /patroni/my-cluster/leader → (ПУСТО)
Шаг 3: Standby видит, что primary исчезнул
┌──────────────────────┐
│ Standby (Node 2) │
│ "Primary пропал!" │
│ Я становлюсь primary!│
└──────────────────────┘
Шаг 4: Standby написал в ETCD
etcd key: /patroni/my-cluster/leader → Node-2
Шаг 5: Приложение переключилось
DNS: db.production → 10.0.0.11 (новый primary)
✅ Переключение произошло за 30-35 секунд
Примеры использования в production
Пример 1: 3-нодный кластер PostgreSQL
Производство:
┌──────────────┐
│ Node 1 │ Primary
│ PostgreSQL │ (принимает запросы на запись)
│ Patroni │
└──────────────┘
┌──────────────┐
│ Node 2 │ Standby
│ PostgreSQL │ (реплицирует данные)
│ Patroni │
└──────────────┘
┌──────────────┐
│ Node 3 │ Standby
│ PostgreSQL │ (реплицирует данные)
│ Patroni │
└──────────────┘
ETCD кластер для хранения состояния
Пример 2: Node.js приложение с Patroni
const { Pool } = require('pg');
const pool = new Pool({
// Вместо IP адреса, используем DNS имя
// Patroni управляет этим DNS
host: 'postgres.db.svc.cluster.local',
port: 5432,
database: 'myapp',
user: 'app_user',
password: process.env.DB_PASSWORD,
// Автоматический reconnect при переключении
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});
app.post('/users', async (req, res) => {
const client = await pool.connect();
try {
await client.query('INSERT INTO users (name) VALUES ($1)', [req.body.name]);
res.json({ status: 'ok' });
} catch (error) {
// При переключении Primary → Standby
// соединение разорвётся, но pool автоматически переподключится
res.status(500).json({ error: error.message });
} finally {
client.release();
}
});
Преимущества Patroni
✅ Автоматическое переключение — без участия администратора ✅ Высокая доступность — RTO < 1 минута ✅ Масштабируемость — работает с кластерами из 3+ узлов ✅ Безопасность — не теряются данные (sync replication опция) ✅ Мониторинг — REST API для проверки статуса ✅ Простота — YAML конфиг, не нужно писать скрипты
Когда использовать Patroni
✅ Используй Patroni когда:
- Production окружение с требованием HA
- Нужна автоматическая отказоустойчивость
- Есть несколько PostgreSQL серверов
- Допустим простой в несколько секунд
- Используешь Kubernetes (есть встроенная поддержка)
❌ Не нужен Patroni:
- Разработка локально
- Простой проект на одном сервере
- AWS RDS PostgreSQL (управляется AWS)
- Небольшие нагрузки
Альтернативы
- AWS RDS — облачное управление HA (самое простое)
- PostgreSQL built-in replication — простая репликация без failover
- Stolon — похож на Patroni, тоже для HA
- pg_auto_failover — от PostgreSQL разработчиков
Выводы
Patroni — это критичный инструмент для production кластеров PostgreSQL, который:
- Обеспечивает автоматическую отказоустойчивость
- Убирает простои при сбое основного сервера
- Упрощает операции (не нужен ручной failover)
- Масштабируется на большие кластеры
В production окружении, где нельзя терять данные и допустимый простой минимален, Patroni — это стандартное решение.