Diseño de aplicaciones resistentes con los SDK de Azure Cosmos DB

SE APLICA A: NoSQL

Al crear aplicaciones cliente que interactúan con Azure Cosmos DB mediante el uso de cualquiera de los SDK, es importante comprender algunos aspectos básicos clave. Este artículo constituye una guía de diseño que le ayudará a comprender estos aspectos básicos y diseñar aplicaciones resistentes.

Información general

A continuación, encontrará un vídeo introductorio a los conceptos que se describen en este artículo:

Modos de conectividad

Los SDK de Azure Cosmos DB pueden conectarse al servicio con dos modos de conectividad. Los SDK de .NET y Java pueden conectarse al servicio tanto en el modo de puerta de enlace como en el modo directo. En cambio, los demás SDK solo pueden conectarse en modo de puerta de enlace. El modo de puerta de enlace usa el protocolo HTTP y el modo directo suele usar el protocolo TCP.

Para capturar metadatos como la cuenta o la información de enrutamiento, siempre se usa el modo de puerta de enlace independientemente de en qué modo se configuró el SDK. Esta información se copia en caché en la memoria y se usa para conectarse a las réplicas de servicio.

En resumen, los SDK en modo de puerta de enlace usan tráfico HTTP y los SDK en modo directo usan una combinación de tráfico HTTP y TCP dependiendo de la circunstancia (por ejemplo: en la inicialización o para capturar metadatos).

Conexiones e instancias de cliente

Independientemente del modo de conectividad, es fundamental mantener una instancia singleton de cliente del SDK por cada cuenta y aplicación. Tanto las conexiones HTTP como las TCP tienen como ámbito la instancia de cliente. La mayoría de los entornos de proceso están limitados en cuanto al número de conexiones que pueden permanecer abiertas al mismo tiempo. Como consecuencia, si se alcanzan estos límites, la conectividad se verá afectada.

Redes y aplicaciones distribuidas

Al diseñar aplicaciones distribuidas, existen tres componentes clave:

  • La aplicación y el entorno donde se ejecuta.
  • La red, en la que se incluye cualquier componente entre la aplicación y el punto de conexión de servicio de Azure Cosmos DB.
  • El punto de conexión de servicio de Azure Cosmos DB.

Cuando se producen errores, estos suelen pertenecer a una de estas tres áreas. Además, es importante comprender que, debido a la naturaleza distribuida del sistema, es poco práctico esperar que cualquiera de estos componentes ofrezca una disponibilidad del 100 %.

Aunque Azure Cosmos DB ofrece un conjunto completo de Acuerdos de Nivel de Servicio de disponibilidad, ninguno de ellos la ofrece al 100 %. Los componentes de red que conectan a la aplicación con el punto de conexión de servicio pueden tener problemas transitorios de hardware y perder paquetes. También es posible, por ejemplo, que el entorno de proceso donde se ejecuta la aplicación experimente un pico en el uso de la CPU y este afecte a las operaciones. Estas condiciones de error pueden afectar a las operaciones de los SDK y normalmente aparecen en forma de errores con códigos concretos.

La aplicación debe poseer un cierto grado de resistencia ante posibles errores en estos componentes. Esto puede conseguirse mediante la implementación de directivas de reintento relacionadas con las respuestas que proporcionan los SDK.

¿Debe mi aplicación reintentar el proceso en caso de que se produzcan errores?

La respuesta rápida es . Sin embargo, no tiene sentido reintentar el proceso tras todos los errores, ya que algunos de los códigos de error o estado no son transitorios. La siguiente tabla describe estas consultas detalladamente:

Código de estado Debe incluir una operación de reintento Reintento de los SDK Descripción
400 No No Solicitud incorrecta
401 No No No autorizado
403 Opcional No Prohibido
404 No No No se encuentra el recurso
408 Se ha agotado el tiempo de espera para la solicitud
409 No No Los errores de conflicto ocurren si un recurso involucrado en una operación de escritura recibe una identidad (id. y clave de partición) que ya está usando otro recurso. También pueden producirse si se infringe una restricción de clave única.
410 Excepciones que ya no existen (error transitorio que no debería infringir el Acuerdo de Nivel de Servicio)
412 No No Un error en la condición previa se produce cuando la operación especificó un valor eTag que es diferente de la versión disponible en el servidor. Se trata de un error de simultaneidad optimista. Vuelva a intentar la solicitud después de leer la versión más reciente del recurso y de actualizar el valor eTag en la solicitud.
413 No No Entidad de solicitud demasiado grande
429 Es seguro reintentar el proceso con errores de tipo 429. Consulte la guía para solucionar problemas de HTTP 429.
449 Error transitorio que solo se produce en las operaciones de escritura y para el que es seguro realizar el reintento. Esta situación puede indicar un problema de diseño en virtud del cual un número demasiado elevado de operaciones simultáneas intentan actualizar el mismo objeto en Azure Cosmos DB.
500 No No No se pudo realizar la operación debido a un error de servicio inesperado. Abra una incidencia para ponerse en contacto con el Soporte técnico de Azure.
503 Servicio no disponible

En la tabla anterior, todos los códigos de estado marcados con un en la segunda columna deben tener cierto grado de cobertura para las operaciones de reintento en la aplicación.

HTTP 403

