Ir al contenido

Qué cambia un Postgres gestionado para Laravel

El Postgres serverless está diseñado y tarifado para cargas de una conexión por petición. Laravel mantiene conexiones de larga vida en sus workers de cola, y ahí están las sorpresas.

5 min de lectura

Postgres gestionado solía significar un servidor que parcheaba otro. Cada vez más significa una plataforma: almacenamiento separado del cómputo, conexiones intermediadas por un pooler, bases de datos que se ramifican como git, y cómputo que se suspende cuando nadie pregunta.

Todo eso está construido para una carga en la que llega una petición, ejecuta una consulta y se va. Laravel es esa carga en la capa web y lo contrario en todo lo demás.

El desajuste, dicho sin rodeos

Una aplicación Laravel tiene tres tipos de cliente de base de datos y se comportan de forma completamente distinta:

Peticiones web. PHP-FPM, conectar y desconectar por petición. Esto encaja con el modelo serverless exactamente.

Workers de cola. El comando queue:work conecta al arrancar y mantiene esa conexión toda su vida, esté procesando algo o no. Veinte workers son veinte conexiones permanentes antes de que llegue un solo visitante.

El planificador. Una entrada de cron ejecutando schedule:run cada minuto, para siempre.

Los proveedores tarifan y dimensionan alrededor del primero. El segundo es lo que llena una asignación de conexiones y es la causa más común de un SQLSTATE[HY000] [1040] Too many connections, un error que desglosamos en detalle en nuestras páginas de errores en inglés. El tercero es lo que derrota en silencio el escalado a cero.

El escalado a cero y el planificador

Esto es lo que la gente hace mal primero y es aritmética, no opinión.

El cómputo se suspende tras cierto periodo de inactividad. La orden schedule:run emite una consulta cada sesenta segundos. Si el umbral de inactividad es mayor que un minuto, la base de datos no se suspende nunca y usted está pagando cómputo siempre encendido con características de arranque en frío encima.

Hay tres respuestas honestas. Aceptarlo y dimensionar para siempre encendido, en cuyo caso una instancia convencional puede salir más barata. Mover el planificador a algo que no toque la base de datos cuando no hay nada pendiente, lo que significa que la definición del calendario tiene que poder leerse sin una consulta. O aceptar arranques en frío en un entorno de pruebas y no en producción, que es donde el escalado a cero de verdad compensa.

Nadie debería descubrir esto por una factura.

Los modos de pooling, que son lo que rompe cosas

Todo Postgres serverless pone un pooler delante. El modo decide qué puede hacer su aplicación.

El pooling por sesión le entrega una conexión real durante toda la vida de su conexión. Todo funciona. También obtiene muchas menos conexiones efectivas, que suele ser el motivo por el que vino.

El pooling por transacción le entrega un backend solo durante una transacción. Esto es lo que da miles de conexiones de cliente sobre unas pocas reales, y elimina todo lo que abarca varias sentencias:

  • Las sentencias preparadas en servidor, que PDO usa por defecto. Esta es la que muerde a Laravel en concreto, y el arreglo es una bandera en la cadena de conexión o un ajuste de emulación, no un cambio de código, pero hay que ponerlo a propósito.
  • Los bloqueos de aviso, lo que significa que withoutOverlapping() en un calendario y ShouldBeUnique en un trabajo pueden no comportarse como están escritos si se apoyan en la base de datos.
  • Las sentencias SET, así que todo lo que fije una zona horaria o una ruta de búsqueda por conexión deja de aguantar.
  • LISTEN/NOTIFY, y cualquier cursor de larga vida.

La disposición práctica son dos conexiones en config/database.php: el punto final con pooling para las peticiones web, el directo para las migraciones, los workers de cola y cualquier cosa que sostenga un bloqueo. Son diez líneas y evitan la mayor parte de este artículo.

El branching, que es la capacidad genuinamente nueva

Una rama es una base de datos con copia en escritura a escala de producción, creada en segundos. Para Laravel eso aterriza sobre un problema concreto: migraciones que son seguras contra cuarenta filas y bloquean cuatro minutos contra cuatro millones.

Una rama por pull request, las migraciones ejecutadas contra ella en CI, los tiempos registrados. Ahora un cambio de esquema peligroso falla una compilación en vez de un despliegue. Este es el argumento más fuerte a favor de una plataforma frente a una instancia, y vale más que el modelo de precios.

Elegir entre ellas

Una instancia gestionada convencional - RDS, Cloud SQL, el Postgres sencillo de un proveedor - cuando la aplicación tiene una flota estable de workers, cuando quiere recuentos de conexiones predecibles, y cuando la carga operativa que está comprando es el parcheo y no el escalado. Esta sigue siendo la respuesta correcta para la mayoría de las aplicaciones de negocio y no está de moda decirlo.

Postgres serverless con branching cuando la historia de probar migraciones le importa, cuando los entornos son numerosos y efímeros, o cuando el tráfico es de verdad irregular. Presupueste el trabajo de pooling en lugar de suponer que es un cambio en la cadena de conexión.

Una plataforma con auth y almacenamiento incluidos cuando también los va a usar. Si la usa solo como base de datos, está eligiendo un proveedor de Postgres y debería compararlo como tal.

Cualquier cosa compatible con MySQL pero fragmentada solo con la lista de restricciones leída antes. La integridad referencial, las transacciones que cruzan shards y ORDER BY sobre una tabla fragmentada son donde el modelo se transparenta, y las migraciones de Laravel escribirán tan tranquilas DDL que la plataforma acepta y no impone.

La comprobación que cuesta una tarde

Antes de comprometerse, ejecute lo real: una migración con construcción de índice sobre una tabla de tamaño de producción, su número real de workers conectados a la vez, y un comando programado sosteniendo un bloqueo. Tres medidas, una tarde.

Todos los problemas de este artículo son baratos de encontrar así y caros de encontrar en el segundo mes.

Preguntas relacionadas

¿Funciona el escalado a cero con una aplicación Laravel?
Rara vez, y por un motivo fácil de pasar por alto: el planificador corre cada minuto. Una entrada de cron con `schedule:run` es una consulta cada sesenta segundos, así que el cómputo nunca queda inactivo el tiempo suficiente para suspenderse. Se queda con el comportamiento de arranque en frío sin el ahorro, salvo que organice deliberadamente periodos de silencio.
¿Seguimos necesitando un pooler?
Casi con seguridad, y lo importante es en qué modo. El pooling por transacción es el que da el número de conexiones, y rompe todo lo que asume una sesión: bloqueos de aviso, sentencias `SET`, `LISTEN/NOTIFY`, y las sentencias preparadas en servidor, que PDO usa por defecto. El pooling por sesión conserva todo eso y devuelve mucho menos.
¿Merece la pena el branching de base de datos?
Para probar migraciones contra datos con forma de producción, sí, y es la funcionalidad que más merece la pena y que una instancia convencional no puede dar. Una rama por pull request significa que una migración destructiva la caza el CI con recuentos de filas reales en lugar de contra una tabla sembrada con cuarenta.
¿Y PlanetScale y otras plataformas tipo Vitess?
Son compatibles con MySQL en vez de Postgres, y la restricción significativa han sido históricamente las claves foráneas: el modelo de sharding hace cara la integridad referencial entre shards, y el soporte ha cambiado con el tiempo. Compruebe el comportamiento actual antes de escribir `constrained()` en una migración, porque una clave foránea aceptada y no impuesta es peor que una rechazada.

← Volver a todos los artículos

Llamar+1 848 272 7583WhatsApp+90 850 308 5436Correoinfo@codefacture.comPágina de contacto