Plataforma de datos para cargas de trabajo crítica en Azure

En una arquitectura crítica, cualquier estado debe almacenarse fuera del proceso en la medida de lo posible. La elección de la tecnología se basa en estas características arquitectónicas clave:

Características Consideraciones
Rendimiento ¿Cuánto proceso se necesita?
Latencia ¿Qué impacto tendrá la distancia entre el usuario y el almacén de datos en la latencia? ¿Cuál es el nivel de coherencia deseado con la compensación de la latencia?
Capacidad de respuesta ¿Se requiere que el almacén de datos esté siempre disponible?
Escalabilidad ¿Cuál es el esquema de partición?
Durabilidad. ¿Se espera que los datos sean duraderos? ¿Cuál es la directiva de retención?
Resistencia En caso de error, ¿el almacén de datos es capaz de conmutar por error automáticamente? ¿Qué medidas se han tomado para reducir el tiempo de conmutación por error?
Seguridad ¿Se cifran los datos? ¿Se puede acceder al almacén de datos a través de la red pública?

En esta arquitectura, hay dos almacenes de datos:

  • Base de datos

    Stores relacionadas con la carga de trabajo. Se recomienda almacenar todo el estado globalmente en una base de datos independiente de los stamps regionales. Cree redundancia mediante la implementación de la base de datos en varias regiones. En el caso de las cargas de trabajo críticas, la sincronización de datos entre regiones debe ser la principal preocupación. Además, en caso de error, las solicitudes de escritura en la base de datos deben seguir siendo funcionales.

    La replicación de datos en una configuración activo-activo es muy recomendable. La aplicación debe poder conectarse al instante con otra región. Todas las instancias deben poder controlar las solicitudes de lectura y escritura.

  • Agente de mensajes

    El único servicio con estado en el stamp regional es el agente de mensajes, que almacena las solicitudes durante un breve periodo. El agente atiende la necesidad de almacenamiento en búfer y de mensajería confiable. Las solicitudes procesadas se conservan en la base de datos global.

Para conocer otras consideraciones sobre los datos, consulte Consideraciones sobre la plataforma de datos para cargas de trabajo críticas en Azure.

Base de datos

Esta arquitectura usa Azure Cosmos DB for NoSQL. Se elige esta opción porque proporciona la mayor cantidad de características necesarias en este diseño:

  • Escritura multirregional

    La escritura multirregional está habilitada con réplicas desplegadas en cada región en la que se implementa un stamp. Cada stamp puede escribir localmente y Azure Cosmos DB controla la replicación de datos y la sincronización entre los stamps. Esta capacidad reduce significativamente la latencia para los usuarios finales de la aplicación distribuidos geográficamente. La implementación de referencia de Azure Mission-Critical utiliza la tecnología de arquitectura multimaestro para proporcionar la máxima resistencia y disponibilidad.

    También está habilitada la redundancia de zona en cada región replicada.

    Para más información sobre las escrituras en varias regiones, consulte Configuración de escrituras en varias regiones en las aplicaciones que usan Azure Cosmos DB.

  • Administración de conflictos

    La capacidad de realizar escrituras en varias regiones conlleva la necesidad de adoptar un modelo de administración de conflictos, ya que las escrituras simultáneas pueden introducir conflictos de registro. Last Writer Wins es el modelo predeterminado y se utiliza para el diseño de Mission Critical. Last writer, definido por las marcas de tiempo asociadas de los registros, supera el conflicto. Azure Cosmos DB for NoSQL también permite definir una propiedad personalizada.

  • Optimización de las consultas

    Una recomendación general de eficiencia de consulta para los contenedores de lectura con un elevado número de particiones es añadir un filtro de igualdad con el ID del elemento identificado. Puede encontrar una revisión en profundidad de las recomendaciones de optimización de consultas en Solucionar problemas de consultas sobre incidencias al utilizar Azure Cosmos DB.

  • Característica de copia de seguridad

    Se recomienda utilizar la característica de copia de seguridad nativa de Azure Cosmos DB para la protección de datos. La característica de copia de seguridad de Azure Cosmos DB admite copias de seguridad en línea y restauración de datos bajo demanda.

Nota:

La mayoría de las cargas de trabajo no son puramente OLTP. Hay una creciente demanda de informes en tiempo real, como la ejecución de informes contra el sistema operativo. Esto también se denomina HTAP (procesamiento transaccional y analítico híbrido). Azure Cosmos DB soporta esta capacidad a través de Azure Synapse Link para Azure Cosmos DB.

Modelo de datos para la carga de trabajo

El modelo de datos se debe diseñar de forma que no sean necesarias las características que ofrecen las bases de datos relacionales tradicionales. Por ejemplo, claves externas, esquema de fila y columna estricto, vistas y otros.

