Alta disponibilidad con Patroni y etcd

Avanzado
SQL
SQL
Actualizado: 19/04/2026

Una base de datos productiva debe sobrevivir a la caída de su servidor primario sin intervención manual. La alternativa al script casero ("si pings fallan, hacer pg_promote") es un orquestador robusto: Patroni, junto con un DCS (Distributed Configuration Store) como etcd, gestiona el cluster con garantías de seguridad y trazabilidad.

El problema del failover manual

Sin orquestación, el flujo típico ante una caída es:

  • 1. Alguien se da cuenta de que el primario no responde.
  • 2. Verifica que la réplica está al día.
  • 3. Ejecuta pg_ctl promote o equivalente.
  • 4. Reconfigura las aplicaciones para apuntar a la nueva IP.
  • 5. Si vuelve el viejo primario, hay que evitar el split-brain (dos primarios escribiendo).

Cada paso es una oportunidad para errores humanos. Patroni automatiza todo el flujo y añade salvaguardas que un script casero no contempla.

Arquitectura: Patroni + DCS

Un cluster Patroni consta de tres componentes:

  • Nodos PostgreSQL con un demonio Patroni en cada uno.
  • DCS (etcd, Consul, ZooKeeper o Kubernetes API) que mantiene el estado distribuido del cluster.
  • Proxy (HAProxy, pgBouncer, AWS NLB) que enruta a la IP del leader actual.
flowchart TB
    A[Aplicacion] --> B[HAProxy]
    B -->|leader=pg-1| C[Nodo pg-1<br/>PRIMARY]
    B -.->|standby| D[Nodo pg-2<br/>STANDBY]
    B -.->|standby| E[Nodo pg-3<br/>STANDBY]
    C --> F[(etcd cluster<br/>quorum 3 nodos)]
    D --> F
    E --> F
    F -->|leader key TTL| C

El DCS mantiene una clave leader con un TTL corto (15-30 segundos). El nodo primario renueva el TTL constantemente. Si deja de hacerlo, las réplicas detectan la expiración, una de ellas adquiere la clave (leader election) y Patroni la promueve automáticamente.

Instalación básica

Patroni se distribuye como paquete pip:

pip install patroni[etcd]

Cada nodo necesita un fichero YAML de configuración. Un ejemplo mínimo para un cluster de tres nodos:

scope: produccion-cluster
namespace: /service/
name: pg-1

restapi:
  listen: 0.0.0.0:8008
  connect_address: 10.0.0.1:8008

etcd:
  hosts: 10.0.0.10:2379,10.0.0.11:2379,10.0.0.12:2379

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      parameters:
        max_connections: 200
        wal_level: replica
        hot_standby: "on"
        max_wal_senders: 10
        max_replication_slots: 10
        wal_keep_size: 1GB

postgresql:
  listen: 0.0.0.0:5432
  connect_address: 10.0.0.1:5432
  data_dir: /var/lib/postgresql/data
  bin_dir: /usr/lib/postgresql/16/bin
  authentication:
    replication:
      username: replicator
      password: <secret>
    superuser:
      username: postgres
      password: <secret>

Las contraseñas reales se gestionan con secret managers (Vault, AWS Secrets Manager, Kubernetes Secrets). Nunca se comprometen en repositorios.

Comandos principales

Patroni añade un cliente CLI patronictl para operar el cluster:

# Estado del cluster
patronictl -c /etc/patroni.yml list

#  Member  | Host       | Role    | State   | TL | Lag
# pg-1    | 10.0.0.1   | Leader  | running | 12 |   0
# pg-2    | 10.0.0.2   | Replica | running | 12 |   0
# pg-3    | 10.0.0.3   | Replica | running | 12 |   0

# Failover manual planificado (mantenimiento)
patronictl -c /etc/patroni.yml switchover --master pg-1 --candidate pg-2

# Reinicializar una replica desde cero
patronictl -c /etc/patroni.yml reinit produccion-cluster pg-3

# Pausar el cluster (deshabilitar failover automatico)
patronictl -c /etc/patroni.yml pause

El switchover es la operación segura para mantenimiento: se asegura de que la nueva primaria esté al día antes de promoverla y degradar la antigua. Failover es el escenario de fallo no planificado.

Cómo se evita el split-brain

