Planificación de Capacidad en Profundidad
La planificación de capacidad para PostgreSQL se basa fundamentalmente en tres recursos: CPU, memoria y E/S de disco, más un límite estricto que se comporta de manera diferente a los tres: el límite de conexiones.
Esta página construye el modelo mental que conecta esos recursos con los síntomas que los equipos observan realmente, de modo que una decisión de escalado comience a partir de la evidencia en lugar de redimensionar la instancia por instinto.
Resumen
- La planificación de capacidad mapea los síntomas observados (latencia, saturación, errores) a uno de un pequeño número de cuellos de botella de recursos subyacentes.
- Por Qué Importa: Escalar el recurso incorrecto, como añadir CPU para solucionar una carga de trabajo limitada por E/S, desperdicia presupuesto sin solucionar el problema real.
- Conceptos Clave: saturación, ratio de aciertos de caché, límite de conexiones, escalado vertical, escalado horizontal, previsión de crecimiento.
- Cuándo Usar: Dimensionamiento inicial de la instancia, revisiones trimestrales de capacidad y cualquier incidente donde la latencia aumentó pero la CPU parece estar bien.
- Limitaciones / Compensaciones: Cada estrategia de escalado (instancia más grande, réplicas de lectura, partición, fragmentación) intercambia costo o complejidad por margen, y ninguna de ellas soluciona un plan de consulta deficiente.
- Temas Relacionados: agrupación de conexiones, ajuste de rendimiento de consultas, monitorización y alertas, dimensionamiento de plataformas gestionadas.
Fundamentos
La capacidad de CPU rige cuánta ejecución de consultas, ordenación y trabajo de autovacuum puede realizar el clúster de forma concurrente.
La capacidad de memoria rige la efectividad de la caché a través de shared_buffers y la caché de páginas del sistema operativo, determinando con qué frecuencia una lectura se satisface desde la RAM en lugar del disco.
La capacidad de E/S de disco rige la rapidez con la que la capa de almacenamiento puede servir lecturas que no están en caché y absorber el flujo continuo de escrituras WAL que genera cada transacción.
El límite de conexiones, establecido por max_connections, se comporta de manera diferente a los otros tres porque es un corte estricto en lugar de una degradación gradual, y una vez alcanzado, las nuevas sesiones se rechazan directamente en lugar de simplemente ralentizarse.
Un modelo mental útil es una cocina de restaurante: la CPU es el número de cocineros que pueden trabajar a la vez, la memoria es el espacio del mostrador que evita viajes repetidos a la nevera, la E/S de disco es la rapidez con la que se puede acceder a esa nevera, y el límite de conexiones es el número fijo de tickets que la impresora de la cocina puede contener físicamente.
Añadir cocineros no ayuda si la nevera es el cuello de botella, y una nevera más grande no ayuda si la impresora está atascada, que es exactamente por lo que la planificación de capacidad comienza identificando qué recurso está realmente limitado.
PostgreSQL expone la evidencia para este diagnóstico directamente a través de pg_settings, pg_stat_activity y herramientas a nivel de host como iostat, por lo que los datos necesarios para distinguir una carga de trabajo limitada por CPU de una limitada por E/S ya están disponibles en cada clúster.
Las decisiones de dimensionamiento tomadas sin esa evidencia tienden a basarse en el hábito, redimensionando a una clase de instancia familiar en lugar de a lo que exige el perfil de recursos real de la carga de trabajo.
Mecánica e Interacciones
Los cuatro recursos interactúan a través de una cadena que comienza con una consulta y termina con una finalización rápida o una latencia visible para el usuario.
Una consulta primero compite por CPU para planificar y ejecutar, luego por memoria (work_mem) si necesita ordenar o hashear, y finalmente por E/S de disco si los datos que necesita no residen ya en shared_buffers o en la caché del SO.
effective_cache_size no asigna memoria por sí mismo, sino que indica al planificador de consultas aproximadamente cuánta caché está disponible en todo el sistema, lo que da forma a la elección del plan, como favorecer un escaneo de índice sobre un escaneo secuencial cuando el planificador espera que las páginas relevantes ya estén en caché.
Bajo una carga de escritura sostenida, la E/S de disco y la CPU interactúan a través de autovacuum, ya que una tabla que genera tuplas muertas más rápido de lo que autovacuum puede reclamarlas causa índices inflados (más E/S por escaneo) y más CPU gastada evaluando filas que eventualmente se descartarán.
-- Un mecanismo concretado: esta señal distingue
-- "las consultas se están ejecutando" de "las consultas están en cola", lo cual
-- es la primera bifurcación en cualquier diagnóstico de capacidad.
SELECT count(*) FILTER (WHERE state = 'active') AS active,
count(*) FILTER (WHERE wait_event_type = 'Lock') AS blocked,
count(*) AS total
FROM pg_stat_activity
WHERE backend_type = 'client backend';Las conexiones interactúan con los tres recursos de manera indirecta pero significativa, ya que cada backend abierto consume memoria incluso cuando está inactivo, y una tormenta de conexiones de una aplicación con agrupación insuficiente puede agotar max_connections mucho antes de que la CPU o el disco muestren alguna tensión real.
Un error de razonamiento común es escalar primero la CPU o el tamaño de la instancia, cuando el cuello de botella real es frecuentemente un índice faltante o un recuento de conexiones ilimitado, ninguno de los cuales una instancia más grande solucionará y solo hará más costoso seguir ignorando.
Consideraciones Avanzadas y Aplicaciones
A gran escala, la planificación de capacidad pasa de la extinción reactiva de incendios a una disciplina de previsión que anticipa el agotamiento de recursos antes de que se convierta en un incidente.
El crecimiento del almacenamiento es el recurso que la mayoría de los equipos subestiman, ya que el crecimiento de tablas e índices se acumula con el tiempo en cargas de trabajo de series temporales o registros de eventos de una manera que una instantánea única en el tiempo no revela, haciendo que la proyección basada en tendencias sea más útil que una alerta estática de "porcentaje libre".
La elección entre escalado vertical, réplicas de lectura y estrategias horizontales como la partición o la fragmentación depende de qué recurso está realmente limitado: una carga de trabajo de un solo escritor limitada por CPU o memoria se beneficia del escalado vertical, una carga de informes con muchas lecturas se beneficia de las réplicas, y una tabla única demasiado grande para hacer vacuum o indexar eficientemente se beneficia de la partición independientemente del tamaño de la instancia.
La fragmentación específicamente debe tratarse como un último recurso en esta jerarquía, ya que introduce complejidad en las consultas entre fragmentos y sobrecarga operativa que la partición o las réplicas de lectura suelen evitar mientras resuelven la misma presión subyacente.
La agrupación de conexiones interactúa con la planificación de capacidad a nivel arquitectónico, ya que un agrupador como PgBouncer cambia el recurso real que se está dimensionando de "conexiones por instancia de aplicación" a "conexiones por grupo", que es lo que hace que los niveles de aplicación escalados horizontalmente (muchos pods, muchas invocaciones sin servidor) sean compatibles con un límite estricto de max_connections.
Las revisiones de capacidad realizadas de forma trimestral, correlacionando el crecimiento de tablas, los picos de conexiones y el costo de las consultas principales, detectan la deriva lenta hacia un límite de recursos mucho antes de que se convierta en una página a las 3 a.m.
| Enfoque | Fortaleza | Debilidad | Mejor Ajuste |
|---|---|---|---|
| Escalado vertical (instancia más grande) | Simple, sin cambios en la aplicación | El costo crece más rápido que linealmente en el extremo superior, tiene un límite | Cargas de trabajo de un solo escritor limitadas por CPU o memoria |
| Réplicas de lectura | Descarga el tráfico de lectura, mejora la latencia de lectura | Retraso de replicación, no ayuda al rendimiento de escritura | Carga de informes con muchas lecturas |
| Partición | Limita el costo de mantenimiento de vacuum e índices por partición | La complejidad de las consultas y la migración aumenta | Tablas únicas muy grandes con una clave natural (tiempo, inquilino) |
| Fragmentación | Distribuye la carga de lectura y escritura horizontalmente | Consultas entre fragmentos, sobrecarga operativa significativa | Rendimiento de escritura que excede cualquier primario único, último recurso |
Conceptos Erróneos Comunes
- "La alta latencia siempre significa que la instancia necesita más CPU." - Las cargas de trabajo de PostgreSQL frecuentemente están limitadas por E/S o bloqueos, por lo que la CPU puede parecer saludable mientras las consultas se ponen en cola detrás de esperas de disco o transacciones bloqueantes.
- "max_connections debe establecerse alto 'para el crecimiento'." - cada conexión abierta consume memoria, ya sea inactiva o activa, por lo que un límite alto sin agrupación de conexiones arriesga el agotamiento de memoria, no el margen.
- "Un shared_buffers más grande siempre significa un mejor ratio de aciertos de caché." - los retornos disminuyen mucho antes del 100% de la RAM, y la caché de páginas del SO realiza un trabajo significativo que
shared_bufferssobredimensionado puede desplazar. - "Las réplicas de lectura solucionan los cuellos de botella de escritura." - las réplicas solo descargan el tráfico de lectura; un primario limitado por escritura necesita una estrategia diferente, como la partición o, eventualmente, la fragmentación.
- "La fragmentación es la respuesta predeterminada para quedarse sin capacidad." - suele ser la opción más costosa operativamente y se reserva mejor para el rendimiento de escritura que el escalado vertical y la partición genuinamente no pueden resolver.
- "La planificación de capacidad es un ejercicio de dimensionamiento único." - la carga de trabajo y el volumen de datos cambian continuamente, por lo que el dimensionamiento decidido en el lanzamiento rutinariamente se vuelve incorrecto en un año sin una cadencia de revisión.
Preguntas Frecuentes
¿Cuáles son los recursos principales involucrados en la planificación de capacidad de PostgreSQL?
CPU para la ejecución de consultas, memoria para el almacenamiento en caché, E/S de disco para lecturas y escrituras WAL, y el límite de conexiones como un límite estricto y distinto.
¿Por qué puede aumentar la latencia incluso cuando la utilización de la CPU parece baja?
PostgreSQL frecuentemente está limitado por la E/S de disco o la contención de bloqueos, ambos pueden saturarse independientemente de la CPU.
¿Qué controla realmente `effective_cache_size`?
No asigna memoria por sí mismo; informa la estimación del planificador de consultas de la caché disponible, lo que influye en la elección del plan, como escaneos de índice frente a escaneos secuenciales.
¿Por qué el límite de conexiones se trata de manera diferente a la CPU, la memoria y el disco?
Es un corte estricto en lugar de una degradación gradual, rechazando nuevas sesiones directamente una vez que se alcanza max_connections en lugar de simplemente ralentizarlas.
¿Cómo se conecta autovacuum tanto a la capacidad de CPU como a la de E/S de disco?
Una tabla que acumula tuplas muertas más rápido de lo que autovacuum las recupera causa índices inflados que cuestan más E/S por escaneo y más CPU evaluando filas descartables.
¿Cuándo tiene sentido el escalado vertical frente a una réplica de lectura?
El escalado vertical se ajusta a una carga de trabajo de un solo escritor limitada por CPU o memoria, mientras que una réplica de lectura se ajusta al tráfico de informes con muchas lecturas que no afecta al cuello de botella de escritura.
¿Por qué la fragmentación se considera un último recurso en lugar de una ruta de escalado predeterminada?
Introduce complejidad en las consultas entre fragmentos y sobrecarga operativa que la partición o las réplicas de lectura suelen evitar mientras abordan la misma presión subyacente.
¿Cómo cambia la agrupación de conexiones el panorama de la capacidad?
Cambia el recurso que se está dimensionando de conexiones por instancia de aplicación a conexiones por grupo, permitiendo que un nivel de aplicación escalado horizontalmente permanezca bajo un límite estricto de max_connections.
¿Por qué el crecimiento del almacenamiento se pronostica comúnmente de forma insuficiente?
Una instantánea única en el tiempo no revela el crecimiento compuesto de cargas de trabajo de series temporales o registros de eventos, por lo que la proyección basada en tendencias detecta lo que una comprobación estática de espacio libre no capta.
¿La planificación de capacidad es algo que se hace una vez al lanzar?
No, la carga de trabajo y el volumen de datos cambian continuamente, por lo que se necesita una cadencia de revisión trimestral para detectar la deriva antes de que se convierta en un incidente.
¿Una instancia más grande siempre soluciona una consulta lenta?
Rara vez; un índice faltante o un plan de consulta deficiente generalmente dominan sobre el tamaño bruto de la instancia, y escalar el hardware primero a menudo solo hace que la misma ineficiencia sea más costosa.
¿Qué evidencia debe preceder a una decisión de escalado?
Eventos de espera de pg_stat_activity, ratio de aciertos de caché, métricas de E/S a nivel de host y saturación de conexiones, para que la decisión se dirija al recurso que está realmente limitado.
Relacionados
- Fundamentos de Capacidad - el punto de partida a nivel de receta para el modelo de recursos descrito aquí.
- Matemáticas de Conexiones - la mecánica de agrupación de conexiones referenciada en la discusión del límite de conexiones de esta página.
- Escalado Vertical vs. Escalado Horizontal - una comparación más profunda de las estrategias de escalado en la tabla anterior.
- Previsión de Crecimiento del Almacenamiento - la disciplina de previsión descrita en Consideraciones Avanzadas.
- Fragmentación: Último Recurso - por qué la fragmentación se encuentra al final de la jerarquía de escalado.
- Puntos Clave de Métricas y Monitorización - las señales utilizadas para diagnosticar qué recurso está limitado.
Versiones de Stack: Esta página fue escrita para PostgreSQL 18.4 (versión principal estable 18, línea de mantenimiento 17) y PgBouncer 1.x.