La carga de trabajo tiene estas características de acceso a datos:

  • Patrón de lectura:
    • Lecturas puntuales: captura de un único registro. El ID del elemento y la clave de la partición se utilizan directamente para la máxima optimización (1 RU por solicitud).
    • Lecturas de lista: obtención de artículos del catálogo que se mostrarán en una lista. Se usa FeedIterator con un límite en el número de resultados.
  • Patrón de escritura:
    • Escrituras pequeñas - Las solicitudes suelen insertar un solo registro o un pequeño número de ellos en una transacción.
  • Diseñado para controlar el tráfico elevado de los usuarios finales con la capacidad de escalar para controlar la demanda de tráfico en el orden de millones de usuarios.
  • Carga o tamaño del conjunto de datos pequeño: normalmente en el orden de KB.
  • Tiempo de respuesta bajo (en el orden de milisegundos).
  • Baja latencia (en orden de milisegundos).

Configuración

Azure Cosmos DB está configurado de la siguiente manera:

  • El nivel de coherencia se establece en la coherencia de sesión predeterminada, ya que es el nivel más usado para aplicaciones distribuidas globalmente y de una sola región. No se necesita una coherencia más débil con un mayor rendimiento debido a la naturaleza asincrónica del procesamiento de escritura y no requiere una latencia baja en la escritura de base de datos.

    Nota:

    El nivel de coherencia de laSesión ofrece un equilibrio razonable entre la latencia, la disponibilidad y las garantías de consistencia para esta aplicación específica. Es importante comprender que el nivel de coherencia fuerte no está disponible para las bases de datos de escritura multimaestro.

  • La clave de partición se establece en /id para todas las colecciones. Esta decisión se basa en el patrón de utilización que es principalmente "escribir nuevos documentos con GUID como ID" y "leer una amplia gama de documentos por ID". Siempre que el código de la aplicación mantenga su identidad única, los nuevos datos son distribuidos uniformemente en particiones por Azure Cosmos DB, lo que permite una escala infinita.

  • Se configura la directiva de indexación en las colecciones para optimizar las consultas. Para optimizar el costo y el rendimiento de RU, se usa una directiva de indexación personalizada. Esta directiva solo indexa las propiedades que se utilizan en los predicados de consulta. Por ejemplo, la aplicación no usa el campo de texto de comentarios como filtro en las consultas. Se ha excluido de la directiva de indexación personalizada.

Este es un ejemplo de la implementación que muestra la configuración de la directiva de indexación mediante Terraform:

indexing_policy {

  excluded_path {
    path = "/description/?"
  }

  excluded_path {
    path = "/comments/text/?"
  }

  included_path {
    path = "/*"
  }

}

Para obtener información sobre la conexión de la aplicación a Azure Cosmos DB en esta arquitectura, consulteConsideraciones sobre la plataforma de la aplicación para cargas de trabajo de críticas

Servicios de mensajería

Los sistemas de misión crítica suelen utilizar servicios de mensajería para el procesamiento de mensajes o eventos. Estos servicios promueven el acoplamiento flexible y actúan como un búfer que aísla el sistema contra los picos inesperados de la demanda.

  • Azure Service Bus se recomienda para las cargas de trabajo basadas en mensajes cuando se manejan mensajes de alto valor.
  • Azure Event Hubs se recomienda para los sistemas basados en eventos que procesan grandes volúmenes de eventos o telemetría.

A continuación se exponen consideraciones y recomendaciones de diseño para Azure Service Bus premium y Azure Event Hubs en una arquitectura crítica.

Control de carga

El sistema de mensajería debe ser capaz de asumir el rendimiento requerido (en MB por segundo). Tenga en cuenta lo siguiente.

  • Los requisitos no funcionales (NFR) del sistema deben especificar el tamaño medio de los mensajes y el número máximo de mensajes/segundo que debe soportar cada stamp. Esta información puede utilizarse para calcular el pico de MB/segundo necesario por stamp.
  • Hay que tener en cuenta el impacto de una conmutación por error al calcular el pico de MB/segundo necesario por stamp.
  • En el caso del Azure Service Bus, los NFR deben especificar cualquier característica avanzada de Service Bus, como las sesiones y la eliminación de mensajes. Estas características afectarán al rendimiento de Service Bus.
  • El rendimiento de Service Bus con las características requeridas debe calcularse mediante pruebas como MB/segundo por Unidad de Mensajería (UM). Para más información sobre este tema, consulte los niveles de mensajería premium y estándar de Service Bus.
  • El rendimiento de los Azure Event Hubs debe calcularse mediante pruebas como MB/segundo por unidad de rendimiento (TU) para el nivel estándar o unidad de procesamiento (PU) para el nivel premium. Para más información sobre este tema, consulte Escaado con Event Hubs.
  • Los cálculos anteriores pueden utilizarse para validar que el servicio de mensajería puede asumir la carga requerida por stamp y el número de unidades de escalado necesarias para satisfacer esa carga.
  • En la sección de operaciones se hablará del autoescalado.

