Ingeniería del caos: la armonía del desastre

Ingeniería del caos: la armonía del desastre

A medida que la computación en la nube, los sistemas distribuidos y los microservicios son protagonistas en la decisiones arquitectónicas de las empresas de software, nuestros sistemas son más complejos y las debilidades sistémicas son más frecuentes, por lo que garantizar la fiabilidad de las soluciones, desde todos los posibles escenarios, es un desafío.

Una de las disciplinas que en los últimos tiempos se ha fortalecido en el desarrollo de software para atacar esta problemática es la Ingeniería del Caos, la cual plantea que rompamos, nosotros mismos, nuestras soluciones de software para entender si se comportan debidamente ante situaciones de estrés.

La popular Ley de Murphy plantea: “Si algo puede pasar, pasará”, por lo que hemos de prepararnos para ello. No esperemos a incidentes para aplicar patrones de resiliencia o para aplicarlos bien en nuestros sistemas de software para evitar que fallen en los horarios productivos y los usuarios reciban una mala experiencia.

Si nosotros mismos experimentamos con las diferentes situaciones que hacen débiles a nuestra infraestructura o arquitectura, podremos tomar las medidas necesarias para robustecerlas.

Agreguemos latencias a servicios para ver si los tiempos de espera están bien definidos; apaguemos microservicios no esenciales para ver si seguimos ofreciendo un servicio mediante los que sí son esenciales en el flujo de negocio; estresemos el CPU o la RAM para ver si nuestra infraestructura responde como hemos definido en nuestras políticas de escalamiento o si se levantan los circuit breakers dando errores del tipo 5XX, por solo mencionar algunos ejemplos.

El origen del caos

La Ingeniería del Caos no es nueva. Surgió en 2010 a partir de iniciativas de Netflix durante la migración desde la infraestructura física a la nube (Rosenthal, & Jones, 2020). Pese a lo anterior, aún muchas empresas son escépticas y no la incorporan a su conjunto de herramientas para garantizar la confianza de sus soluciones, por lo intimidante para el negocio que puede llegar a ser si no se realiza de manera responsable y debidamente planificada. Por ello, es importante aprender de las lecciones aprendidas o buenas prácticas de los que ya han normalizado las pruebas de resiliencia en su saber hacer.

Afortunadamente, esta perspectiva está cambiando. El soporte tecnológico de herramientas comunitarias y licenciadas han aportado madurez y profesionalidad. Muchos roles la han incorporado a su conjunto de competencias de valor, como los DEVOPS, SRE (Site Reliability Engineering), ingenieros de performance o incluso roles (muchas empresas han creado posiciones directas para ingenieros del caos).

La armonía del desastre

Con la evolución de la disciplina se han definido y refinado varios principios de la Ingeniería del Caos que impulsan a hacer una correcta planificación, mitigando los riesgos y ganando objetividad. Estos principios son planteados a continuación (Rosenthal, & Jones, 2020):

1) Construye una hipótesis sobre el comportamiento de estado estacionario

Ante todo, es importante entender qué se considera un "estado estacionario", definido cómo el comportamiento normal de las métricas medibles del sistema, ya sean de performance o del negocio.

Es decir, cuáles son los valores esperados de la latencia, el índice de errores, el consumo de CPU, el índice de solicitudes procesadas, índice de ventas generadas, índice de sesiones abiertas en un periodo de tiempo o condiciones específicas, por solo mencionar algunos ejemplos. Se plantea desde la visión que serán igual tanto en el grupo de control como en el grupo experimental que tomemos para validar.

Cuando se  realizan ejercicios de experimentación para conocer las condiciones actuales de nuestro sistema, debemos de partir de la definición de la hipótesis que queremos validar. La misma se define en positivo con base en el estado estacionario. Si la validamos, podemos decir que estamos frente a una solución confiable y si el experimento aporta argumentos para refutarla, entonces hemos encontrado un comportamiento a investigar que puede resultar ser una oportunidad de mejora, un aprendizaje sobre nuestro sistema o alguna propiedad de la que no estábamos siendo conscientes.

Una hipótesis se plantea en dos partes fundamentales: la variable independiente y la dependiente, donde la primera  sería aquella que generamos nosotros para evaluar el resultado y la dependiente sería el resultado esperado (Sampieri, 2007).

Un ejemplo de hipótesis de un experimento de Ingeniería de Caos muy común es: Si genero una latencia de 500 ms al microservicio X, el servicio dependiente X va a generar timeout a las solicitudes realizadas a los 100 ms y reintentará a los 10 ms. Los tiempos de respuestas aumentarán, pero serán las solicitudes resueltas con éxito.

2) Varía los eventos del mundo real

Para que los experimentos de caos provean resultados realistas y objetivos, de igual manera deben ser las variables que insertamos: eventos del mundo real y específicos para el fenómeno en estudio y en la magnitud correcta para el comportamiento evaluado.

Un ejemplo puede ser cuando estamos en una arquitectura basada en el nivel de importancia del servicio, digamos servicios esenciales y no esenciales. Deseamos saber si realmente seguimos vendiendo sin problema sin cierto servicio no esencial. Para ello, debemos tener claro que el servicio esencial, ante la indisponibilidad de su dependencia, va a recibir un error 503 “Servicio no disponible”. No nos vale simular la indisponibilidad mediante latencia insertada, debido a que esto dispara otros mecanismos de resiliencia.

