Proxies de Conexión
Durante una conmutación por error, algo debe enviar las conexiones del cliente al nuevo primario. HAProxy (o un balanceador de carga en la nube) dirige TCP; PgBouncer 1.x agrupa sesiones. Resuelven diferentes capas.
Receta
Frontends TCP de HAProxy para escritura (primario) y lectura (réplicas); PgBouncer en modo de agrupación de transacciones para los workers de la aplicación.
# HAProxy realiza comprobaciones de backend en la REST API de Patroni (puerto 8008) para el líder
# frontend pg_write -> backend patroni_primary (solo el líder pasa la comprobación)
# frontend pg_read -> backend patroni_replicas (los standby pasan la comprobación de réplica)# fragmento de pgbouncer.ini
[databases]
appdb = host=pg-write.internal port=5432 dbname=appdb
[pgbouncer]
listen_port = 6432
pool_mode = transaction
max_client_conn = 2000
default_pool_size = 50
server_lifetime = 300Cuándo recurrir a esto: Más de un puñado de servidores de aplicaciones conectándose a PostgreSQL; la conmutación por error no debe requerir cambios en la configuración de la aplicación.
Ejemplo de Trabajo
Script de comprobación de HAProxy Patroni y recarga de PgBouncer después de la conmutación por error:
#!/usr/bin/env bash
# patroni-primary-check.sh - sale con 0 si este nodo es el líder de Patroni
LEADER=$(curl -sf http://127.0.0.1:8008/patroni | jq -r .role)
[[ "$LEADER" == "master" || "$LEADER" == "primary" ]]# extracto de haproxy.cfg
backend patroni_primary
mode tcp
option tcp-check
tcp-check connect port 8008
tcp-check send GET\ /primary\ HTTP/1.0\r\n
tcp-check expect string 200
server pg1 10.0.1.11:5432 check port 8008
server pg2 10.0.1.12:5432 check port 8008
server pg3 10.0.1.13:5432 check port 8008# Después de la conmutación por error: reinicia PgBouncer para descartar conexiones de servidor obsoletas
psql -h 127.0.0.1 -p 6432 -U pgbouncer pgbouncer -c "RECONNECT;"
# o: systemctl reload pgbouncerLo que esto demuestra:
- HAProxy utiliza los puntos finales REST
/primaryy/replicade Patroni para el enrutamiento de salud. - Las aplicaciones se conectan a
pg-write.internal:6432(PgBouncer) y no a las IPs de nodos individuales. RECONNECTo la recarga limpian los pools que apuntan al primario anterior.
Análisis Profundo
Responsabilidades de Capa
| Componente | Capa OSI | Comportamiento de conmutación por error |
|---|---|---|
| HAProxy / NLB | TCP (L4) | Dirige al líder de Patroni saludable |
| PgBouncer 1.x | Pool de conexiones | Reabre backends después del cambio de líder |
| RDS Proxy | Pool administrado + IAM | AWS maneja el intercambio de backends |
| URL JDBC de la aplicación | Cliente | Debe usar nombre de host estable + tiempos de espera |
División Lectura/Escritura
- Escrituras: Backend único que pasa la comprobación de primario de Patroni.
- Lecturas: Réplicas a través de la comprobación
/replica; toleran un ligero retraso para la notificación. - Precaución: La lectura de tus escrituras requiere un enrutamiento consciente del primario o de sincronización, no de cualquier réplica.
Modos de PgBouncer
| Modo | Nota de HA |
|---|---|
session | Más seguro para sentencias preparadas; menos conexiones guardadas |
transaction | Común para aplicaciones web; usa compatibilidad con DISCARD ALL |
statement | Raro; rompe muchos patrones ORM |
Errores Comunes
- Solo PgBouncer, sin HAProxy - El pool todavía apunta a un nombre de host; DNS debe actualizarse en la conmutación por error. Solución: Patroni + HAProxy o TTL de DNS confiable + comprobaciones de salud.
- Sentencias preparadas en modo transacción - Errores después de la reutilización del pool. Solución:
pool_mode = sessionpara las aplicaciones afectadas o deshabilitar sentencias preparadas. - HAProxy comprobando solo el puerto de PostgreSQL - Tanto el primario como la réplica aceptan TCP; enrutamiento incorrecto. Solución: Comprobaciones de salud HTTP de Patroni en 8008.
server_lifetimelargo - Conexiones obsoletas al primario durante minutos. Solución: Reducir el tiempo de vida;RECONNECTen la callbackon_role_changede Patroni.- RDS Proxy con Patroni autoalojado - Productos diferentes; no mezclar patrones. Solución: Elegir pila administrada o autoalojada por entorno.
Alternativas
| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
| VIP + keepalived | Centro de datos heredado | Se prefiere LB en la nube |
| Servicio Kubernetes + endpoints de Patroni | PG alojado en K8s | VMs en bare-metal |
| Intercambio directo de CNAME DNS | Configuraciones pequeñas más simples | Se requiere RTO de menos de un minuto |
Preguntas Frecuentes
¿Orden de HAProxy vs PgBouncer?
Común: cliente -> PgBouncer -> HAProxy -> PostgreSQL, o cliente -> HAProxy -> PgBouncer -> PostgreSQL. Elige una topología y documéntala.
¿RDS Proxy reemplaza a Patroni?
No. RDS Proxy agrupa conexiones; Aurora/RDS Multi-AZ maneja la conmutación por error subyacente.
¿Conexiones de replicación a través de PgBouncer?
No. La replicación en streaming y lógica se conectan directamente al puerto 5432 de PostgreSQL.
¿Terminación SSL?
Terminar en HAProxy o usar sslmode=require de extremo a extremo. Cumplir con los requisitos de cumplimiento.
¿Cuántas instancias de PgBouncer?
Al menos dos para HA; cada una apunta al mismo VIP de escritura de HAProxy.
Relacionado
- Patroni y etcd/Consul - elección de líder
- Conceptos Básicos de HA - requisitos de reintento del cliente
- Pruebas de HA - validar el enrutamiento en simulacros
- Matemáticas de Conexiones - dimensionamiento de pools
Versiones de la pila: Esta página se escribió para PostgreSQL 18.4 (estable 18, mantenimiento 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x y PostGIS 3.5+.