Read in English · Lire en français · Auf Deutsch lesen
Sección 6.8 de 6.8 · Intermedio · 28 min de lectura
Arquitecturas serverless y basadas en espacios
Videolección
5 min · narrado en inglés, con subtítulosSolo escuchar (audio)
Leer la transcripción
Esta lección trata dos estilos que responden a la cuestión de la capacidad de formas opuestas. Serverless solo cobra por el uso. La arquitectura basada en espacios atiende los picos extremos desde memoria. Ambas son herramientas especializadas, y ambas se eligen a menudo por motivos equivocados.
Una parada de taxis solo cobra por cada viaje. Cuando nadie necesita un trayecto no pagas nada, pero en una noche de mucho movimiento cada viaje cuesta más de lo que costaría tener un automóvil propio. Y el primer taxi puede tardar un momento en llegar. Eso es serverless. Ahora imagina la taquilla de un estadio antes de un gran concierto. En lugar de que cada empleado consulte un único registro central, cada ventanilla guarda su propia copia de qué asientos están libres y envía sus ventas a la oficina central más tarde. Eso es la arquitectura basada en espacios, construida para la avalancha.
Serverless no significa que no haya servidores. Significa que tu equipo no aprovisiona, parchea ni dimensiona servidores, ni paga por ellos cuando están inactivos. Con las funciones como servicio, los eventos activan pequeñas piezas de tu propio código. Aquí, una solicitud web, un mensaje de cola, una foto subida y una programación nocturna activan cada uno una función, cuyas instancias crea, escala y destruye el proveedor. Con el backend como servicio, servicios totalmente gestionados sustituyen a partes del lado del servidor: una base de datos, el correo electrónico y el almacenamiento de archivos. Las funciones no tienen estado y duran poco. Todo el estado duradero vive en servicios gestionados, así que un sistema serverless es un sistema distribuido por construcción.
Sin tráfico, no se ejecuta nada y no se factura cómputo. A medida que llegan eventos, arrancan muchas instancias en paralelo, y mil de ellas pueden desbordar una base de datos con sus conexiones. Pagas por solicitud, más la memoria multiplicada por el tiempo de ejecución. El código que espera a una API lenta está pagando por esperar. La primera solicitud a una instancia nueva espera mientras esta arranca, desde decenas de milisegundos hasta varios segundos. Estos arranques en frío afectan sobre todo a las ráfagas repentinas. Las funciones no guardan nada entre llamadas, se ejecutan con límites estrictos y muchos disparadores entregan al menos una vez, por lo que los manejadores deben ser idempotentes. Y serverless te ata estrechamente a tu proveedor. Un camino intermedio es mantener la lógica de negocio en módulos simples detrás de puertos, con manejadores de función finos que actúan como adaptadores.
¿Es más barato? La sección hace el cálculo con precios ilustrativos en cifras redondas, no con los precios reales de ningún proveedor. Dos máquinas virtuales siempre activas y un balanceador de carga cuestan una cantidad fija de cien libras al mes. Como funciones, la misma API de cartas cuesta unas tres libras con veinte por cada millón de solicitudes, y sube con el tráfico. Las líneas se cruzan en unos treinta y un millones de solicitudes al mes, aproximadamente doce por segundo. Por debajo de esa cifra, serverless es más barato, porque el tiempo inactivo es gratis. Por encima, un servicio con carga constante paga más. Esto deja fuera a las personas, cuyo tiempo puede costar más que la diferencia. Así que rehaz las cuentas con precios reales y tráfico medido.
La arquitectura basada en espacios saca de la ruta crítica la base de datos, que normalmente toca cada solicitud. Aquí, para una puesta a la venta de entradas, un grid de mensajería dirige la solicitud de cada comprador a una unidad de procesamiento. Cada unidad, idéntica a las demás, guarda en memoria la lógica y los datos de los asientos, y un grid de datos replica los cambios entre las unidades. Los cambios llegan más tarde a la base de datos: las bombas de datos los ponen en cola y los escritores de datos los escriben. Los lectores de datos cargan datos de la base de datos para precargar el grid al arrancar. El problema son las colisiones de datos: dos unidades pueden actualizar el mismo elemento antes de que la replicación se ponga al día. Para los datos que nunca deben colisionar, como el último asiento, dirige todas sus solicitudes a una sola unidad.
Imagina una gira por estadios que sale a la venta a las diez en punto, con unas cuatrocientas mil personas esperando. El sistema nunca debe vender un asiento dos veces, y no debe caerse. Las solicitudes se enrutan por espectáculo y zona, así que una sola unidad gestiona todas las reservas provisionales de una zona. Las reservas provisionales nunca pueden colisionar. Cuando un comprador elige dos asientos, la unidad los reserva durante ocho minutos, en memoria, en microsegundos. El pago se ejecuta con una clave de idempotencia. Si tiene éxito, los asientos se marcan como vendidos y una bomba de datos pone la venta en cola. La base de datos se escribe a un ritmo constante que puede sostener, y la cola se vacía unos minutos después del pico. Ningún comprador espera a la base de datos.
Serverless encaja en el trabajo con picos, impredecible o de bajo volumen, en el pegamento dirigido por eventos, en los trabajos programados y en los equipos sin capacidad de operaciones. Encaja mal con el tráfico constante de gran volumen, los procesos de larga duración y los requisitos estrictos de latencia de cola que los arranques en frío incumplirían. La arquitectura basada en espacios es compleja y costosa, y la base de datos va con retraso respecto al grid. Úsala solo para picos extremos. Prueba primero la caché, las réplicas de lectura o una sala de espera virtual que admita a los compradores a un ritmo controlado. Eso es mucho más sencillo, y a menudo basta por sí solo.
Con esto termina el Capítulo 6. Cuando estés listo, haz la prueba del capítulo opcional: veinte preguntas de opción múltiple y dos respuestas escritas, con una nota de aprobado del ochenta por ciento. Después, continúa con el Capítulo 7, sobre arquitectura de datos. Nos vemos allí.
Lo que necesitas saber
- Serverless combina las funciones como servicio, donde el proveedor ejecuta código activado por eventos y lo escala desde cero, con el backend como servicio, donde servicios gestionados sustituyen a componentes del lado del servidor; AWS Lambda (anunciado en 2014) popularizó FaaS.
- Las funciones no tienen estado y duran poco, se facturan por invocación y por GB-segundo, están sujetas a arranques en frío (cold starts) y a límites estrictos de tiempo, memoria y carga útil, y a menudo se activan al menos una vez, por lo que los manejadores deben ser idempotentes.
- Todo el estado duradero vive en servicios gestionados, así que un sistema serverless es un sistema distribuido por construcción y está fuertemente acoplado a su proveedor, salvo que la lógica de negocio se mantenga detrás de puertos.
- El precio por solicitud es más barato que la capacidad siempre activa por debajo de un volumen de cruce y más caro por encima de él; el punto de cruce depende de la duración, la memoria, la forma del tráfico y los costos de personal.
- La arquitectura basada en espacios atiende las solicitudes desde unidades de procesamiento con grids de datos en memoria replicados, gestionadas por un middleware virtualizado, y actualiza la base de datos de forma asíncrona mediante bombas de datos y escritores de datos, con lectores de datos para precargar el grid.
- Su nombre procede del espacio de tuplas de Linda, de Gelernter (1985); sus principales riesgos son las colisiones de datos entre réplicas, los límites de memoria, el retraso de la base de datos, el costo y la complejidad.
- Usa la arquitectura basada en espacios solo para cargas extremas y con picos que la caché, las réplicas y las salas de espera no puedan manejar, y enruta o particiona los datos disputados para que no puedan colisionar.
Dos respuestas a la cuestión de la capacidad
Todos los estilos de este capítulo vistos hasta ahora suponen que alguien ejecuta servidores y los dimensiona para la carga. Esta sección trata dos estilos que responden a la cuestión de la capacidad de formas opuestas. La arquitectura serverless entrega por completo los servidores a un proveedor de nube y paga por uso, lo que conviene al trabajo pequeño, dirigido por eventos y a menudo inactivo. La arquitectura basada en espacios mantiene en memoria todo lo que necesita una solicitud con mucha actividad, repartido entre muchas unidades idénticas, para que la base de datos deje de estar en la ruta crítica, lo que conviene a picos extremos y repentinos, como la puesta a la venta de entradas. Ambas son herramientas especializadas; ambas se eligen a menudo por motivos equivocados.
Serverless: funciones y backends gestionados
Serverless no significa que no haya servidores; significa que el equipo no aprovisiona, parchea ni dimensiona servidores, ni paga por ellos cuando están inactivos. El artículo de Mike Roberts de 2018, muy citado, distingue dos ingredientes. Las funciones como servicio (FaaS) ejecutan pequeñas piezas del código propio del equipo en respuesta a eventos, en contenedores que el proveedor crea, escala y destruye, y que pueden durar una sola invocación. AWS Lambda, anunciado en noviembre de 2014 y disponible de forma general en abril de 2015, popularizó el modelo; Azure Functions, Google Cloud Run functions y Cloudflare Workers son otros ejemplos. El backend como servicio (BaaS) sustituye componentes del lado del servidor por servicios de terceros totalmente gestionados a los que el cliente o la función llaman directamente: autenticación (Auth0, Amazon Cognito), bases de datos (Firebase, DynamoDB), almacenamiento de objetos, correo electrónico y colas.
Una aplicación serverless suele ser una combinación: las funciones contienen la lógica de negocio específica de la organización, y todo lo demás, incluido todo el estado duradero, vive en servicios gestionados. El proveedor se encarga de la capacidad, la disponibilidad entre zonas y el sistema operativo. El equipo sigue siendo responsable de su código, sus datos, su configuración y sus ajustes de seguridad, como explica el modelo de responsabilidad compartida en los servidores y la nube.
Los eventos activan funciones; el estado vive en otro lugar
Cómo se comportan las funciones: las características que condicionan el diseño
Disparadores de eventos. Las funciones se ejecutan en respuesta a eventos: una solicitud HTTP a través de un gateway, un mensaje en una cola o un flujo, un archivo que llega al almacenamiento de objetos, un cambio en una base de datos o una programación horaria. Los disparadores que invocan la función de forma asíncrona, como las colas y las notificaciones de almacenamiento, suelen entregar al menos una vez y reintentar en caso de fallo, por lo que los manejadores deben ser idempotentes, exactamente igual que en la arquitectura dirigida por eventos.
Escalar a cero y escalar horizontalmente. Sin tráfico, no se ejecuta ninguna instancia y no se factura nada de cómputo. A medida que llegan eventos, la plataforma arranca más instancias en paralelo, hasta un límite de concurrencia de la cuenta o de la función; en AWS Lambda, el límite regional por defecto es de 1000 ejecuciones concurrentes en el momento de escribir esto, ampliable a petición. El escalado horizontal rápido es a la vez una ventaja y un peligro: mil funciones concurrentes pueden abrir mil conexiones de base de datos y desbordar una base de datos relacional diseñada para unos pocos cientos, y por eso existen los proxies de conexiones y los topes de concurrencia por función.
Facturación por invocación. El costo suele ser un pequeño cargo por solicitud más un cargo por la memoria multiplicada por el tiempo de ejecución (gigabytes-segundo). Por tanto, el código que espera sin hacer nada a una API lenta de la que depende está pagando por esperar.
Arranques en frío (cold starts). La primera solicitud a una instancia nueva debe esperar mientras la plataforma arranca un contenedor, carga el entorno de ejecución y ejecuta el código de inicialización: desde decenas de milisegundos hasta varios segundos, según el lenguaje, el tamaño del paquete y la configuración de red. Las instancias se reutilizan para solicitudes posteriores mientras siguen calientes, así que los arranques en frío afectan sobre todo al tráfico poco frecuente y a las ráfagas repentinas. Las mitigaciones incluyen paquetes de despliegue más pequeños, entornos de ejecución más ligeros, inicializar fuera del manejador y pagar por mantener instancias preinicializadas (AWS lo llama provisioned concurrency), lo que reintroduce en parte el costo de tener capacidad siempre activa.
Límites. Las funciones se ejecutan con límites estrictos de tiempo de ejecución, memoria, tamaño de la carga útil y disco temporal; para AWS Lambda, en el momento de escribir esto, 15 minutos, de 128 MB a 10 240 MB de memoria (con CPU asignada en proporción) y 6 MB para una solicitud o respuesta síncrona. Los trabajos largos deben dividirse en pasos, y las cargas útiles grandes deben pasarse por referencia al almacenamiento de objetos.
Ausencia de estado. Nada de lo que hay en la memoria o el disco local de una instancia tiene garantizado sobrevivir hasta la siguiente invocación. Guardar en caché en memoria entre llamadas es una optimización que puede acertar o no, nunca un lugar para datos importantes.
Adónde va el estado
Como las funciones no guardan nada, el trabajo de arquitectura pasa a consistir en elegir dónde vive cada tipo de estado. Los datos de negocio duraderos van a una base de datos gestionada, a menudo una que maneje bien muchas conexiones de corta duración (almacenes clave-valor o documentales, o una base de datos relacional detrás de un proxy de conexiones). Los objetos grandes van al almacenamiento de objetos y se pasan entre funciones mediante su clave. El estado compartido de corta duración, como los contadores de limitación de tasa, va a una caché gestionada. El progreso de un proceso de varios pasos va a un servicio de flujos de trabajo (AWS Step Functions, Azure Durable Functions o similares), que actúa como orquestador de sagas duradero, como se describe en sagas. Las sesiones de usuario van en tokens que guarda el cliente o en un almacén de sesiones.
La consecuencia es que un sistema serverless es un sistema distribuido por construcción, con todas las inquietudes de este capítulo: latencia de red entre cada función y sus datos, fallos parciales, eventos duplicados, consistencia eventual y la necesidad de trazado distribuido. Una sola acción de negocio puede atravesar un gateway, tres funciones, una cola y dos bases de datos. La observabilidad (consulta observabilidad) no es opcional.
Acoplamiento al proveedor: el precio de no ejecutar servidores
Serverless acopla un sistema a su proveedor más estrechamente que alquilar máquinas virtuales o ejecutar contenedores. Los formatos de los eventos, la configuración de los disparadores, los modelos de identidad y permisos, las definiciones de flujos de trabajo y los propios servicios gestionados son todos específicos del proveedor. Trasladar una aplicación serverless madura a otra nube se parece más a una reescritura que a una migración.
Los profesionales no se ponen de acuerdo sobre cuánto importa esto. Una postura sostiene que la dependencia del proveedor (lock-in) es el precio de una gran reducción del trabajo operativo y que la mayoría de las organizaciones nunca cambian de nube, así que optimizar para la portabilidad es un esfuerzo perdido. La otra sostiene que los cambios de precios, las exigencias regulatorias o las adquisiciones sí obligan a cambiar, y que un acoplamiento profundo elimina poder de negociación. Un camino intermedio es aceptar el acoplamiento en los bordes y contenerlo en el núcleo: mantener la lógica de negocio en módulos simples detrás de puertos, con manejadores de función finos que actúan como adaptadores (el enfoque de la arquitectura hexagonal), mantener la infraestructura como código y registrar el acoplamiento como una decisión explícita. El costo y la dependencia del proveedor se tratan con más detalle en FinOps y dependencia del proveedor.
Ejemplo práctico
Ejemplo práctico: ¿cuándo sale más barato lo siempre activo?
La API de cartas de restaurantes de la plataforma de reparto de comida podría ejecutarse como funciones o en dos máquinas virtuales siempre activas. Todos los precios son cifras redondas ilustrativas elegidas para facilitar la aritmética, no precios de lista actuales de ningún proveedor. Cada solicitud se ejecuta durante una media de 200 ms con 0.5 GB de memoria, así que consume 0.1 GB-segundos.
| Precios serverless ilustrativos | Cómputo: £0.00002 por GB-segundo; £0.20 por millón de invocaciones; £1.00 por millón de solicitudes a través del gateway HTTP. |
|---|---|
| Costo serverless por millón de solicitudes | Cómputo: 1 000 000 × 0.1 GB-s × £0.00002 = £2.00. Invocaciones: £0.20. Gateway: £1.00. Total: £3.20 por millón. |
| Costo ilustrativo de lo siempre activo | Dos VM pequeñas a £40 al mes cada una (dos por redundancia) más un balanceador de carga a £20 = £100 al mes, dimensionado para picos de unas 300 solicitudes por segundo. |
| 1 millón de solicitudes al mes (0.4 por segundo de media) | Serverless: £3.20; siempre activo: £100. Serverless es unas 30 veces más barato. |
| 10 millones al mes (unas 4 por segundo) | Serverless: £32; siempre activo: £100. |
| Punto de cruce | £100 ÷ £3.20 ≈ 31 millones de solicitudes al mes, unas 12 solicitudes por segundo de media (31.25 millones ÷ 2.59 millones de segundos en 30 días). |
| 100 millones al mes (unas 39 por segundo) | Serverless: £320; siempre activo: todavía £100, porque las dos VM aún tienen margen de capacidad. |
| Efecto de reducir la duración a la mitad, a 100 ms | El cómputo baja a £1.00, el total a £2.20 por millón, y el punto de cruce se desplaza a unos 45 millones. En serverless, la optimización se nota directamente en la factura. |
Por debajo del punto de cruce, serverless es más barato porque el tiempo inactivo es gratis; por encima, un servicio con carga constante paga más por el mismo trabajo. El tráfico a ráfagas con largos periodos de inactividad favorece a serverless incluso con volúmenes más altos.
La comparación en bruto deja fuera el mayor costo para muchos equipos: las personas. Parchear, escalar y hacer guardias para las VM puede costar fácilmente más que la diferencia, lo que eleva el punto de cruce real. Los cargos por transferencia de datos, logging y observabilidad se aplican a ambas opciones y a menudo superan cualquiera de las dos facturas de cómputo.
Como el resultado depende de la duración, la memoria, la forma del tráfico y los precios actuales, rehaz el cálculo con precios reales y tráfico medido antes de decidir, y vuelve a hacerlo a medida que crezca el tráfico.
El punto de cruce, dibujado
Cuándo encaja serverless y cuándo no
Serverless encaja en cargas de trabajo con picos, impredecibles o de bajo volumen, en las que pagar por servidores inactivos es un desperdicio; en el pegamento dirigido por eventos, como reaccionar a subidas de archivos, mensajes de cola y cambios en bases de datos; en los trabajos programados y la automatización administrativa; en los prototipos y productos nuevos, en los que el equipo debería dedicar su tiempo al producto y no a la infraestructura; y en equipos sin capacidad de plataforma ni de operaciones.
Encaja mal con el tráfico constante y de gran volumen, en el que el precio por solicitud supera a la capacidad siempre activa (como en el ejemplo práctico); con los procesos de larga duración o con estado, como la transcodificación de video que supera el límite de tiempo o los servidores WebSocket que mantienen muchas conexiones; con requisitos estrictos de baja latencia de cola que los arranques en frío incumplirían; con cargas de trabajo que necesitan hardware especial o un control fino del entorno de ejecución; y con diseños de grano fino en los que muchas funciones se llaman entre sí de forma síncrona, lo que añade saltos de red, costo y puntos de fallo en cada paso. El Capítulo 1 describió cómo Amazon Prime Video, en 2023, pasó un servicio de monitorización de pasos serverless distribuidos a un único proceso e informó de una reducción de más del 90% en el costo de infraestructura (por qué importa la arquitectura): no es un veredicto sobre serverless, sino un recordatorio de que el encaje importa más que la moda.
Arquitectura basada en espacios: sacar la base de datos de la ruta crítica
La mayoría de las arquitecturas escalan con facilidad los niveles web y de aplicación, pero acaban chocando con la base de datos, que toca cada solicitud. Añadir servidores delante solo traslada la cola a la base de datos. La arquitectura basada en espacios, tal como la describen Mark Richards y Neal Ford en Fundamentals of Software Architecture, elimina por completo la base de datos de la ruta síncrona. Cada solicitud se gestiona íntegramente en memoria en una de muchas unidades de procesamiento idénticas, y la base de datos se actualiza de forma asíncrona, entre bastidores.
El nombre procede del espacio de tuplas, una memoria asociativa compartida introducida por el lenguaje de coordinación Linda de David Gelernter en 1985: los procesos se comunican escribiendo tuplas en un espacio compartido y leyendo o extrayendo las tuplas que coinciden, sin conocerse entre sí. JavaSpaces, de Sun, llevó la idea a Java a finales de la década de 1990, y plataformas comerciales construyeron sobre ella espacios distribuidos y replicados, que evolucionaron hasta los grids de datos en memoria actuales, como Hazelcast, Apache Ignite y Oracle Coherence.
Las partes de un sistema basado en espacios
- Unidad de procesamientoUna unidad desplegable que contiene la lógica de la aplicación y un grid de datos en memoria (in-memory data grid) con los datos que necesita esa lógica, además de un motor de replicación. Las unidades son idénticas, así que añadir una añade capacidad. En el ejemplo de venta de entradas, cada unidad contiene el mapa de asientos y las reservas provisionales actuales de los eventos que atiende.
- Middleware virtualizadoLa infraestructura que gestiona las unidades. El grid de mensajería recibe las solicitudes y dirige cada una a una unidad disponible. El grid de datos replica los cambios entre las copias en memoria de las unidades. El grid de procesamiento, opcional, coordina las solicitudes que necesitan varios tipos de unidad. El gestor de despliegue arranca y detiene unidades a medida que la carga sube y baja.
- Bombas de datos (data pumps)Canales asíncronos, normalmente colas de mensajes persistentes, que llevan cada cambio hecho en una unidad al lado de la base de datos. Si la base de datos va lenta o está caída, los cambios esperan en la cola; los compradores no se ven afectados.
- Escritores de datos (data writers)Componentes que consumen los mensajes de las bombas y escriben los cambios en la base de datos. Pueden escalarse y pausarse con independencia de las unidades.
- Lectores de datos (data readers)Componentes que cargan datos de la base de datos en las unidades cuando el grid arranca en frío, por ejemplo después de que se hayan reiniciado o vuelto a desplegar todas las unidades. No se usan en el procesamiento normal de solicitudes.
Arquitectura basada en espacios para una puesta a la venta de entradas
Colisiones de datos y otros costos
Mantener copias replicadas en muchas unidades traslada a la memoria los problemas de consistencia de las secciones anteriores. Con una caché replicada, cada unidad tiene una copia completa y los cambios se copian de forma asíncrona, lo que da lecturas locales rápidas, pero dos unidades pueden actualizar el mismo elemento antes de que la replicación se ponga al día. Richards y Ford llaman a esto colisión de datos y estiman su tasa como el número de unidades multiplicado por el cuadrado de la tasa de actualización, dividido por el número de elementos y multiplicado por la latencia de replicación. Con 5 unidades, 20 actualizaciones por segundo, 50 000 elementos y 100 ms de latencia, eso da 5 × 400 ÷ 50 000 × 0.1 = 0.004 por segundo, unas 115 colisiones en una jornada de ocho horas; reducir la latencia a 1 ms la deja en torno a una.
Para los datos que nunca deben colisionar, como el último asiento de una fila, las alternativas son una caché distribuida, en la que cada elemento vive en una partición y todas las unidades lo leen y escriben allí (consistente, pero cada acceso es una llamada de red y las particiones del grid deben seguir disponibles), o dirigir todas las solicitudes de un evento o una zona a la misma unidad, de modo que solo una unidad cambie esos asientos. La mayoría de los diseños reales combinan ambas cosas: particionan por clave los datos calientes y disputados, y replican los datos que se leen mucho y se escriben poco, como los mapas del recinto y los precios.
Los demás costos son importantes. Los datos guardados en memoria están limitados por el tamaño de la memoria y deben reconstruirse tras un reinicio completo. La base de datos es eventualmente consistente con el grid, así que los informes y otros sistemas ven los cambios con retraso, y perder cambios en cola es un riesgo real que debe cubrir la durabilidad de las bombas. Probar con una carga de pico realista es caro y difícil. Y el estilo es complejo y costoso de construir: Richards y Ford le dan una puntuación baja en simplicidad y en capacidad de prueba, y alta en costo. Solo merece la pena cuando la carga de verdad no puede atenderse con caché, réplicas de lectura y una base de datos bien ajustada.
Ejemplo práctico
Ejemplo práctico: la puesta a la venta de un estadio
Las entradas de una gira por estadios salen a la venta a las 10:00. Hay unas 400 000 personas esperando; durante los primeros diez minutos, la demanda es cientos de veces la tasa normal y luego decae. El sistema de venta de entradas no debe vender un asiento dos veces ni debe caerse.
| Antes de la puesta a la venta | Los lectores de datos cargan en el grid los mapas de asientos de cada espectáculo. El gestor de despliegue arranca suficientes unidades de procesamiento para el pico previsto. |
|---|---|
| Enrutamiento | El grid de mensajería dirige las solicitudes por espectáculo y zona, de modo que todas las reservas provisionales de la zona 112 del espectáculo del sábado las gestiona la misma unidad. Las reservas provisionales de asientos nunca colisionan. |
| Un comprador selecciona dos asientos | La unidad los marca como HELD para este comprador durante 8 minutos, en memoria, en microsegundos, y responde. Los mapas de asientos de los demás compradores se actualizan mediante la replicación. |
| La reserva provisional se convierte en venta | Se ejecuta el paso de pago (una llamada externa, con una clave de idempotencia); si tiene éxito, la unidad marca los asientos como SOLD y una bomba de datos pone la venta en cola. |
| La base de datos | Los escritores de datos escriben las ventas a un ritmo constante que la base de datos puede sostener. Durante el pico, la cola crece; se vacía unos minutos después de que baje la demanda. Ninguna solicitud de un comprador espera a la base de datos. |
| Una reserva provisional caduca | La unidad libera los asientos en memoria; la bomba pone en cola un registro de liberación. |
Muchos sistemas de venta de entradas colocan además una sala de espera virtual delante de la venta, que admite a los compradores a un ritmo controlado. Es mucho más sencilla y a menudo basta por sí sola; la arquitectura basada en espacios es para cuando la propia carga admitida sigue siendo demasiado alta para un diseño centrado en la base de datos.
Enrutar por zona es la decisión de diseño que convierte el problema de las colisiones de "raro pero posible" en "imposible" para los datos que más importan.
Comparación de características (cualitativa, para diseños típicos)
| Característica | Serverless (FaaS y BaaS) | Basada en espacios |
|---|---|---|
| Elasticidad | Muy alta, automática, incluido el escalado a cero | Muy alta para los picos, pero las unidades tardan en arrancar y cargar los datos |
| Rendimiento | Bueno en caliente; los arranques en frío y los saltos de red añaden latencia | Muy alto: las solicitudes se atienden desde memoria |
| Perfil de costos | Pago por uso; excelente con inactividad o picos, caro con carga constante | Alto: muchas unidades, mucha memoria, middleware complejo, siempre activo |
| Simplicidad | Sencilla por función; el sistema completo puede volverse difícil de seguir | Baja: replicación, colisiones, bombas y carga en el arranque en frío |
| Consistencia | Lo que ofrezcan los almacenes de datos gestionados | La replicación en memoria es eventual salvo que los datos disputados se particionen; la base de datos va con retraso |
| Capacidad de prueba (testabilidad) | Las unidades son fáciles de probar; la integración necesita entornos en la nube | Difícil: probar con picos realistas es caro |
| Esfuerzo operativo | Bajo en infraestructura; alto en observabilidad y límites | Alto |
| Portabilidad | Baja: disparadores y servicios específicos del proveedor | Media: depende del producto de grid de datos |
Lista de comprobación: antes de elegir serverless o basada en espacios
Responde a estas preguntas con cifras medidas siempre que puedas.
- Forma del tráfico¿La carga tiene picos, está inactiva gran parte del tiempo o es constante? Serverless premia el tiempo inactivo; la arquitectura basada en espacios premia los picos extremos; la carga constante favorece los servicios normales siempre activos.
- Punto de cruce de costos¿Has calculado el costo por solicitud frente al costo de lo siempre activo con precios, duraciones y tráfico reales, incluidos el gateway, la transferencia de datos y las personas?
- Presupuesto de latencia¿La respuesta más lenta aceptable puede absorber un arranque en frío, o el salto de red hasta donde vive el estado?
- Límites¿Algún trabajo supera los límites de tiempo de ejecución, memoria o carga útil? ¿Puede dividirse en pasos o pasarse por referencia?
- Estado y conexiones¿Dónde vive cada tipo de estado, y pueden los almacenes de datos soportar ráfagas repentinas de conexiones concurrentes?
- Idempotencia¿Puede cada manejador ejecutarse dos veces sin riesgo para el mismo evento?
- ContenciónEn los diseños basados en espacios, ¿qué datos están disputados, y se particionarán o enrutarán para que no puedan colisionar?
- Durabilidad del retrasoSi el grid o las bombas fallan, ¿qué se pierde? ¿Las bombas son persistentes, y es aceptable el retraso de la base de datos para los informes y otros sistemas?
- Alternativas más sencillas¿La caché, las réplicas de lectura, una cola delante de la base de datos o una sala de espera virtual cubrirían la necesidad con menos complejidad?
- Decisión sobre la dependencia del proveedor¿Está registrado el acoplamiento al proveedor o al producto de grid como una decisión consciente, con la lógica de negocio detrás de puertos?
Comprueba lo que has entendido
¿Por qué debe ser idempotente una función activada por una cola?
Porque los disparadores asíncronos suelen entregar al menos una vez y reintentan en caso de fallo, así que el mismo evento puede invocar la función más de una vez.
Con los precios ilustrativos del ejemplo práctico, ¿cuánto costarían aproximadamente 50 millones de solicitudes al mes en serverless, y qué opción es más barata?
50 × £3.20 = £160 al mes, así que la opción siempre activa de £100 es más barata en costo bruto de infraestructura, antes de contar a las personas y otros cargos.
En la arquitectura basada en espacios, ¿qué hacen los lectores de datos y cuándo?
Cargan datos de la base de datos en los grids en memoria de las unidades de procesamiento cuando el grid arranca en frío, por ejemplo tras un reinicio o un nuevo despliegue completos; no se usan para las solicitudes normales.
¿De qué sirve dirigir todas las solicitudes de una zona del estadio a una sola unidad de procesamiento?
Solo esa unidad cambia esos asientos, así que dos unidades no pueden actualizar el mismo asiento antes de que la replicación se ponga al día, lo que elimina las colisiones de datos para esos datos.
Fuentes y lecturas recomendadas
¿Tienes una pregunta sobre esta sección? ArchitectBot, el asistente de estudio con IA del curso, responde primero a partir del curso.
Pregunta: “Nuestro sitio de venta de entradas se cae cada vez que sale a la venta un gran espectáculo. ¿Deberíamos pasar a serverless, a una arquitectura basada en espacios o a algo más sencillo, como una sala de espera?”