Cada mensaje debe ser procesado

El nivel premium de Azure Service Bus es la solución recomendada para los mensajes de alto valor cuyo procesamiento debe estar garantizado. A continuación se detallan los detalles de este requisito cuando se utiliza Azure Service Bus Premium:

  • Para garantizar que los mensajes se transfieren correctamente al agente y son aceptados por este, los productores de mensajes deben utilizar uno de los clientes de la API de Service Bus admitidos. Las APIs compatibles solo devolverán con éxito una operación de envío si el mensaje fue perseguido en la cola/tema.

  • Para asegurarte de que se procesan los mensajes de Service Bus, debes utilizar el modo de PeekLock. Este modo habilita el procesamiento al menos una vez. A continuación se describe el proceso:

    • El consumidor del mensaje recibe el mensaje para procesarlo.
    • El consumidor recibe un bloqueo exclusivo sobre el mensaje durante un tiempo determinado.
    • Si el consumidor procesa el mensaje con éxito, envía un acuse de recibo al intermediario y el mensaje se elimina de la cola.
    • Si el agente no recibe un acuse de recibo en el período de tiempo asignado, o el controlador abandona explícitamente el mensaje, se libera el bloqueo exclusivo. El mensaje está entonces disponible para que otros consumidores lo procesen.
    • Si un mensaje no se procesa correctamente un número configurable de veces, o el controlador reenvía el mensaje a la cola de mensajes fallidos.
      • Para garantizar que los mensajes enviados a la cola de mensajes fallidos sean atendidos, se debe supervisar la cola de mensajes fallidos y establecer alertas.
      • El sistema debe tener herramientas para que los operadores puedan inspeccionar, corregir y volver a enviar los mensajes.
  • Dado que los mensajes pueden ser procesados potencialmente más de una vez, los controladores de mensajes deben hacerse idempotentes.

Procesamiento de mensajes idempotente

En el RFC 7231, el Protocolo de transferencia de hipertexto afirma: "Un ... método se considera idempotente si el efecto previsto en el servidor de múltiples peticiones idénticas con ese método es el mismo que el efecto para una sola de esas peticiones".

Una técnica común de hacer que el control de mensajes sea idempotente es comprobar un almacén persistente, como una base de datos, si el mensaje ya se ha procesado. Si se ha procesado, no ejecutaría la lógica para procesarla de nuevo.

  • Puede haber situaciones en las que el procesamiento del mensaje incluye operaciones de base de datos, específicamente la inserción de nuevos registros con identificadores generados por la base de datos. Se pueden emitir mensajes nuevos al agente, que contienen esos identificadores. Dado que no hay transacciones distribuidas que abarcan la base de datos y el agente de mensajes, puede haber una serie de complicaciones que pueden producirse si el proceso que ejecuta el código produce un error. Consulta las siguientes situaciones de ejemplo:
    • El código que emite los mensajes puede ejecutarse antes de que se confirme la transacción de base de datos, que es el número de desarrolladores que trabajan con el patrón unidad de trabajo. Esos mensajes pueden escapar, si el error se produce entre llamar al agente y pedir que se confirme la transacción de base de datos. A medida que se revierte la transacción, esos identificadores generados por la base de datos también se deshacen, lo que los deja disponible para otro código que podría estar ejecutándose al mismo tiempo. Esto puede hacer que los destinatarios de los mensajes con escape procesen las entradas de base de datos incorrectas, lo que daña la coherencia general y la corrección del sistema.
    • Si los desarrolladores colocan el código que emite el mensaje una vez completada la transacción de base de datos, el proceso todavía puede producir un error entre estas operaciones (transacción confirmada: mensaje enviado). Cuando esto ocurra, el mensaje volverá a ser procesado, pero esta vez la cláusula de restricción de idempotencia verá que ya ha sido procesado (basándose en los datos almacenados en la base de datos). La cláusula omitirá el mensaje que emite código y creerá que todo se realizó correctamente la última vez. Los sistemas de bajada, que esperaban recibir notificaciones sobre el proceso completado, no reciben nada. Esta situación vuelve a generar un estado general de incoherencia.
  • La solución a los problemas anteriores implica el uso del patrón de Bandeja de Salida Transaccional, donde los mensajes salientes se almacenan a un lado, en el mismo almacén transaccional que los datos empresariales. A continuación, los mensajes se transmiten al agente de mensajes cuando el mensaje inicial se ha procesado correctamente.
  • Dado que muchos desarrolladores no están familiarizados con estos problemas o sus soluciones, con el fin de garantizar que estas técnicas se aplican de forma coherente en un sistema crítico, le sugerimos que tenga la funcionalidad de la bandeja de salida y la interacción con el agente de mensajes encapsulado en algún tipo de biblioteca. Todo el procesamiento de código y el envío de mensajes transaccionales significativos deben usar esa biblioteca, en lugar de interactuar directamente con el agente de mensajes.