Por lo general, los SDK de Azure Cosmos DB no llevan a cabo reintentos frente a los errores HTTP 403. Sin embargo, hay ciertos errores asociados con HTTP 403 que podrían hacer que la aplicación decida reaccionar. Por ejemplo, si recibe un error que indica que hay una clave de partición llena, puede definir una regla de negocio que modifique la clave de partición del documento que está intentando escribir.

HTTP 429

Los SDK de Azure Cosmos DB llevan a cabo reintentos frente a los errores HTTP 429 de forma predeterminada, de acuerdo con la configuración del cliente y respetando el encabezado de respuesta x-ms-retry-after-ms del servicio. Este encabezado define el tiempo que transcurre antes del reintento.

Si se supera el límite de reintentos del SDK, se devuelve el error a la aplicación. Para decidir el tiempo que debe transcurrir antes de reintentar enviar la solicitud, lo ideal es inspeccionar el encabezado x-ms-retry-after-ms de la respuesta. También existen otras alternativas, como usar un algoritmo de interrupción exponencial o configurar el cliente para que amplíe el número de reintentos para los errores HTTP 429.

HTTP 449

Los SDK de Azure Cosmos DB llevan a cabo reintentos frente a los errores HTTP 449 y usan interrupciones incrementales durante un periodo fijo de tiempo para adaptarse a la mayoría de escenarios.

Si se supera el límite de reintentos automáticos del SDK, se devuelve el error a la aplicación. Los errores HTTP 449 se pueden reintentar de forma segura. Debido a la naturaleza altamente simultánea de las operaciones de escritura, lo mejor es usar un algoritmo de interrupción aleatorio para evitar que se repita el mismo grado de simultaneidad después de intervalos fijos.

Los tiempos de espera de red y los errores de conectividad son algunos de los errores más comunes. Los SDK de Azure Cosmos DB son resistentes y, si la opción de reintento es factible, la llevarán a cabo según los tiempos de espera y los problemas de conectividad de los protocolos HTTP y TCP:

  • En el caso de las operaciones de lectura, los SDK llevan a cabo reintentos de cualquier error relacionado con el tiempo de espera o la conectividad.
  • En el caso de las operaciones de escritura, los SDK no llevan a cabo reintentos, ya que estas operaciones no son idempotentes. Cuando se agota el tiempo de espera de una respuesta, no es posible saber si la solicitud llegó al servicio.

Si la cuenta tiene varias regiones disponibles, los SDK también intentarán llevar a cabo reintentos entre regiones.

Debido a la naturaleza de los tiempos de espera y los errores de conectividad, es posible que estos no aparezcan en las métricas de la cuenta, ya que estas solo documentan los errores que se producen en el lado del servicio.

Se recomienda que las aplicaciones tengan su propia directiva de reintentos para estos escenarios y que se tenga en cuenta cómo resolver los tiempos de espera de escritura. Por ejemplo, llevar a cabo un reintento frente a un tiempo de espera de creación puede producir un error HTTP 409 (conflicto) si la solicitud anterior llegó al servicio, o puede completarse correctamente si esta no llegó.

Detalles de implementación específicos del lenguaje

Para más detalles sobre la implementación de un lenguaje específico, consulte:

¿Afectan los reintentos a mi latencia?

Desde la perspectiva de cliente, cualquier reintento de una operación afectará a la latencia de un extremo a otro. Cuando la latencia de la aplicación se ve afectada en el P99 (percentil 99), es importante comprender los reintentos que se están produciendo y cómo abordarlos.

La información detallada que proporcionan los registros y diagnósticos de los SDK de Azure Cosmos DB puede ayudarle a identificar qué reintentos se están llevando a cabo. Para obtener más información, consulte los siguientes artículos sobre cómo recopilar diagnósticos del SDK de .NET y cómo recopilar diagnósticos del SDK de Java.

¿Y qué sucede con las interrupciones regionales?

Los SDK de Azure Cosmos DB ya contemplan la disponibilidad regional, por lo que pueden realizar reintentos en otras regiones de cuenta. Consulte el siguiente artículo sobre escenarios de reintento y configuraciones de entornos multiregionales para saber qué escenarios implican a otras regiones.

Cuándo ponerse en contacto con asistencia al cliente

Antes de ponerse en contacto con el departamento de asistencia al cliente, siga estos pasos:

  • ¿Qué impacto tiene el problema, si se mide comparando el volumen de operaciones afectadas con el de operaciones que sí se realizaron correctamente? ¿Es este valor aplicable a los Acuerdos de Nivel de Servicio?
  • ¿Se ve afectada la latencia en el percentil 99 (P99)?
  • ¿Se deben los errores a códigos de error tras los cuales la aplicación debe llevar a cabo reintentos? Si es así, ¿realiza la aplicación esos reintentos?
  • ¿Afectan los errores a todas las instancias de la aplicación, o solo a un subconjunto? Si el problema se reduce a un subconjunto de instancias, normalmente se trata de un problema relacionado con ellas.
  • ¿Ha consultado la documentación para la solución de problemas de la tabla anterior para descartar un problema en el entorno de la aplicación?

Si el problema afecta a todas las instancias de la aplicación, a un porcentaje de operaciones que no es aplicable a los Acuerdos de Nivel de Servicio, o a los Acuerdos de Nivel de Servicio y P99 propios de su aplicación, póngase en contacto con el servicio de asistencia al cliente.

Pasos siguientes