El split-brain (dos nodos creyéndose primarios simultáneamente y escribiendo) es el peor escenario en HA. Patroni lo evita con varias salvaguardas:

  • Quórum en el DCS: solo el nodo que adquiere la clave leader en etcd se promueve. Si la red se parte y un nodo queda aislado del DCS, no puede ser leader.
  • Watchdog (opcional): el kernel reinicia el nodo si Patroni no responde, evitando que un nodo zombie siga escribiendo.
  • Sincronía de réplicas configurable: con synchronous_commit = on y synchronous_standby_names, el primario solo confirma escrituras cuando una réplica las ha persistido.
postgresql:
  parameters:
    synchronous_commit: "on"
    synchronous_standby_names: "ANY 1 (pg-2,pg-3)"

Con esa configuración, las escrituras solo se confirman cuando al menos una de las dos réplicas ha persistido el WAL. En caso de failover, esa réplica está garantizada de tener todos los datos confirmados.

Integración con HAProxy

Patroni expone una REST API en cada nodo (/health, /leader, /replica) que HAProxy usa para enrutar:

backend postgres-write
    mode tcp
    option httpchk GET /leader
    http-check expect status 200
    server pg-1 10.0.0.1:5432 check port 8008
    server pg-2 10.0.0.2:5432 check port 8008
    server pg-3 10.0.0.3:5432 check port 8008

backend postgres-read
    mode tcp
    balance roundrobin
    option httpchk GET /replica
    http-check expect status 200
    server pg-1 10.0.0.1:5432 check port 8008
    server pg-2 10.0.0.2:5432 check port 8008
    server pg-3 10.0.0.3:5432 check port 8008

El backend postgres-write solo dirige tráfico al nodo que responde 200 a /leader (el primario actual). El backend postgres-read distribuye lecturas entre las réplicas. La aplicación apunta a la IP de HAProxy, no a IPs específicas de PostgreSQL.

Alternativas: repmgr y pgpool-II

Patroni no es la única opción de HA:

  • repmgr (de 2ndQuadrant): herramienta más ligera, sin DCS externo. Apropiada para clusters pequeños o entornos donde añadir etcd resulta excesivo. El failover automático requiere repmgrd corriendo y tiene menos garantías frente a particiones de red.
  • pgpool-II: añade pooling de conexiones, balanceo y failover en un solo proceso, pero su modelo es más complejo y la documentación es densa. Apropiado cuando ya se usa pgpool por otras razones.
  • PostgreSQL Operator (Kubernetes): para deployments en Kubernetes, operadores como crunchy-postgres-operator o cloudnative-pg orquestan PostgreSQL con la API de Kubernetes como DCS implícito.

| Aspecto | Patroni | repmgr | pgpool-II | |---------|---------|--------|-----------| | DCS requerido | Sí | No | No | | Failover automático | Sí | Sí (repmgrd) | Sí | | Pooling | No | No | Sí | | Balanceo | No | No | Sí | | Madurez | Alta | Alta | Alta | | Recomendado para | Producción seria | Setups pequeños | Setups que necesitan pooling integrado |

Buenas prácticas operativas

  • Cluster DCS de 3 o 5 nodos en zonas de disponibilidad distintas.
  • Monitorización de etcd: cualquier degradación del DCS afecta la HA de PostgreSQL.
  • Backups independientes del cluster: HA no sustituye backups (no protege contra borrado lógico).
  • Probar failover periódicamente en preproducción.
  • Documentar el runbook de recuperación: si se cae el DCS entero, ¿cómo se recupera?
  • Versionar la configuración Patroni en Git con rotación automática de secretos.

El error más común en HA es asumir que funciona sin probarlo. Un calendario trimestral de pruebas de failover es la única forma de garantizar que el cluster responde como se espera el día que de verdad falla algo.

Patroni convierte la HA de PostgreSQL en una operación rutinaria. La inversión inicial en la configuración del cluster y el DCS se recupera la primera vez que un servidor cae a las 3 de la madrugada y el sistema sigue atendiendo peticiones sin que nadie tenga que despertarse.

Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, SQL es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de SQL

Explora más contenido relacionado con SQL y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Comprender la arquitectura Patroni con DCS (etcd, Consul, ZooKeeper). Configurar un cluster de tres nodos con leader election y failover automático. Evitar split-brain mediante el quorum del DCS. Integrar HAProxy o pgBouncer para enrutar tráfico al leader. Diferenciar Patroni frente a alternativas como repmgr o pgpool-II.

Cursos que incluyen esta lección

Esta lección forma parte de los siguientes cursos estructurados con rutas de aprendizaje