Decisión: ¿cómo configurar el connection pooling?
Cada conexión a la base de datos conlleva un costo de memoria y de planificación; un crecimiento descontrolado del número de conexiones ralentiza el servidor o incluso lo hace caer. Un pool de conexiones lo resuelve reutilizando un pequeño número de conexiones persistentes. Este árbol orienta las decisiones sobre dónde se ubica el pool, qué modo usar (session/transaction/statement) y el tamaño adecuado, e insiste en por qué un pooler externo es obligatorio en entornos serverless.
¿Cómo se conecta la arquitectura de su aplicación?
La decisión de pooling empieza por la arquitectura. ¿Es un único proceso de aplicación de larga duración (servidor clásico), muchos procesos/instancias independientes (microservicios, muchos pods) o funciones serverless/Lambda que nacen y mueren con cada solicitud? Cada caso requiere una ubicación distinta del pool.
- Uno/pocos procesos de aplicación de larga duración
- Muchos procesos/instancias/pods se conectan a la misma BD
- Serverless / Lambda / funciones de corta duración
- Muéstreme primero cómo elegir el tamaño de pool adecuado
¿Cómo debe elegirse el modo del pooler intermedio?
Con muchos clientes, un pooler intermedio (PgBouncer, ProxySQL) mantiene bajo el número de conexiones en la BD. Pero el modo del pool depende de las funciones que usa la aplicación: ¿depende de un estado ligado a la sesión (prepared statements, tablas temporales, SET, advisory locks, funciones a nivel de sesión), o todo se completa dentro de una sola transacción?
- Dependo del estado de sesión (SET, tablas temporales, prepared statements de sesión)
- Las transacciones son cortas e independientes; no mantengo estado de sesión
Recomendación: pool de conexiones dentro de la aplicación
Para uno/pocos procesos de larga duración, una biblioteca de pool dentro de la aplicación (HikariCP, el pool integrado de database/sql de Go, el connection pooling de .NET) cubre la mayoría de las necesidades. Las conexiones se abren una vez y se reutilizan una y otra vez.
Recomendación: dimensione correctamente el pool
El pool no debe ser ni demasiado pequeño (las solicitudes esperan) ni demasiado grande. Demasiadas conexiones generan cambios de contexto de CPU y contención de bloqueos y reducen el throughput. El tamaño no es un número que haya que aumentar indefinidamente, sino un número pequeño basado en los núcleos y la E/S.
Recomendación: modo de pool session
En el modo session, una conexión de cliente queda fijada a una conexión de servidor del backend hasta que termina su sesión. El estado a nivel de sesión (SET, tablas temporales, advisory locks, prepared statements de sesión) se conserva, pero la compartición de conexiones es mínima.
Recomendación: modo de pool transaction
En el modo transaction, una conexión de servidor se presta al cliente solo durante una transacción y vuelve al pool cuando la transacción termina. Así, miles de clientes pueden trabajar con muy pocas conexiones reales en la BD; es el modo más común a gran escala.
Recomendación: un pooler externo es obligatorio en serverless
Las funciones serverless/Lambda escalan rápidamente y cada instancia abre su propia conexión; un pool dentro de la aplicación no ayuda aquí porque las instancias son de corta duración y no comparten nada. Cuando surgen de golpe cientos/miles de instancias, se supera el límite de conexiones de la BD. La solución es un pool de conexiones externo delante de la BD.