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 e falhas relacionadas à conectividade (HTTP 408/503)
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
- Saiba mais sobre cenários e configurações de repetição de ambientes multirregionais
- Revise os SLAs de disponibilidade
- Usar o SDK do .NET mais recente
- Use o Java SDK mais recente
- Use o SDK Python mais recente
- Usar o SDK do nó mais recente