Alta disponibilidad y recuperación ante desastres

El agente de mensajes debe estar disponible para que los productores envíen mensajes y los consumidores los reciban. A continuación se detallan los detalles de este requisito:

  • Para garantizar la máxima disponibilidad con Service Bus, utiliza el nivel premium, que tiene soporte para las zonas de disponibilidad en las regiones de apoyo. Gracias a las zonas de disponibilidad, los mensajes y los metadatos se replican en tres centros de datos distintos de la misma región.
  • Utilice los SDKs de Service Bus o Event Hubs compatibles para reintentar automáticamente los fallos de lectura o escritura.
  • Considere los patrones de replicación activo-activo oactivo-pasivo para aislarse de los desastres regionales.

Nota:

La recuperación ante desastres geográfica de Azure Service Bus solo replica los metadatos entre regiones. Esta característica no replica los mensajes.

Supervisión

El sistema de mensajería actúa como un búfer entre los productores y los consumidores de mensajes. Hay tipos de indicadores clave que debes supervisar en un sistema crítico que proporcionan información valiosa que se describe a continuación:

  • Limitación - La limitación indica que el sistema no tiene los recursos necesarios para procesar la solicitud. Tanto Service Bus como Event Hubs admiten la monitorización de las solicitudes limitadas. Debería alertar sobre este indicador.
  • Profundidad de la cola - Una profundidad de cola que crece puede indicar que los procesadores de mensajes no están funcionando o que no hay suficientes procesadores para manejar la carga actual. La profundidad de la cola puede utilizarse para informar a la lógica de autoescalado de los controladores.
    • Para Service Bus, la profundidad de la cola se expone como recuento de mensajes
    • En el caso de Event Hubs, los consumidores tienen que calcular la profundidad de la cola por partición y enviar la métrica a su software de monitorización. Para cada lectura, el consumidor obtiene el número de secuencia del evento actual y las propiedades del evento del último evento puesto en cola. El consumidor puede calcular la compensación.
  • Cola de mensajes fallidos - Los mensajes de la cola de mensajes fallidos representan mensajes que no han podido ser procesados. Estos mensajes suelen requerir una intervención manual. Las alertas deben establecerse en la cola de mensajes fallidos.
    • Service Bus tiene una cola de mensajes fallidos y una métrica de DeadLetteredMessages (mensajes fallidos).
    • En el caso de Event Hubs, esta funcionalidad debe ser una lógica personalizada integrada en el consumidor.
  • CPU/Utilización de la memoria - La CPU y la memoria deben ser monitorizadas para asegurar que el sistema de mensajería tiene suficientes recursos para procesar la carga actual. Tanto Service Bus premium como Event Hubs premium revelan la utilización de la CPU y la memoria.
    • Las unidades de mensajería (MU) se utilizan en Service Bus para aislar recursos como la CPU y la memoria de un espacio de nombres. El aumento de la CPU y la memoria por encima de un umbral puede indicar que no hay suficientes MUs configuradas, mientras que la caída por debajo de otros umbrales puede indicar que hay demasiadas MUs configuradas. Estos indicadores pueden utilizarse para autoescalar las MU.
    • Event Hubs Premium utiliza unidades de procesamiento (PUs) para aislar los recursos, mientras que el nivel estándar utiliza unidades de rendimiento (TUs). Esos niveles no requieren la interacción con la CPU/Memoria para auto-inflar los PUs o TUs.

Comprobación de estado

La salud del sistema de mensajería debe tenerse en cuenta en las comprobaciones de salud de una aplicación crítica. Tenga en cuenta los siguientes factores:

  • El sistema de mensajería actúa como un búfer entre los productores y los consumidores de mensajes. La marca se puede ver como correcta si los productores pueden enviar mensajes correctamente al agente y si los consumidores pueden procesar correctamente los mensajes del agente.
  • La comprobación de la salud debe asegurar que los mensajes pueden ser enviados al sistema de mensajes.

Pasos siguientes

Implemente la implementación de referencia para comprender completamente los recursos utilizados en esta arquitectura y su configuración.