Diagnosticar e solucionar exceções com a taxa de solicitação muito grande no Azure Cosmos DB (429)
APLICA-SE A: NoSQL
Este artigo contém causas e soluções conhecidas para vários erros de código de status 429 para a API para NoSQL. Se você estiver usando a API para MongoDB, consulte o artigo Solucionar problemas comuns na API para MongoDB para saber como depurar o código de status 16500.
Uma exceção chamada "taxa de solicitação muito grande", também conhecida como código de erro 429, indica que suas solicitações em relação ao Azure Cosmos DB estão sendo limitadas por taxa.
Ao usar a taxa de transferência provisionada, você define a taxa de transferência, medida em unidades de solicitação por segundo (RU/s), que são necessárias para sua carga de trabalho. As operações de banco de dados em relação ao serviço, como leituras, gravações e consultas, consomem um certo número de RUs (unidades de solicitação). Saiba mais sobre unidades de solicitação.
Em um determinado segundo, se as operações consumirem mais do que as unidades de solicitação provisionadas, o Azure Cosmos DB retornará uma exceção 429. A cada segundo, o número de unidades de solicitação disponíveis para uso é redefinido.
Antes de executar uma ação para alterar as RU/s, é importante entender a causa raiz da limitação de taxa e resolver o problema subjacente.
Dica
As diretrizes neste artigo se aplicam a bancos de dados e contêineres usando a produtividade provisionada – tanto o dimensionamento automático quanto a taxa de transferência manual.
Há diferentes mensagens de erro que correspondem a diferentes tipos de exceção 429:
- A taxa de solicitação é grande. Mais Unidades de Solicitação podem ser necessárias, portanto, nenhuma alteração foi feita.
- A solicitação não foi concluída devido a uma alta taxa de solicitações de metadados.
- A solicitação não foi concluída devido a um erro de serviço temporário.
A taxa de solicitação é alta
Esse é o cenário mais comum. Isso ocorre quando as unidades de solicitação consumidas por operações em dados excedem o número provisionado de RU/s. Se você estiver usando a taxa de transferência manual, isso ocorrerá quando você tiver consumido mais RU/s do que a taxa de transferência manual provisionada. Se você estiver usando o dimensionamento automático, isso ocorrerá quando você tiver consumido mais do que o máximo de RU/s provisionadas. Por exemplo, se você tiver um recurso provisionado com uma taxa de transferência manual de 400 RU/s, verá 429 quando consumir mais de 400 unidades de solicitação em um único segundo. Se você tiver um recurso provisionado com o dimensionamento automático máximo de RU/s de 4000 RU/s (dimensionado entre 400 RU/s a 4000 RU/s), verá 429 respostas quando consumir mais de 4000 unidades de solicitação em um único segundo.
Dica
Todas as operações são cobradas com base no número de recursos que elas consomem. Esses preços são medidos em unidades de solicitação. Essas cobranças incluem solicitações que não foram concluídas com êxito devido a erros de aplicativo, como 400
, 412
, 449
, etc. Ao analisar a limitação ou o uso, é uma boa ideia investigar se algum padrão mudou em seu uso, o que resultaria em um aumento dessas operações. Especificamente, verifique as marcas 412
ou 449
(conflito real).
Para saber mais sobre a taxa de transferência provisionada, confira a taxa de transferência provisionada no Azure Cosmos DB.
Etapa 1: Verificar as métricas para determinar o percentual de solicitações com o erro 429
Ver 429 mensagens de erro não significa necessariamente que há um problema com seu banco de dados ou contêiner. Uma pequena porcentagem de 429 respostas é normal se você estiver usando a taxa de transferência manual ou de dimensionamento automático e é um sinal de que você está maximizando as RU/s provisionadas.
Como investigar
Determine qual percentual de suas solicitações para seu banco de dados ou contêiner resultou nas 429 respostas, em comparação com a contagem geral de solicitações bem-sucedidas. Na sua conta do Azure Cosmos DB, navegue até Insights>Solicitações>Total de Solicitações por Código de Status. Filtre para um banco de dados e contêiner específicos.
Por padrão, os SDKs de cliente do Azure Cosmos DB e as ferramentas de importação de dados, como Azure Data Factory e biblioteca de executores em massa, retentam automaticamente em 429s. Eles são repetidos normalmente até nove vezes. Como resultado, embora você possa ver as 429 respostas nas métricas, esses erros podem nem mesmo ser retornados ao seu aplicativo.
Solução recomendada
Em geral, para uma carga de trabalho de produção, se você vir de 1 a 5% das solicitações com 429 respostas e sua latência de ponta a ponta for aceitável, isso é um sinal saudável de que as RUs estão sendo totalmente utilizadas. Nenhuma ação é necessária. Caso contrário, vá para as próximas etapas de solução de problemas.
Importante
Esse intervalo de 1 a 5% pressupõe que as partições da conta sejam distribuídas uniformemente. Se as partições não forem distribuídas uniformemente, a partição com problema poderá retornar uma grande quantidade de erros 429, enquanto a taxa geral poderá ser baixa.
Se você estiver usando o dimensionamento automático, será possível ver 429 respostas em seu banco de dados ou contêiner, mesmo que as RU/s não tenham sido dimensionadas para o máximo de RU/s. Confira a seção A taxa de solicitação é grande com o dimensionamento automático para obter uma explicação.
Uma pergunta comum que surge é: "Por que estou vendo 429 respostas nas métricas do Azure Monitor, mas nenhuma no meu próprio monitoramento de aplicativos?" Se as métricas do Azure Monitor mostrarem que você tem 429 respostas, mas você não viu nenhuma em seu próprio aplicativo, isso ocorre porque, por padrão, os SDKs do cliente Azure Cosmos DB automatically retried internally on the 429 responses
e a solicitação tiveram êxito nas tentativas subsequentes. Como resultado, o código de status 429 não é retornado ao aplicativo. Nesses casos, a taxa geral de 429 respostas normalmente é muito baixa e pode ser ignorada com segurança, supondo que a taxa geral esteja entre 1% a 5% e a latência de ponta a ponta seja aceitável para seu aplicativo.
Etapa 2: determinar se há uma partição em chamas
Uma partição em chamas ocorre quando uma ou algumas chaves de partição lógicas consomem uma quantidade desproporcional do total de RU/s devido a um volume de solicitação mais alto. Isso pode ser causado por um design de chave de partição que não distribui as solicitações de maneira uniforme. Isso resulta em muitas solicitações sendo direcionadas para um pequeno subconjunto de partições lógicas (o que implica físicas) que se tornam "em chamas". Como todos os dados de uma partição lógica residem em uma partição física e o total de RU/s é distribuído uniformemente entre as partições físicas, uma partição em chamas pode levar a 429 respostas e uso ineficiente da taxa de transferência.
Aqui estão alguns exemplos de estratégias de particionamento que levam a partições em chamas:
- Você tem um contêiner que armazena dados do dispositivo IoT para uma intensa carga de trabalho de gravação particionada por
date
. Todos os dados de uma única data residirão na mesma partição lógica e física. Como todos os dados gravados todos os dias têm a mesma data, isso resultaria em uma partição em chamas todos os dias.- Em vez disso, para esse cenário, uma chave de partição como
id
(uma GUID ou ID do dispositivo) ou uma chave de partição sintética que combineid
edate
produziriam uma cardinalidade maior de valores e melhor distribuição do volume de solicitação.
- Em vez disso, para esse cenário, uma chave de partição como
- Você tem um cenário multilocatário com um contêiner particionado por
tenantId
. Se um locatário estiver muito mais ativo do que os outros, isso resulta em uma partição em chamas. Por exemplo, se o maior locatário tiver 100 mil usuários, mas a maioria dos locatários tiver menos de 10 usuários, você terá uma partição em chamas quando particionada pelatenantID
.- Para este cenário anterior, considere ter um contêiner dedicado para o maior locatário, particionado por uma propriedade mais granular, como
UserId
.
- Para este cenário anterior, considere ter um contêiner dedicado para o maior locatário, particionado por uma propriedade mais granular, como
Como identificar a partição em chamas
Para verificar se há uma partição em chamas, navegue até Insights>Taxa de Transferência>Consumo de RU Normalizado (%) Por PartitionKeyRangeID. Filtre para um banco de dados e contêiner específicos.
Cada PartitionKeyRangeId é mapeada para uma partição física. Se houver um PartitionKeyRangeId que tenha um consumo de RU normalizado muito maior do que outros (por exemplo, um está consistentemente em 100%, mas outros estão em 30% ou menos), isso pode ser um sinal de uma partição em chamas. Saiba mais sobre a Métrica de Consumo de RU Normalizado.
Para ver quais chaves de partição lógica estão consumindo a maioria das RU/s, use os Logs de Diagnóstico do Azure. Esta consulta de exemplo soma o total de unidades de solicitação consumidas por segundo em cada chave de partição lógica.
Importante
A habilitação de logs de diagnóstico incorre em um custo separado para o serviço Log Analytics, que é cobrado com base no volume de dados ingeridos. É recomendável ativar os logs de diagnóstico por um período limitado para depuração e desligar quando não for mais necessário. Confira a página de preços para obter detalhes.
CDBPartitionKeyRUConsumption
| where TimeGenerated >= ago(24hour)
| where CollectionName == "CollectionName"
| where isnotempty(PartitionKey)
// Sum total request units consumed by logical partition key for each second
| summarize sum(RequestCharge) by PartitionKey, OperationName, bin(TimeGenerated, 1s)
| order by sum_RequestCharge desc
Esse exemplo de saída mostra que em um minuto específico, a chave de partição lógica com o valor "Contoso" consumiu cerca de 12.000 RU/s, enquanto a chave de partição lógica com o valor "Fabrikam" consumiu menos de 600 RU/s. Se esse padrão fosse consistente durante o período em que a limitação de taxa ocorreu, isso indicaria uma partição em chamas.
Dica
Em qualquer carga de trabalho, haverá variação natural no volume de solicitação em partições lógicas. Você deve determinar se a partição ativa é causada por uma distorção fundamental devido à escolha da chave de partição (que pode exigir a alteração da chave) ou ao pico temporário devido à variação natural nos padrões de carga de trabalho.
Solução recomendada
Examine as diretrizes sobre como escolher uma boa chave de partição.
Se houver uma porcentagem alta de solicitações limitadas por taxa e nenhuma partição em chamas:
- Você pode aumentar as RU/s no banco de dados ou contêiner usando os SDKs do cliente, portal do Azure, PowerShell, CLI ou modelo ARM. Siga as melhores práticas para dimensionar a taxa de transferência provisionada (RU/S) para determinar as RU/S corretas a serem definidas.
Se houver uma porcentagem alta de solicitações limitadas por taxa e houver uma partição em chamas subjacente:
- A longo prazo, para obter melhor custo e desempenho, considere alterar a chave de partição. A chave de partição não pode ser atualizada no local, portanto, isso requer a migração dos dados para um novo contêiner com uma chave de partição diferente. O Azure Cosmos DB dá suporte a uma ferramenta de migração de dados dinâmicos para essa finalidade.
- No curto prazo, você pode aumentar temporariamente as RU/s gerais do recurso para permitir mais taxa de transferência para a partição ativa. Isso não é recomendado como uma estratégia de longo prazo, pois leva a um excesso de provisionamento de RU/s e de custo mais alto.
- No curto prazo, você pode usar o recurso de redistribuição de taxa de transferência entre partições (versão prévia) para atribuir mais RU/s à partição física ativa. Isso é recomendado somente quando a partição física ativa é previsível e consistente.
Dica
Quando você aumenta a taxa de transferência, a operação de expansão será concluída instantaneamente ou precisará de até 5-6 horas para ser concluída, dependendo do número de RU/s para o qual você deseja escalar verticalmente. Se você quiser saber o número mais alto de RU/s que pode definir sem disparar a operação de expansão assíncrona (que requer que o Azure Cosmos DB provisione mais partições físicas), multiplique o número de PartitionKeyRangeIds distintos por 10, 0000 RU/s. Por exemplo, se você tiver 30.000 RU/s provisionadas e 5 partições físicas (6000 RU/s alocadas por partição física), poderá aumentar para 50.000 RU/s (10.000 RU/s por partição física) em uma operação de expansão instantânea. Aumentar para > 50.000 RU/s exigiria uma operação de expansão assíncrona. Saiba mais sobre as Melhores práticas para o dimensionamento de taxa de transferência provisionada (RU/s).
Etapa 3: determinar quais solicitações estão retornando 429 respostas
Como investigar solicitações com 429 respostas
Use os Logs de Diagnóstico do Azure para identificar quais solicitações estão retornando 429 respostas e quantos elas RUs consumiram. Essa consulta de exemplo é agregada a nível de minuto.
Importante
A habilitação de logs de diagnóstico incorre em um custo separado para o serviço Log Analytics, que é cobrado com base no volume de dados ingeridos. É recomendável ativar os logs de diagnóstico por um período limitado para depuração e desligar quando não for mais necessário. Confira a página de preços para obter detalhes.
CDBDataPlaneRequests
| where TimeGenerated >= ago(24h)
| summarize throttledOperations = dcountif(ActivityId, StatusCode == 429), totalOperations = dcount(ActivityId), totalConsumedRUPerMinute = sum(RequestCharge) by DatabaseName, CollectionName, OperationName, RequestResourceType, bin(TimeGenerated, 1min)
| extend averageRUPerOperation = 1.0 * totalConsumedRUPerMinute / totalOperations
| extend fractionOf429s = 1.0 * throttledOperations / totalOperations
| order by fractionOf429s desc
Por exemplo, esse exemplo de saída mostra que a cada minuto, 30% das solicitações de Criação de Documento estavam sendo limitadas por taxa, com cada solicitação consumindo uma média de 17 RUs.
Solução recomendada
Usar o planejador de capacidade Azure Cosmos DB
É possível usar o planejador de capacidade do Azure Cosmos DB para entender qual é a melhor taxa de transferência provisionada com base em sua carga de trabalho (volume e tipo de operações e tamanho de documentos). É possível personalizar os cálculos fornecendo dados de exemplo para obter uma estimativa mais precisa.
429 respostas em solicitações de criação, substituição ou upsert de documento
- Por padrão, na API para NoSQL, todas as propriedades são indexadas por padrão. Ajuste a política de indexação para indexar apenas as propriedades necessárias. Isso reduzirá as Unidades de Solicitação necessárias por operação de criação de documento, o que reduzirá a probabilidade de ver 429 respostas ou permitirá que você alcance operações mais altas por segundo para a mesma quantidade de RU/s provisionadas.
429 respostas em solicitações de consulta de documento
- Siga as orientações para solucionar problemas de consultas com altas cobranças de RU
429 respostas ao executar procedimentos armazenados
- Os Procedimentos armazenados são destinados a operações que exigem transações de gravação em um valor de chave de partição. Não é recomendável usar procedimentos armazenados para um grande número de operações de leitura ou consulta. Para obter um melhor desempenho, essas operações de leitura ou consulta devem ser feitas no lado do cliente, usando os SDKs do Azure Cosmos DB.
A taxa de solicitação é grande com o dimensionamento automático
Todas as diretrizes neste artigo se aplicam à taxa de transferência manual e de dimensionamento automático.
Ao usar o dimensionamento automático, uma pergunta comum que surge é "Ainda é possível ver 429 respostas com o dimensionamento automático?"
Sim. Há dois cenários principais nos quais isso pode ocorrer.
Cenário 1: quando as RU/s gerais consumidas excedem o máximo de RU/s do banco de dados ou contêiner, o serviço limita as solicitações de acordo. Isso é análogo a exceder a taxa de transferência provisionada manual geral de um banco de dados ou contêiner.
Cenário 2: se houver uma partição em chamas, ou seja, um valor de chave de partição lógica que tenha uma quantidade desproporcionalmente maior de solicitações em comparação a outros valores de chave de partição, é possível que a partição física subjacente exceda seu orçamento de RU/s. Como melhor prática, para evitar partições ativas, escolha uma chave de partição adequada que resulte em uma distribuição uniforme do armazenamento e da taxa de transferência. Isso é semelhante a quando há uma partição em chamas ao usar a taxa de transferência manual.
Por exemplo, se você selecionar a opção de taxa de transferência máxima de 20.000 RU/s e tiver 200 GB de armazenamento, com quatro partições físicas, cada partição física pode ser dimensionada para até 5.000 RU/s. Se houver uma partição em chamas em uma chave de partição lógica específica, você verá 429 respostas quando a partição física subjacente na qual ela reside exceder 5000 RU/s, ou seja, exceder 100% da utilização normalizada.
Siga as orientações na Etapa 1, Etapa 2 e Etapa 3 para depurar esses cenários.
Outra pergunta comum que surge é, Por que o consumo normalizado de RU é 100%, mas o dimensionamento automático não foi dimensionado para o máximo de RU/s?
Isso normalmente ocorre para cargas de trabalho que têm picos temporários ou intermitentes de uso. Quando você usa o dimensionamento automático, o Azure Cosmos DB dimensiona as RU/s para a taxa de transferência máxima somente quando o consumo de RU normalizado é de 100% para um período de tempo contínuo e sustentado em um intervalo de cinco segundos. Isso é feito para garantir que a lógica de dimensionamento seja econômica para o usuário, pois garante que picos únicos e momentâneos não levem a um dimensionamento desnecessário e custos mais altos. Quando há picos momentâneos, o sistema normalmente é dimensionado para um valor superior ao dimensionado anteriormente para RU/s, mas inferior ao máximo de RU/s. Saiba mais sobre como interpretar a métrica de consumo de RU normalizada com dimensionamento automático.
Limitação de taxa em solicitações de metadados
A limitação da taxa de metadados pode ocorrer quando você está executando um alto volume de operações de metadados em bancos de dados e/ou contêineres. As operações de metadados incluem:
- Criar, ler, atualizar ou excluir um contêiner ou banco de dados
- Listar bancos de dados ou contêineres em uma conta do Azure Cosmos DB
- Consultar ofertas para ver a taxa de transferência provisionada atual
Há um limite de RU reservado do sistema para essas operações, portanto, aumentar as RU/s provisionadas do banco de dados ou do contêiner não terá nenhum impacto e não será recomendado. Consulte Painel de Controle para Limites de Serviço.
Como investigar
Navegue até Insights>Sistema>Solicitações de Metadados por Código de Status. Filtre para um banco de dados e contêiner específicos, se desejado.
Solução recomendada
Se seu aplicativo precisar executar operações de metadados, considere implementar uma política de retirada para enviar essas solicitações a uma taxa mais baixa.
Use instâncias estáticas de cliente do Azure Cosmos DB. Quando o DocumentClient ou o CosmosClient é inicializado, o SDK do Azure Cosmos DB busca metadados sobre a conta, incluindo informações sobre o nível de consistência, os bancos de dados, os contêineres, as partições e as ofertas. Essa inicialização pode consumir uma grande quantidade de RUs e deveria ser executada com pouca frequência. Use uma instância única de DocumentClient e use-a para o tempo de vida do aplicativo.
Armazene em cache os nomes dos bancos de dados e contêineres. Recupere os nomes dos bancos de dados e coleções de configuração ou armazene-os em cache na inicialização. Chamadas como ReadDatabaseAsync/ReadDocumentCollectionAsync ou CreateDatabaseQuery/CreateDocumentCollectionQuery resultarão em chamadas de metadados para o serviço, que consomem do limite de RU reservado do sistema. Essas operações devem ser executadas com pouca frequência.
Limitação de taxa devido a erro de serviço temporário
Esse erro 429 é retornado quando a solicitação encontra um erro de serviço transitório. Aumentar RU/s no banco de dados ou do contêiner não terá nenhum impacto e não será recomendado.
Solução recomendada
Tente novamente a solicitação. Se o erro persistir por vários minutos, crie um tíquete de suporte no portal do Azure.
Próximas etapas
- Monitore o consumo normalizado de RU/s do seu banco de dados ou contêiner.
- Diagnosticar e solucionar problemas ao usar o SDK do .NET para o Azure Cosmos DB.
- Saiba mais sobre as diretrizes de desempenho para o .NET v3 e o .NET v2.
- Diagnosticar e solucionar problemas ao usar o SDK do Java v4 para o Azure Cosmos DB.
- Saiba mais sobre as diretrizes de desempenho para o SDK do Java v4.