Es importante analizar el comportamiento del sistema ante situaciones de caos no segmentado por la visión del desarrollador, sino desde la posición de la experiencia de los usuarios. En dependencia del objetivo del experimento puede ir desde el punto de vista del usuario final del flujo de negocio, hasta la experiencia de usuario de los servicios clientes o dependientes que consumen un servicio en particular sobre el que queremos generar la variación.


3) Ejecuta experimentos en producción

¿Experimentar en producción? ¿Generar caos en producción? No parece una buena idea a priori, pero sí, sí lo es, aunque no para todos los casos. Soy consciente de que no es posible según algunos tipos de dominio de aplicación, normativas restrictivas sobre entornos productivos, o posibles barreras técnicas.

Pero no perdamos el foco de que el objetivo de la Ingeniería del Caos es descubrir el caos inherente a los sistemas complejos, no causarlo.  Si sabemos que un experimento va a generar un resultado no deseado, entonces no debemos realizar ese experimento. No nos disparemos en el pie.

Como en cualquier práctica de pruebas de software, nuestro principal objetivo es mitigar riesgos reducir la incertidumbre y aumentar la confianza. En ocasiones, incluso no sabemos que existen riesgos y ahí está la oportunidad de aprender. La evaluación del costo beneficio de experimentar para refutar una hipótesis es algo que siempre debe estar presente.

Por otra parte, no se recomienda que, si eres una empresa que nunca ha realizado ingeniería del caos, inicies directamente a experimentar en producción. Tiene mayor sentido que lo hagas previamente en entornos de prueba o staging mientras te preparas, aprendes y estableces las bases de la infraestructura tecnológicas para ello. Una vez que entiendes cómo funciona la herramienta de generación de caos y cuáles son los comportamientos esperados en general de tu sistema, podrás pasar gradualmente a producción.

En general, no se recomienda realizar caos en entornos alternativos, ya que es esperable diferenciales contra el entorno productivo que generarían ruidos en el experimento y afectaría la confianza de los resultados.

4) Automatiza los experimentos para que se ejecuten continuamente

Experimentar sobre soluciones complejas proclives a debilidades sistémicas no es una actividad que manualmente sea viable desarrollar, principalmente si aumentamos y diversificamos el conjunto de experimentos en busca de comportamientos no conocidos y riesgos potenciales.

La arquitectura de los sistemas de software, las tecnologías en las que se basan, la infraestructura en la que se despliegan y los enfoques de los equipos de desarrollo están todo el tiempo en constante cambio y evolución, por lo que nuevos estados estacionarios justifican nuevas iteraciones de experimentación. Entendiendo esto, las comunidades y empresas han visto un nicho de trabajo en herramientas que automatizan no solo la generación del caos a efectos prácticos, sino también desde la gestión y seguimiento del experimento de manera centralizada.

Podemos mencionar herramientas alternativas para esta práctica como Chaos Monkey, Toxiproxy, Chaos Mesh, Pumba, Litmus, Gremlin y AWS Fault Injection Simulator, entre otras. Algunas poseen  mayor madurez que otras, mayor posibilidad de profesionalización de la disciplina, modalidad Open Source o licenciadas, integrales o segmentadas por tipos de caos, pero todo esto lo abordaré en posteriores publicaciones de esta serie.

5) Minimizar el radio de explosión

Ninguno de los equipos que experimentan con caos desea que el impacto afecte más allá de lo planificado, pero ante arquitecturas de centenas de microservicios es necesario entender detalladamente todo el ecosistema de dependencias existente y cómo pueden verse afectadas. No siempre es humanamente posible controlar todos los casos. Ante esta incertidumbre, comparto varias lecciones aprendidas que he incorporado a mis procesos de experimentación:

  • Parece básico, pero es altamente recomendado entender exactamente cómo funciona la herramienta seleccionada de generación de caos a bajo nivel. Probarla en entornos seguros y evaluar si cumple con el comportamiento esperado para tu plan. En ocasiones, damos por sentado que aplicaciones de alta popularidad funcionan perfectamente, que aplican las variaciones de la misma forma que el resto utilizadas,  filtran bajo los mismos algoritmos o presentan las mismas restricciones, pero no siempre es así. Por lo tanto, prueba y entiende a profundidad qué realmente hace a nivel de aplicación, de infraestructura o de procesos. La confianza en la herramienta y el uso que le vas a dar es esencial.
  • Plantéate objetivos concretos y granulares, lo que se verá representado en la hipótesis. Entre más acotemos los componentes objetivo evaluados, más fiables serán las conclusiones. Debemos experimentar con la selección de un grupo de control representativo (no necesariamente debe considerarse todo). Un ejemplo sería cuando se está en una arquitectura multitenant, donde una solución es igual para cada tenant. ¿Por qué afectar a la totalidad si con una de ellas puedo extraer las mismas inferencias?
  • Limitar el alcance del experimento a un caos a la vez. Cada tipo de variables que incorporamos tiene patrones de resiliencia que se activan de manera distinta. Esto crea confusión en las conclusiones. Lo mismo sucede cuando una hipótesis es refutada en el peor de los casos, el tiempo de resolución y recuperación es significativo. Si desarrollamos una cadena de experimentos, ejecutaremos ejercicios distintos bajo un estado estacionario no real.

Si aplicas todos estos consejos aplicarás procesos de Ingeniería de Caos maduros, predecibles y con mayor probabilidad de éxito.

¡Inténtalo y diviértete en el proceso!

Referencias

⚠️
Las opiniones y comentarios emitidos en este artículo son propiedad única de su autor y no necesariamente representan el punto de vista de Revelo.

Revelo Content Network da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.