Read in English · Lire en français · Auf Deutsch lesen
Capítulo 9 de 12 · De intermedio a avanzado
Rendimiento, escalabilidad, resiliencia y operabilidad
Este capítulo convierte los escenarios de rendimiento y disponibilidad del Capítulo 2 en sistemas que funcionan. Trata el escalado vertical y horizontal y el cubo de escalado, el balanceo de carga y los servicios sin estado, las colas, el back pressure y la limitación de tasa (rate limiting), los patrones de resiliencia que impiden que los fallos se propaguen (timeouts, reintentos, circuit breakers, bulkheads), los SLI, los SLO y los presupuestos de errores, la observabilidad con logs, métricas y trazas, la planificación de capacidad y las pruebas de rendimiento, y la ingeniería del caos y el aprendizaje a partir de incidentes. Está pensado para desarrolladores y arquitectos que conocen los estilos distribuidos del Capítulo 6 y deben mantener un sistema rápido y en funcionamiento bajo carga real.
Introducción en video al capítulo 9
7 min · narrado en inglés, con subtítulosSolo escuchar (audio)
Leer la transcripción
Te damos la bienvenida al Capítulo 9: Rendimiento, escalabilidad, resiliencia y operabilidad. Un diseño que cumple sus objetivos en un diagrama puede venirse abajo a las doce y media de un viernes, cuando todas las oficinas de la ciudad piden el almuerzo. La diferencia rara vez es un código ingenioso. Es un conjunto de decisiones arquitectónicas sobre cómo se añade capacidad, cómo se reparte la carga, cómo espera el trabajo, cómo se contienen los fallos y cómo saben las personas que operan el sistema qué está haciendo.
Este capítulo está pensado para desarrolladores y arquitectos que conocen los estilos distribuidos del Capítulo 6 y que deben mantener un sistema rápido y en funcionamiento bajo carga real. Se basa en el Capítulo 2, que hizo precisos el rendimiento y la disponibilidad como escenarios de atributos de calidad que se pueden probar. Aquí aprendes a lograr esos escenarios en un sistema en ejecución y a mantenerlos ciertos el día de más actividad del año. Remite al Capítulo 7 para la replicación, el particionamiento y la caché, en lugar de repetirlos. Y lleva al Capítulo 10, sobre las plataformas en la nube, las funcionalidades de Kubernetes y los diseños multirregión sobre los que suelen ejecutarse estos sistemas.
Dos ejemplos recurrentes recorren el capítulo. Una plataforma de reparto de comida, con picos muy marcados a la hora del almuerzo y por la noche. Y una puesta a la venta de entradas, en la que la demanda pasa de casi nada a muchas veces la capacidad del sistema en cuestión de segundos. La sección nueve punto uno compara el escalado vertical con el horizontal, usa el cubo de escalado para separar la clonación, la división por función y la división por datos, y explica por qué el autoescalado basado en la CPU suele ser la elección equivocada. La sección nueve punto dos trata de lo que se sitúa delante de las instancias: los balanceadores de carga, los algoritmos que usan, las comprobaciones de estado, el drenaje de conexiones y por qué las sesiones persistentes deben dar paso a un estado de sesión guardado fuera de la instancia. La sección nueve punto tres trata de lo que ocurre cuando el trabajo llega más deprisa de lo que se puede hacer: colas acotadas, back pressure, descarte de carga y limitación de tasa, que deciden qué se acepta, qué espera y qué se rechaza educadamente. La sección nueve punto cuatro se ocupa del fallo entre servicios: timeouts y plazos, reintentos con backoff y jitter, circuit breakers, bulkheads y alternativas.
El ejemplo práctico de la sección nueve punto cuatro muestra cómo la falta de un solo timeout permite que una única dependencia lenta tumbe todo lo que la llama. El proveedor de pagos responde normalmente en cero punto tres segundos. Hoy ha dejado de responder. El servicio de pedidos lo llama sin timeout, así que, uno a uno, sus doscientos hilos acaban esperando llamadas de pago. Ahora falla el proceso de pago. Pero también fallan el historial de pedidos y el seguimiento, que nunca tocan los pagos, porque no quedan hilos libres para atenderlos. La base de datos está perfectamente sana, pero no hay ningún hilo libre para llamarla. Los timeouts, los circuit breakers y los bulkheads son los patrones que detienen este tipo de cascada.
La segunda mitad pasa de los mecanismos a la operación. La sección nueve punto cinco muestra cómo expresar la fiabilidad desde el punto de vista del usuario y cómo un presupuesto de errores convierte un objetivo de disponibilidad en una cantidad de fallo permitido que los equipos pueden gastar en cambios. La sección nueve punto seis trata de los logs, las métricas y las trazas que permiten a los ingenieros hacer preguntas nuevas a un sistema en producción, y del trazado distribuido con OpenTelemetry. La sección nueve punto siete cierra el círculo entre las previsiones y la evidencia, con pruebas de carga, de estrés, de resistencia, de picos y de punto de ruptura, y un plan de capacidad para una puesta a la venta de entradas. Y la sección nueve punto ocho se ocupa de los fallos que ocurren de todos modos: experimentos deliberados para encontrar las debilidades antes que los clientes, roles claros durante los incidentes y revisiones sin culpas que cambian el sistema y no a las personas.
Este diagrama de la sección nueve punto cinco sitúa tres términos en una misma escala, usando la disponibilidad del proceso de pago durante veintiocho días móviles. El objetivo de nivel de servicio, o SLO, es la meta interna: aquí, el noventa y nueve punto nueve por ciento. El acuerdo de nivel de servicio, o SLA, es un contrato con los socios, fijado de forma menos exigente, en el noventa y nueve punto cinco por ciento. El indicador de nivel de servicio, o SLI, es la medición. Este mes es del noventa y nueve punto nueve cuatro por ciento, dentro de la zona en la que el servicio está dentro de su presupuesto. Por debajo del SLO, el objetivo no se cumple, y una política escrita de presupuesto de errores dice qué ocurre a continuación. Solo por debajo del SLA se deben créditos de servicio. El hueco entre el SLO y el SLA es la zona de aviso. El presupuesto de errores es simplemente uno menos el SLO. En treinta días, un objetivo del noventa y nueve punto nueve por ciento permite cuarenta y tres punto dos minutos de caída total, o que falle una solicitud de cada mil.
Las secciones forman una cadena y llevan a una sola idea. Todo recurso es finito, así que todo sistema tiene un punto de ruptura. El trabajo del arquitecto es decidir de antemano qué ocurre cuando se alcanza. Un sistema bien diseñado sometido a una carga excesiva se ralentiza de forma elegante y descarta primero el trabajo menos importante. Rechaza con claridad, en lugar de agotar el tiempo en silencio. Aísla la parte que falla. Y se recupera por sí solo cuando pasa la presión. Uno mal diseñado encola sin límite, reintenta hasta derrumbarse y arrastra consigo a sus vecinos. Estos mecanismos son baratos de añadir en la fase de diseño y caros de incorporar después. Si un servicio es sin estado, si una cola está acotada y si una solicitud lleva un plazo se decide mucho antes del primer incidente.
Al final del capítulo, sabrás elegir cómo escalar y dimensionar una flota para un pico conocido con la ley de Little y un margen de capacidad. Sabrás combinar timeouts, plazos, reintentos con backoff y jitter, circuit breakers, bulkheads y alternativas para contener los fallos. Sabrás definir indicadores y objetivos de nivel de servicio desde el punto de vista del usuario, calcular presupuestos de errores y diseñar alertas según la rapidez con que se gastan. Y sabrás planificar pruebas de capacidad y de rendimiento, ejecutar experimentos de caos de forma segura y dirigir revisiones posteriores a incidentes sin culpas.
Como las secciones forman una cadena, lo mejor es leerlas en orden. Pero cada una se sostiene también por sí sola, así que puedes ir directamente a la sección que necesites. Calcula unas tres horas y media para leer todo el capítulo. Al final de cada sección hay preguntas de autoevaluación. Respóndelas mentalmente antes de mirar las respuestas. Cuando estés listo, hay una prueba opcional del capítulo, que lleva unos cuarenta y cinco minutos. Tiene veinte preguntas de opción múltiple y dos respuestas escritas. La nota de aprobado es el ochenta por ciento.
Esa es la estructura del capítulo. Empieza por la sección nueve punto uno, sobre el escalado vertical, el escalado horizontal y el cubo de escalado. Nos vemos allí.
De un vistazo
Aprenderás a
- Elegir entre el escalado vertical y el horizontal y entre los ejes X, Y y Z del cubo de escalado, y dimensionar una flota para un pico conocido con la ley de Little y un margen de capacidad (headroom).
- Seleccionar señales y ajustes de autoescalado que eviten el retraso y el flapping (oscilación), y explicar por qué la CPU suele ser la métrica equivocada.
- Comparar el balanceo de carga de capa 4 y de capa 7 y los principales algoritmos, diseñar comprobaciones de estado y el drenaje de conexiones, y externalizar el estado de sesión.
- Aplicar colas, búferes acotados, back pressure, descarte de carga y limitación de tasa (incluido el token bucket) para mantener la sobrecarga bajo control.
- Combinar timeouts, plazos, reintentos con backoff y jitter, presupuestos de reintentos, circuit breakers, bulkheads y alternativas (fallbacks) para contener los fallos.
- Definir SLI y SLO desde el punto de vista del usuario, calcular presupuestos de errores y tasas de consumo (burn rates), y diseñar alertas basadas en ellos.
- Instrumentar un sistema con logs, métricas y trazas usando OpenTelemetry, y usar los métodos RED y USE para diagnosticar problemas.
- Planificar pruebas de capacidad y de rendimiento, ejecutar experimentos de caos de forma segura y dirigir revisiones posteriores a incidentes sin culpas.
Antes de empezar
El Capítulo 2, en especial las secciones sobre rendimiento y escalabilidad y sobre disponibilidad y fiabilidad; el Capítulo 6, en especial por qué distribuir, la comunicación y las API; y las secciones del Capítulo 7 sobre replicación, particionamiento y caché.
Tiempo
Unas 3½ horas de lectura; 45 minutos para la prueba.
Términos clave
cubo de escalado · autoescalado · servicio sin estado · balanceador de carga de capa 7 · poder de dos elecciones aleatorias (power of two choices) · back pressure (contrapresión) · descarte de carga (load shedding) · token bucket (cubeta de tokens) · circuit breaker (disyuntor) · bulkhead (mamparo) · presupuesto de errores · tasa de consumo (burn rate) · trazado distribuido · ingeniería del caos
De las cualidades sobre el papel a las cualidades en producción
El Capítulo 2 hizo precisos el rendimiento y la disponibilidad: percentiles de latencia, rendimiento (throughput), la ley de Little, la utilización y los nueves, escritos como escenarios de atributos de calidad que se pueden probar. Este capítulo trata de cómo lograr esos escenarios en un sistema en ejecución y de mantenerlos ciertos el día de más actividad del año. Un diseño que cumple sus objetivos en un diagrama puede venirse abajo a las 12:30 de un viernes, cuando todas las oficinas de la ciudad piden el almuerzo, o a las 10:00 de la mañana en que salen a la venta las entradas de un concierto. La diferencia entre ambos rara vez es un código ingenioso. Es un conjunto de decisiones arquitectónicas sobre cómo se añade capacidad, cómo se reparte la carga, cómo espera el trabajo, cómo se contienen los fallos y cómo saben las personas que operan el sistema qué está haciendo.
Dos ejemplos recurrentes recorren el capítulo. La plataforma de reparto de comida tiene un pico diario muy marcado a la hora del almuerzo y otro por la noche, decenas de servicios y dependencias de terceros como los proveedores de pago y las API de mapas. La puesta a la venta de entradas es el caso extremo: una demanda que pasa de casi nada a muchas veces la capacidad del sistema en cuestión de segundos, para un número fijo de asientos, con todo el país mirando. Entre los dos ponen a prueba todas las técnicas del capítulo.
Gestionar la carga: escalar, balancear y esperar
Las cuatro primeras secciones tratan de la carga. Estrategias de escalado compara el escalado vertical con el horizontal, usa el cubo de escalado de Abbott y Fisher para separar la clonación, la división por función y la división por datos, y explica por qué el autoescalado basado en la CPU suele ser la elección equivocada y cómo dimensionar una flota para un pico conocido con la ley de Little y un margen de capacidad. Balanceo de carga, ausencia de estado y sesiones trata de lo que se sitúa delante de las instancias: los balanceadores de carga de capa 4 y de capa 7, los algoritmos que usan (incluido el poder de dos elecciones aleatorias), las comprobaciones de estado que no dejan fuera de servicio una flota entera de golpe, el drenaje de conexiones y por qué las sesiones persistentes deben dar paso a un estado de sesión externalizado.
Asincronía, colas y back pressure trata de lo que ocurre cuando el trabajo llega más deprisa de lo que se puede hacer. Las colas convierten los picos en trabajo acumulado (backlog), lo cual solo es útil si ese trabajo acumulado está acotado y se vacía en un tiempo aceptable. El back pressure, el descarte de carga y la limitación de tasa deciden qué trabajo se acepta, cuál espera y cuál se rechaza educadamente con HTTP 429. Timeouts, reintentos, circuit breakers, bulkheads y degradación elegante se ocupa después del fallo entre servicios: timeouts y plazos, reintentos con backoff y jitter y los presupuestos que evitan las tormentas de reintentos, circuit breakers, bulkheads, alternativas (fallbacks), idempotencia y solicitudes de cobertura (hedged requests). Su ejemplo práctico muestra cómo la falta de un solo timeout permite que una única dependencia lenta tumbe todo lo que la llama.
Operar el sistema: objetivos, observabilidad, pruebas y aprendizaje
La segunda mitad pasa de los mecanismos a la operación. SLI, SLO, SLA y presupuestos de errores muestra cómo expresar la fiabilidad desde el punto de vista del usuario, cómo un presupuesto de errores convierte un objetivo de disponibilidad en una cantidad de fallo permitido que los equipos pueden gastar en cambios, y cómo las alertas por tasa de consumo (burn rate) avisan a las personas solo cuando ese presupuesto está realmente en peligro. Observabilidad trata de los logs, las métricas y las trazas que permiten a los ingenieros hacer preguntas nuevas a un sistema en producción, los métodos RED y USE y las cuatro señales doradas, el trazado distribuido con OpenTelemetry y el costo de los datos de alta cardinalidad.
Planificación de capacidad y pruebas de rendimiento cierra el círculo entre las previsiones y la evidencia: pruebas de carga, de estrés, de resistencia (soak), de picos y de punto de ruptura, modelos de carga abiertos y cerrados, la omisión coordinada (coordinated omission) y un plan de capacidad para una puesta a la venta de entradas. Ingeniería del caos, incidentes y aprendizaje sin culpas se ocupa de los fallos que ocurren de todos modos: experimentar deliberadamente en producción para encontrar las debilidades antes que los clientes, gestionar los incidentes con roles claros y celebrar revisiones sin culpas cuyas acciones cambian el sistema y no a las personas.
Cómo encajan las secciones
Las secciones forman una cadena. El escalado y el balanceo de carga añaden capacidad; las colas y el back pressure deciden qué ocurre cuando, aun así, la capacidad se agota; los patrones de resiliencia impiden que un problema local se convierta en uno global. Los SLO dicen cuándo algo es lo bastante bueno, la observabilidad muestra si el sistema cumple ese nivel y por qué no, las pruebas y la planificación de capacidad predicen cuándo dejará de cumplirlo, y la ingeniería del caos y las revisiones de incidentes encuentran las lagunas de todo lo anterior. La mayoría de los mecanismos son baratos de añadir en la fase de diseño y caros de incorporar después, y por eso son arquitectura y no un detalle de operaciones: si un servicio es sin estado, si una llamada es idempotente, si una cola está acotada y si una solicitud lleva un plazo se decide mucho antes del primer incidente.
El capítulo presupone los estilos distribuidos del Capítulo 6 y la arquitectura de datos del Capítulo 7. Remite a ellos para las claves de idempotencia, las garantías de entrega, la replicación y la caché en lugar de repetirlos, y adelanta el Capítulo 10 para las plataformas en la nube, las funcionalidades de Kubernetes y los diseños multirregión sobre los que suelen ejecutarse estos sistemas.
La idea que debes llevarte
Todo recurso es finito, así que todo sistema tiene un punto de ruptura; el trabajo del arquitecto es decidir de antemano qué ocurre cuando se alcanza. Un sistema bien diseñado sometido a una carga excesiva se ralentiza de forma elegante, descarta primero el trabajo menos importante, rechaza con claridad en lugar de agotar el tiempo en silencio, aísla la parte que falla y se recupera por sí solo cuando pasa la presión. Uno mal diseñado encola sin límite, reintenta hasta derrumbarse y arrastra consigo a sus vecinos. La diferencia está hecha de pequeñas decisiones deliberadas (un timeout aquí, una cola acotada allá, un presupuesto de reintentos, una comprobación de preparación) y del hábito de medir, probar y aprender del sistema tal como se ejecuta en realidad.
Las 8 secciones
Prueba del capítulo
Comprueba lo que has entendido del capítulo 9
Opcional: 20 preguntas de opción múltiple y 2 respuestas escritas breves, elegidas de nuevo cada vez de un banco de 72 preguntas. Nota de aprobado: 80%. Superar todas las pruebas de capítulo y después la evaluación final da derecho al Certificado de Finalización Be Wise.
Haz la prueba del capítulo 9 en la appLecturas recomendadas
- Release It! Design and Deploy Production-Ready Software (2nd edition), Michael T. Nygard (2018), Pragmatic Bookshelf. El libro que dio nombre a los patrones circuit breaker y bulkhead; sus patrones y antipatrones de estabilidad, ilustrados con caídas reales, son la base de la Sección 9.4.
- The Art of Scalability (2nd edition), Martin L. Abbott and Michael T. Fisher (2015), Addison-Wesley. Presenta el cubo de escalado y relaciona las decisiones técnicas de escalado con la organización y los procesos.
- Site Reliability Engineering: How Google Runs Production Systems, Betsy Beyer, Chris Jones, Jennifer Petoff and Niall Richard Murphy (editors) (2016), O'Reilly Media. Gratuito en línea; el origen de los SLO y los presupuestos de errores tal como se practican hoy, con excelentes capítulos sobre sobrecarga, fallos en cascada y post-mortems.
- The Site Reliability Workbook: Practical Ways to Implement SRE, Betsy Beyer, Niall Richard Murphy, David K. Rensin, Kent Kawahara and Stephen Thorne (editors) (2018), O'Reilly Media. El complemento práctico: cómo implementar los SLO, las alertas por tasa de consumo con varias ventanas y las guardias, con ejemplos prácticos.
- Exponential Backoff And Jitter, Marc Brooker (2015), AWS Architecture Blog. Un artículo breve basado en simulaciones que muestra por qué los reintentos necesitan esperas aleatorias; el origen de la fórmula de full jitter, muy utilizada.
- Systems Performance: Enterprise and the Cloud (2nd edition), Brendan Gregg (2020), Addison-Wesley. La referencia estándar sobre análisis de rendimiento, que incluye el método USE, las herramientas de observabilidad y los errores habituales en los benchmarks.
- Chaos Engineering: System Resiliency in Practice, Casey Rosenthal and Nora Jones (2020), O'Reilly Media. Escrito por profesionales de Netflix y de otras empresas; explica los principios de la ingeniería del caos y cómo la adoptan las organizaciones.
- Fail at Scale: Reliability in the face of rapid change, Ben Maurer (2015), ACM Queue, vol. 13, no. 8. Cómo gestiona Facebook la sobrecarga y las dependencias lentas con colas de retardo controlado, LIFO adaptativo y límites de concurrencia en el lado del cliente.