REL10-BP04 Usar arquitecturas herméticas para limitar el alcance del impacto - Pilar de fiabilidad

REL10-BP04 Usar arquitecturas herméticas para limitar el alcance del impacto

La implementación de arquitecturas herméticas (también conocidas como arquitecturas basadas en celdas) restringe el efecto del fallo dentro de una carga de trabajo a un número limitado de componentes.

Resultado deseado: una arquitectura basada en celdas utiliza numerosas instancias aisladas de una carga de trabajo, donde cada instancia se conoce como celda. Cada celda es independiente, no comparte estado con otras celdas y gestiona un subconjunto de las solicitudes de la carga de trabajo global. Esto reduce la posible repercusión de un error, como una actualización de software incorrecta, en una celda individual y en las solicitudes que está procesando. Si una carga de trabajo utiliza 10 celdas para atender 100 peticiones cuando se produce un error, el 90 % del total de las solicitudes no se verá afectado por el error.

Antipatrones usuales:

  • Permitir que las celdas crezcan sin límites.

  • Aplicar actualizaciones o despliegues de código a todas las celdas al mismo tiempo.

  • Compartir estado o componentes entre celdas (a excepción de la capa de enrutador).

  • Añadir lógica compleja de negocio o de enrutamiento a la capa de enrutador.

  • No minimizar las interacciones entre celdas.

Beneficios de establecer esta práctica recomendada: con las arquitecturas basadas en celdas, muchos tipos habituales de errores están contenidos dentro de la propia celda, lo que proporciona un aislamiento adicional de los errores. Estos límites de errores pueden proporcionar resiliencia contra tipos de errores que, de otro modo, serían difíciles de contener, como despliegues de código infructuosos o solicitudes que se corrompen o activan un modo de error concreto (también conocidas como solicitudes de píldora envenenada).

Guía para la implementación

En un barco, los mamparos garantizan que una brecha en el casco quede contenida en una sola sección del casco. En los sistemas complejos, este modelo de contención suele imitarse para facilitar el aislamiento de errores. Los límites aislados de los errores restringen el efecto de un error en una carga de trabajo a un número limitado de componentes. Los componentes fuera del límite no resultan afectados por el error. Mediante el uso de varios límites aislados de error, puede acotar el impacto en su carga de trabajo. En AWS, los clientes pueden utilizar varias zonas y regiones de disponibilidad para proporcionar aislamiento de errores, pero el concepto de aislamiento de errores también puede extenderse a la arquitectura de su carga de trabajo.

La carga de trabajo global se divide en celdas mediante una clave de partición. Esta clave tiene que alinearse con la corriente del servicio, o la forma natural en que la carga de trabajo de un servicio puede subdividirse con mínimas interacciones entre celdas. Algunos ejemplos de claves de partición son el ID de cliente, el ID de recurso o cualquier otro parámetro fácilmente accesible en la mayoría de las llamadas a la API. Una capa de enrutador de celdas distribuye las solicitudes a celdas individuales en función de la clave de partición, y presenta un único punto de conexión a los clientes.

Diagrama que muestra una arquitectura basada en celdas

Figura 11: Arquitectura basada en celdas

Pasos para la implementación

Al diseñar una arquitectura basada en celdas, hay que tener en cuenta varias consideraciones de diseño.

  1. Clave de partición: debe prestarse especial atención a la hora de elegir la clave de partición.

    • Debe alinearse con la corriente del servicio o con la forma natural en que la carga de trabajo de un servicio puede subdividirse con mínimas interacciones entre celdas. Algunos ejemplos son: ID de cliente o bien ID de recurso.

    • La clave de partición debe estar disponible en todas las solicitudes, ya sea de modo directo o de una manera que se pueda inferir con facilidad de forma determinista por otros parámetros.

  2. Asignación persistente de celdas: los servicios ascendentes solo deben interactuar con una única celda durante el ciclo de vida de sus recursos.

    • Según la carga de trabajo, puede ser necesaria una estrategia de migración de celda para migrar datos de una celda a otra. Un posible escenario en el que puede ser precisa una migración de celda es si un usuario o recurso concreto de la carga de trabajo crece demasiado y requiere una celda dedicada.

    • Las celdas no deben compartir estados ni componentes entre ellas.

    • En consecuencia, las interacciones entre celdas deben evitarse o mantenerse al mínimo, ya que dichas interacciones crean dependencias entre las celdas y, por lo tanto, disminuyen las ventajas en el aislamiento de errores.

  3. Capa de enrutador: la capa de enrutador es un componente compartido entre celdas, lo que significa que no puede seguir la misma estrategia de compartimentación que las celdas.

    • Se recomienda que la capa de enrutador distribuya las solicitudes a las celdas individuales mediante un algoritmo de asignación de particiones de una manera eficiente a nivel computacional, como la combinación de funciones hash criptográficas y aritmética modular para asignar claves de partición a las celdas.

    • Para evitar impactos multicelda, la capa de enrutador debe ser lo más simple y escalable horizontalmente posible, lo que requiere evitar una lógica de negocio compleja dentro de esta capa. Esto tiene la ventaja añadida de facilitar la comprensión de su comportamiento esperado en todo momento, lo que permite una comprobabilidad exhaustiva. Como explica Colm MacCárthaigh en Reliability, constant work, and a good cup of coffee (Fiabilidad, trabajo constante y una buena taza de café), los diseños sencillos y los patrones de trabajo constantes producen sistemas fiables y reducen la antifragilidad.

  4. Tamaño de la celda: las celdas deben tener un tamaño máximo y no debe permitirse que lo superen.

    • Para determinar el tamaño máximo, se deben llevar a cabo pruebas exhaustivas hasta que se alcancen puntos de ruptura y se establezcan márgenes de funcionamiento seguros. Para obtener más detalles sobre cómo implementar prácticas de prueba, consulte REL07-BP04 Realizar pruebas de su carga de trabajo

    • La carga de trabajo global crecerá a medida que se añadan celdas adicionales, lo que permite escalar la carga de trabajo con los aumentos de la demanda.

  5. Estrategias multi-AZ o en varias regiones: se deben aprovechar numerosas capas de resiliencia para ofrecer protección contra diferentes dominios de error.

    • Para obtener resiliencia, debe utilizar un enfoque que cree capas de defensa. Una capa protege de las interrupciones más pequeñas y frecuentes mediante la creación de una arquitectura de alta disponibilidad con múltiples AZ. Otra capa de defensa está pensada para proteger de eventos poco frecuentes, como las catástrofes naturales generalizadas y las interrupciones a nivel regional. Esta segunda capa implica la arquitectura de su aplicación para que abarque múltiples Regiones de AWS. La implementación de una estrategia multirregión para su carga de trabajo le ayuda a protegerla de catástrofes naturales generalizadas que afecten a una región geográfica amplia de un país o de errores técnicos de alcance regional. Tenga en cuenta que implementar una arquitectura multirregión puede ser significativamente complejo y no suele ser necesario para la mayoría de las cargas de trabajo. Para obtener más detalles, consulte REL10-BP02 Seleccionar las ubicaciones adecuadas para el despliegue en varias ubicaciones.

  6. Despliegue de código: se prefiere una estrategia de despliegue de código escalonado en lugar de desplegar los cambios de código en todas las celdas al mismo tiempo.

Nivel de riesgo expuesto si no se establece esta práctica recomendada: alto

Recursos

Prácticas recomendadas relacionadas:

Documentos relacionados:

Vídeos relacionados:

Ejemplos relacionados: