Projetando aplicativos resilientes com SDKs do Azure Cosmos DB

APLICA-SE A: NoSQL

Ao criar aplicativos cliente que interagem com o Azure Cosmos DB por meio de qualquer um dos SDKs, é importante entender alguns fundamentos importantes. Este artigo é um guia de design para ajudá-lo a entender esses fundamentos e projetar aplicativos resilientes.

Descrição geral

Para obter uma visão geral em vídeo dos conceitos discutidos neste artigo, consulte:

Modos de conectividade

Os SDKs do Azure Cosmos DB podem se conectar ao serviço em dois modos de conectividade. Os SDKs .NET e Java podem se conectar ao serviço nos modos Gateway e Direct, enquanto os outros só podem se conectar no modo Gateway. O modo de gateway usa o protocolo HTTP e o modo Direct normalmente usa o protocolo TCP.

O modo de gateway é sempre usado para buscar metadados, como a conta, o contêiner e as informações de roteamento, independentemente do modo que o SDK está configurado para usar. Essas informações são armazenadas em cache na memória e usadas para se conectar às réplicas de serviço.

Em resumo, para SDKs no modo Gateway, você pode esperar tráfego HTTP, enquanto para SDKs no modo Direct, você pode esperar uma combinação de tráfego HTTP e TCP em circunstâncias diferentes (como inicialização, busca de metadados ou informações de roteamento).

Instâncias e conexões de clientes

Independentemente do modo de conectividade, é fundamental manter uma instância Singleton do cliente SDK por conta e por aplicativo. As conexões, HTTP e TCP, têm como escopo a instância do cliente. A maioria dos ambientes de computação tem limitações em termos do número de conexões que podem ser abertas ao mesmo tempo e, quando esses limites são atingidos, a conectividade será afetada.

Aplicações e redes distribuídas

Quando você projeta aplicativos distribuídos, há três componentes principais:

  • Seu aplicativo e o ambiente em que ele é executado.
  • A rede, que inclui qualquer componente entre seu aplicativo e o ponto de extremidade do serviço Azure Cosmos DB.
  • O ponto de extremidade do serviço Azure Cosmos DB.

Quando ocorrem falhas, elas geralmente se enquadram em uma dessas três áreas, e é importante entender que, devido à natureza distribuída do sistema, é impraticável esperar 100% de disponibilidade para qualquer um desses componentes.

O Azure Cosmos DB tem um conjunto abrangente de SLAs de disponibilidade, mas nenhum deles é 100%. Os componentes de rede que conectam seu aplicativo ao ponto de extremidade de serviço podem ter problemas de hardware transitórios e perder pacotes. Até mesmo o ambiente de computação em que seu aplicativo é executado pode ter um pico de CPU afetando as operações. Essas condições de falha podem afetar as operações dos SDKs e normalmente aparecem como erros com códigos específicos.

Seu aplicativo deve ser resiliente a um certo grau de falhas potenciais nesses componentes, implementando políticas de repetição sobre as respostas fornecidas pelos SDKs.

A minha aplicação deve repetir os erros?

A resposta curta é sim. Mas nem todos os erros fazem sentido para tentar novamente, alguns dos códigos de erro ou status não são transitórios. A tabela abaixo descreve-os em detalhe:

Código de Estado Deve adicionar nova tentativa Repetição de SDKs Description
400 No Não Mau pedido
401 No Não Não autorizado
403 Opcional Não Proibido
404 No Não O recurso não foi encontrado
408 Sim Sim Tempo limite de solicitação esgotado
409 No Não Falha de conflito é quando a identidade (ID e chave de partição) fornecida para um recurso em uma operação de gravação foi tomada por um recurso existente ou quando uma restrição de chave exclusiva foi violada.
410 Sim Sim Exceções eliminadas (falha transitória que não deve violar o SLA)
412 No Não Falha de pré-condição é quando a operação especificou um eTag que é diferente da versão disponível no servidor. É um erro de simultaneidade otimista. Repita o pedido depois de ler a versão mais recente do recurso e atualizar a eTag no pedido.
413 No Não Solicitar entidade muito grande
429 Sim Sim É seguro tentar novamente em um 429. Consulte o guia para solucionar problemas de HTTP 429.
449 Sim Sim Erro transitório que ocorre apenas em operações de gravação e é seguro para tentar novamente. Isso pode apontar para um problema de design em que muitas operações simultâneas estão tentando atualizar o mesmo objeto no Azure Cosmos DB.
500 No Não A operação falhou devido a um erro de serviço inesperado. Entre em contato com o suporte preenchendo um problema de suporte do Azure.
503 Sim Sim Serviço indisponível

Na tabela acima, todos os códigos de status marcados com Sim na segunda coluna devem ter algum grau de cobertura de repetição em seu aplicativo.

HTTP 403

Os SDKs do Azure Cosmos DB não tentam novamente em falhas HTTP 403 em geral, mas há certos erros associados ao HTTP 403 aos quais seu aplicativo pode decidir reagir. Por exemplo, se você receber um erro indicando que uma chave de partição está cheia, você pode decidir alterar a chave de partição do documento que está tentando escrever com base em alguma regra de negócios.

HTTP 429

Os SDKs do Azure Cosmos DB repetirão os erros HTTP 429 por padrão seguindo a configuração do cliente e honrando o cabeçalho de resposta x-ms-retry-after-ms do serviço, aguardando o tempo indicado e tentando novamente depois.

Quando as novas tentativas do SDK são excedidas, o erro é retornado ao seu aplicativo. Idealmente, inspecionar o x-ms-retry-after-ms cabeçalho na resposta pode ser usado como uma dica para decidir quanto tempo esperar antes de tentar novamente a solicitação. Outra alternativa seria um algoritmo de back-off exponencial ou configurar o cliente para estender as repetições no HTTP 429.

HTTP 449

Os SDKs do Azure Cosmos DB tentarão novamente no HTTP 449 com um back-off incremental durante um período de tempo fixo para acomodar a maioria dos cenários.

Quando as repetições automáticas do SDK são excedidas, o erro é devolvido à aplicação. Os erros HTTP 449 podem ser repetidos com segurança. Devido à natureza altamente simultânea das operações de escrita, é melhor ter um algoritmo de back-off aleatório para evitar repetir o mesmo grau de simultaneidade após um intervalo fixo.

Tempos limite de rede e falhas de conectividade estão entre os erros mais comuns. Os SDKs do Azure Cosmos DB são resilientes e repetirão tempos limite e problemas de conectividade nos protocolos HTTP e TCP se a nova tentativa for viável:

  • Para operações de leitura, os SDKs tentarão novamente qualquer erro relacionado ao tempo limite ou à conectividade.
  • Para operações de gravação, os SDKs não tentarão novamente porque essas operações não são idempotentes. Quando ocorre um tempo limite aguardando a resposta, não é possível saber se a solicitação chegou ao serviço.

Se a conta tiver várias regiões disponíveis, os SDKs também tentarão uma nova tentativa entre regiões.

Devido à natureza dos tempos limite e falhas de conectividade, eles podem não aparecer nas métricas da sua conta, pois cobrem apenas falhas que acontecem no lado do serviço.

É recomendável que os aplicativos tenham sua própria política de repetição para esses cenários e levem em consideração como resolver tempos limite de gravação. Por exemplo, tentar novamente em um tempo limite de criação pode gerar um HTTP 409 (Conflito) se a solicitação anterior chegou ao serviço, mas teria êxito se não chegasse.

Detalhes da implementação específica do idioma

Para mais detalhes sobre a implementação de uma língua, consulte:

As novas tentativas afetam a minha latência?

Do ponto de vista do cliente, qualquer nova tentativa afetará a latência de ponta a ponta de uma operação. Quando a latência do seu aplicativo P99 está sendo afetada, entender as novas tentativas que estão acontecendo e como resolvê-las é importante.

Os SDKs do Azure Cosmos DB fornecem informações detalhadas em seus logs e diagnósticos que podem ajudar a identificar quais novas tentativas estão ocorrendo. Para obter mais informações, consulte como coletar diagnósticos do SDK do .NET e como coletar diagnósticos do Java SDK.

Como posso reduzir a latência de novas tentativas?

Dependendo das circunstâncias, na maioria dos casos, o SDK encaminhará solicitações para a região local, a região de gravação (em um cenário de gravação de região única) ou a primeira região na lista de regiões preferidas. Essa priorização minimiza a latência em cenários íntegros, conectando-se principalmente ao data center mais próximo ou ideal.

No entanto, essa priorização também significa que as solicitações que resultarão em falha sempre serão tentadas em uma região específica primeiro para um determinado cenário de erro. Se o failover para outra região for preferido nesse cenário, isso normalmente será tratado na camada de infraestrutura (gerenciador de tráfego) em vez de no nível do SDK. A instalação e configuração adequadas de sua infraestrutura podem garantir que o tráfego seja redirecionado de forma eficiente durante interrupções regionais, reduzindo assim a latência que pode vir com novas tentativas entre regiões em um cenário de interrupção. Para obter informações mais detalhadas sobre como configurar o failover no nível da infraestrutura, consulte a documentação do Azure Traffic Manager. Alguns SDKs oferecem suporte à implementação de estratégias de failover semelhantes diretamente no nível do SDK. Por exemplo, consulte Alta disponibilidade para Java SDK.

E as interrupções regionais?

Os SDKs do Azure Cosmos DB cobrem a disponibilidade regional e podem executar novas tentativas em outras regiões da conta. Consulte o artigo Cenários e configurações de repetição de ambientes multirregionais para entender quais cenários envolvem outras regiões.

Quando contactar o apoio ao cliente

Antes de entrar em contato com o suporte ao cliente, siga estas etapas:

  • Qual é o impacto medido no volume de operações afetadas em comparação com as operações que têm sucesso? Está dentro dos SLAs de serviço?
  • A latência do P99 é afetada?
  • As falhas estão relacionadas a códigos de erro que meu aplicativo deve repetir e o aplicativo cobre essas tentativas?
  • As falhas estão a afetar todas as instâncias de aplicação ou apenas um subconjunto? Quando o problema é reduzido a um subconjunto de instâncias,geralmente, trata-se de um problema relacionado com essas instâncias.
  • Você passou pelos documentos de solução de problemas relacionados na tabela acima para excluir um problema no ambiente do aplicativo?

Se todas as instâncias de aplicativos forem afetadas, ou se a porcentagem de operações afetadas estiver fora dos SLAs de serviço ou afetando seus próprios SLAs de aplicativos e P99s, entre em contato com o suporte ao cliente.

Próximos passos