Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O Azure Cosmos DB é um banco de dados distribuído, rápido e flexível que pode ser dimensionado perfeitamente com garantia de níveis de latência e taxa de transferência. Você não precisa fazer grandes alterações de arquitetura nem escrever códigos complexos para dimensionar seu banco de dados com o Azure Cosmos DB. Aumentar e diminuir a escala é tão fácil quanto fazer uma única chamada de API. Para saber mais, veja Configurar o desempenho do contêiner ou Configurar o desempenho do banco de dados.
Como o Azure Cosmos DB é acessado por meio de chamadas de rede, você pode otimizar o lado do cliente para obter o melhor desempenho ao usar o SDK do .NET de SQL.
Para se você está tentando melhorar o desempenho do seu banco de dados, considere as opções apresentadas nas seções a seguir.
Recomendações de hospedagem
Ativar a coleta de lixo do lado do servidor
A redução da frequência da coleta de lixo pode ajudar em alguns casos. No .NET, defina gcServer como true.
Dimensionar a carga de trabalho do cliente
Se você estiver realizando testes em taxa de transferência elevados de rendimento ou em taxas superiores a 50.000 unidades de solicitação por segundo (RU/s), o aplicativo cliente poderá se tornar um gargalo na carga de trabalho, pois o computador poderá atingir o limite de uso da CPU ou da rede. Se você chegar a este ponto, poderá continuar aumentando a conta do Azure Cosmos DB ainda mais distribuindo seus aplicativos cliente entre vários servidores.
Observação
O alto uso da CPU pode causar maior latência e exceções de tempo limite de solicitação.
Operações de metadados
Não verifique se um banco de dados ou contêiner existe chamando Create...IfNotExistsAsync ou Read...Async no caminho crítico ou antes de realizar uma operação de item. A validação só deve ser feita na inicialização do aplicativo quando for necessário, se você espera que elas sejam excluídas (caso contrário, não é necessário). Essas operações de metadados geram latência extra de ponta a ponta, não têm SLA e têm suas próprias limitações separadas que não são dimensionadas como operações de dados.
Log e rastreamento
Alguns ambientes têm o DefaultTraceListener do .NET habilitado. O DefaultTraceListener apresenta problemas de desempenho em ambientes de produção que causam altos gargalos de CPU e E/S. Verifique se o DefaultTraceListener está desabilitado no seu aplicativo removendo-o dos TraceListeners em ambientes de produção.
As versões do SDK maiores que a 3.23.0 a removem automaticamente quando detectadas. Com versões mais antigas, você pode removê-la usando os seguintes comandos:
if (!Debugger.IsAttached)
{
Type defaultTrace = Type.GetType("Microsoft.Azure.Cosmos.Core.Trace.DefaultTrace,Microsoft.Azure.Cosmos.Direct");
TraceSource traceSource = (TraceSource)defaultTrace.GetProperty("TraceSource").GetValue(null);
traceSource.Listeners.Remove("Default");
// Add your own trace listeners
}
Alta disponibilidade
Para obter orientações gerais sobre como configurar a alta disponibilidade no Azure Cosmos DB, consulte Alta disponibilidade no Azure Cosmos DB.
Além de uma boa configuração fundamental na plataforma de banco de dados, há técnicas específicas que podem ser implementadas no próprio SDK do .NET, o que pode ajudar em cenários de interrupção. Duas estratégias notáveis são a estratégia de disponibilidade baseada em limite e o interruptor de circuito no nível da partição.
Estratégia de disponibilidade baseada em limite
A estratégia de disponibilidade baseada em limite pode melhorar a latência e a disponibilidade da cauda enviando solicitações de leitura paralelas para regiões secundárias (conforme definido em ApplicationPreferredRegions) e aceitando a resposta mais rápida. Essa abordagem pode reduzir drasticamente o efeito de interrupções regionais ou condições de alta latência no desempenho do aplicativo.
Configuração de exemplo:
A configuração disso pode ser feita usando CosmosClientBuilder:
CosmosClient client = new CosmosClientBuilder("connection string")
.WithApplicationPreferredRegions(
new List<string> { "East US", "East US 2", "West US" } )
.WithAvailabilityStrategy(
AvailabilityStrategy.CrossRegionHedgingStrategy(
threshold: TimeSpan.FromMilliseconds(500),
thresholdStep: TimeSpan.FromMilliseconds(100)
))
.Build();
Ou configurando opções e adicionando-as a CosmosClient:
CosmosClientOptions options = new CosmosClientOptions()
{
AvailabilityStrategy
= AvailabilityStrategy.CrossRegionHedgingStrategy(
threshold: TimeSpan.FromMilliseconds(500),
thresholdStep: TimeSpan.FromMilliseconds(100)
)
ApplicationPreferredRegions = new List<string>() { "East US", "East US 2", "West US"},
};
CosmosClient client = new CosmosClient(
accountEndpoint: "account endpoint",
authKeyOrResourceToken: "auth key or resource token",
clientOptions: options);
Como funciona:
Solicitação inicial: No momento T1, uma solicitação de leitura é feita para a região primária (por exemplo, Leste dos EUA). O SDK aguarda uma resposta de até 500 milissegundos (o valor
threshold).Segunda solicitação: Se não houver resposta da região primária dentro de 500 milissegundos, uma solicitação paralela será enviada para a próxima região preferencial (por exemplo, Leste dos EUA 2).
Terceira solicitação: Se nem a região primária nem secundária responder dentro de 600 milissegundos (500 ms + 100 ms, o
thresholdStepvalor), o SDK enviará outra solicitação paralela para a terceira região preferencial (por exemplo, Oeste dos EUA).A resposta mais rápida vence: Qualquer região que responda primeiro, essa resposta é aceita e as outras solicitações paralelas são ignoradas.
Observação
Se a primeira região preferencial retornar um código de status de erro nãotransiente (por exemplo, documento não encontrado, erro de autorização ou conflito), a operação em si falhará rapidamente, pois a estratégia de disponibilidade não tem nenhum benefício nesse cenário.
Disjuntor de nível de partição
O disjuntor de nível de partição (PPCB) é um recurso do SDK do .NET que aprimora a disponibilidade e a latência ao monitorar partições físicas não saudáveis. Quando habilitado, ele ajuda a rotear solicitações para regiões mais saudáveis, evitando falhas em cascata devido a problemas regionais ou específicos da partição. A funcionalidade é independente do failover ativado pelo back-end e é controlada por meio de variáveis de ambiente.
Esse recurso é desabilitado por padrão, mas é habilitado automaticamente quando o failover no nível da partição está habilitado.
Como funciona
-
Detecção de falhas: Quando erros específicos, como
503 Service Unavailable,408 Request Timeoutou tokens de cancelamento são observados, o SDK conta falhas consecutivas para uma partição. -
Disparando o failover: quando um limite configurado de falhas consecutivas é atingido, o SDK redireciona as solicitações para esse intervalo de chaves de partição para a próxima região preferencial usando
GlobalPartitionEndpointManagerCore.TryMarkEndpointUnavailableForPartitionKeyRange. - Recuperação em segundo plano: Uma tarefa em segundo plano é iniciada durante o failover para reavaliar periodicamente a integridade da partição com falha ao tentar se conectar a todas as quatro réplicas. Depois de íntegro, o SDK remove a substituição e retorna para a região primária.
Comportamento por tipo de conta
- Gravação de região única (mestre único): Somente solicitações de leitura participam do mecanismo de failover PPCB.
- Gravação em várias regiões (vários mestres): Tanto solicitações de leitura quanto de gravação usam a lógica de failover PPCB.
Opções de configuração
Use as seguintes variáveis de ambiente para configurar o PPCB:
| Variável de ambiente | Description | Padrão |
|---|---|---|
AZURE_COSMOS_CIRCUIT_BREAKER_ENABLED |
Habilita ou desabilita o recurso PPCB. | false |
AZURE_COSMOS_PPCB_CONSECUTIVE_FAILURE_COUNT_FOR_READS |
Falhas de leitura consecutivas para disparar failover. | 10 |
AZURE_COSMOS_PPCB_CONSECUTIVE_FAILURE_COUNT_FOR_WRITES |
Falhas de gravação consecutivas para disparar failover. | 5 |
AZURE_COSMOS_PPCB_ALLOWED_PARTITION_UNAVAILABILITY_DURATION_IN_SECONDS |
Intervalo de tempo antes de avaliar novamente a saúde da partição. |
5 Segundos |
AZURE_COSMOS_PPCB_STALE_PARTITION_UNAVAILABILITY_REFRESH_INTERVAL_IN_SECONDS |
Intervalo para atualização em segundo plano da integridade da partição. |
60 Segundos |
Observação
No momento, o SDK não tem um gatilho de failback confiável para leituras. Em vez disso, um verificador de integridade em segundo plano tenta reabilitar gradualmente a região original quando todas as quatro réplicas são responsivas.
Comparar otimizações de disponibilidade
Estratégia de disponibilidade baseada em limite:
- Benefício: reduz a latência final enviando solicitações de leitura paralelas para regiões secundárias e melhora a disponibilidade preemptando solicitações que resultam em tempos limite de rede.
- Compensação: incorre em custos extras de Unidades de Solicitação (RUs) em comparação com o disjuntor, devido a solicitações paralelas adicionais entre regiões (embora somente durante períodos em que os limites são violados).
- Caso de uso: ideal para cargas de trabalho de leitura pesada em que a redução da latência é crítica e algum custo extra (tanto em termos de carga de RU quanto de pressão da CPU do cliente) é aceitável. As operações de gravação também podem se beneficiar, se for optado por uma política de repetição de gravação não idempotente e a conta tiver gravações em várias regiões.
Disjuntor no nível da partição:
- Benefício: aprimora a disponibilidade e a latência de gravação, evitando partições não íntegras, garantindo que as solicitações sejam roteadas para regiões mais íntegras.
- Compensação: não gera mais custos de RU, mas ainda pode permitir certa perda de disponibilidade inicial para as solicitações que resultam em tempos limite de rede.
- Caso de uso: ideal para cargas de trabalho de gravação intensas ou mistas, nas quais o desempenho consistente é essencial, especialmente ao lidar com partições que podem ficar instáveis de forma intermitente.
Ambas as estratégias podem ser usadas em conjunto para aprimorar a disponibilidade de leitura e gravação e reduzir a latência final. O disjuntor de nível de partição pode lidar com vários cenários de falha transitória, incluindo aqueles que podem resultar em réplicas de desempenho lento, sem a necessidade de executar solicitações paralelas. Além disso, adicionar uma estratégia de disponibilidade baseada em limite minimiza ainda mais a latência final e elimina a perda de disponibilidade, se o custo adicional de RU for aceitável.
Ao implementar essas estratégias, os desenvolvedores podem garantir que seus aplicativos permaneçam resilientes, manter alto desempenho e fornecer uma melhor experiência do usuário mesmo durante interrupções regionais ou condições de alta latência.
Regiões excluídas
O recurso regiões excluídas permite um controle refinado sobre o roteamento de solicitações, permitindo que você exclua regiões específicas de seus locais preferenciais por solicitação. Esse recurso está disponível no SDK do .NET do Azure Cosmos DB versão 3.37.0 e superior.
Principais benefícios:
- Lidar com a limitação de taxa: ao encontrar 429 respostas (Muitas solicitações), rote automaticamente as solicitações para as regiões alternativas com taxa de transferência disponível
- Roteamento direcionado: verifique se as solicitações são atendidas de regiões específicas excluindo todas as outras
- Ignorar a ordem preferencial: substituir a lista de regiões preferenciais padrão para solicitações individuais sem criar clientes separados
Configuração:
As regiões excluídas podem ser configuradas no nível da solicitação usando a ExcludeRegions propriedade:
CosmosClientOptions clientOptions = new CosmosClientOptions()
{
ApplicationPreferredRegions = new List<string> {"West US", "Central US", "East US"}
};
CosmosClient client = new CosmosClient(connectionString, clientOptions);
Database db = client.GetDatabase("myDb");
Container container = db.GetContainer("myContainer");
//Request will be served out of the West US region
await container.ReadItemAsync<dynamic>("item", new PartitionKey("pk"));
//By using ExcludeRegions, we are able to bypass the ApplicationPreferredRegions list
// and route a request directly to the East US region
await container.ReadItemAsync<dynamic>(
"item",
new PartitionKey("pk"),
new ItemRequestOptions()
{
ExcludeRegions = new List<string>() { "West US", "Central US" }
});
Exemplo de caso de uso – gerenciamento de limite de taxa:
ItemResponse<CosmosItem> item;
item = await container.ReadItemAsync<CosmosItem>("id", partitionKey);
if (item.StatusCode == HttpStatusCode.TooManyRequests)
{
ItemRequestOptions requestOptions = new ItemRequestOptions()
{
ExcludeRegions = new List<string>() { "East US" }
};
item = await container.ReadItemAsync<CosmosItem>("id", partitionKey, requestOptions);
}
O recurso também funciona com consultas e outras operações:
QueryRequestOptions queryRequestOptions = new QueryRequestOptions()
{
ExcludeRegions = new List<string>() { "East US" }
};
using (FeedIterator<CosmosItem> queryFeedIterator = container.GetItemQueryIterator<CosmosItem>(
queryDefinition,
requestOptions: queryRequestOptions))
{
while(queryFeedIterator.HasMoreResults)
{
var item = await queryFeedIterator.ReadNextAsync();
}
}
Ajuste fino de consistência versus disponibilidade
O recurso regiões excluídas fornece um mecanismo adicional para equilibrar as compensações de consistência e disponibilidade em seu aplicativo. Essa funcionalidade é particularmente valiosa em cenários dinâmicos em que os requisitos podem mudar com base nas condições operacionais:
Tratamento de interrupção dinâmica: quando uma região primária experimenta uma interrupção e os limites de disjuntor no nível da partição se mostram insuficientes, as regiões excluídas permitem o failover imediato sem alterações de código ou reinicializações de aplicativo. Isso fornece uma resposta mais rápida a problemas regionais em comparação com a espera de ativação automática do disjuntor.
Preferências de consistência condicional: os aplicativos podem implementar estratégias de consistência diferentes com base no estado operacional:
- Estado estável: priorize leituras consistentes excluindo todas as regiões, exceto as primárias, garantindo a consistência dos dados ao custo potencial de disponibilidade
- Cenários de interrupção: favoreça a disponibilidade em relação à consistência estrita, permitindo o roteamento entre regiões, aceitando um possível atraso de dados em troca da disponibilidade contínua do serviço
Essa abordagem permite que mecanismos externos (como gerenciadores de tráfego ou balanceadores de carga) orquestram decisões de failover enquanto o aplicativo mantém o controle sobre os requisitos de consistência por meio de padrões de exclusão de região.
Quando todas as regiões são excluídas, as solicitações serão roteadas para a região primária/hub. Esse recurso funciona com todos os tipos de solicitação, incluindo consultas, e é particularmente útil para manter instâncias de cliente singleton e, ao mesmo tempo, obter um comportamento de roteamento flexível.
Rede
Política de conexão: usar o modo de conexão direta
O modo de conexão padrão do SDK do .NET V3 é direto com o protocolo TCP. Você configura o modo de conexão ao criar a instância CosmosClient em CosmosClientOptions. Para saber mais sobre as diferentes opções de conectividade, consulte o artigo Modos de conectividade.
CosmosClient client = new CosmosClient(
"<nosql-account-endpoint>",
tokenCredential
new CosmosClientOptions
{
ConnectionMode = ConnectionMode.Gateway // ConnectionMode.Direct is the default
}
);
Esgotamento de porta efêmera
Ao enfrentar um alto volume de conexões ou uma alta utilização de porta em suas instâncias, verifique primeiro se as instâncias cliente são singletons. Em outras palavras, elas devem ser exclusivas durante o tempo de vida do aplicativo.
Durante a execução do protocolo TCP, o cliente é otimizado para latência usando conexões de longa duração. Isso é diferente no caso do protocolo HTTPS, que encerra as conexões após dois minutos de inatividade.
Em cenários em que você tem acesso esparso e percebe uma contagem de conexões maior em comparação com o acesso do modo de gateway, você pode fazer o seguinte:
- Configure a propriedade CosmosClientOptions. PortReuseMode como
PrivatePortPool(em vigor nas versões 4.6.1 e mais recentes do Framework e nas versões 2.0 e mais recentes do .NET Core). Isso permite que o SDK use um pequeno pool de portas efêmeras para diferentes pontos de extremidade de destino do Azure Cosmos DB. - Configure a propriedade CosmosClientOptions.IdleTcpConnectionTimeout como maior ou igual a dez minutos. Os valores possíveis são de 20 minutos a 24 horas.
Coloque os clientes na mesma região do Azure para aumentar o desempenho
Quando possível, coloque os aplicativos que chamam o Azure Cosmos DB na mesma região do banco de dados dele. Uma comparação aproximada: as chamadas para o Azure Cosmos DB na mesma região são concluídas de 1 a 2 ms (milissegundos), mas a latência entre a Costa Leste e a Oeste dos EUA é maior que 50 ms. Essa latência pode variar entre as solicitações, dependendo da rota seguida por elas ao passar do limite do cliente para o do datacenter do Azure.
A menor latência possível é alcançada garantindo que o aplicativo de chamada esteja na mesma região do Azure que o ponto de extremidade provisionado do Azure Cosmos DB. Para obter uma lista de regiões disponíveis, consulte Regiões do Azure.
Aumentar o número de threads/tarefas
Como as chamadas ao Azure Cosmos DB são feitas sobre a rede, pode ser necessário variar o grau de simultaneidade das solicitações, de forma que o aplicativo cliente aguarde um tempo mínimo entre as solicitações. Por exemplo, ao usar a biblioteca de paralelismo de tarefas do .NET, crie centenas de tarefas que leem ou gravam no Azure Cosmos DB.
Habilitar a rede acelerada para reduzir a latência e a tremulação da CPU
É recomendável que você siga as instruções para habilitar a Rede Acelerada em sua VM do Azure do Windows ou Linux para maximizar o desempenho.
Sem a rede acelerada ativada, a E/S que transita entre sua VM do Azure e outros recursos do Azure pode ser roteada desnecessariamente por meio de um host e de um comutador virtual situados entre a VM e sua placa de rede. Ter o host e o comutador virtual embutidos no caminho de dados não apenas aumenta a latência e a tremulação no canal de comunicação, ele também rouba ciclos de CPU da VM. Com a rede acelerada, a interface da VM comunica diretamente com a NIC sem intermediários adicionais; agora, todos os detalhes da política de rede que foram tratados pelo host e pelo comutador virtual são tratados em hardware na NIC; o host e o comutador virtual são ignorados. Geralmente, você pode esperar uma latência mais baixa e uma taxa de transferência mais alta, bem como uma latência mais consistente e menor utilização da CPU quando você habilita a rede acelerada.
Limitações: a rede acelerada deve ter suporte no sistema operacional da VM e só pode ser habilitada quando a VM é interrompida e desalocada. A VM não pode ser implantada com o Azure Resource Manager. O Serviço de Aplicativo não tem a rede acelerada habilitada.
Para obter mais detalhes, consulte as instruções do Windows e do Linux .
Uso do SDK
Instalar o SDK mais recente
Os SDKs do Azure Cosmos DB estão constantemente sendo aprimorados para fornecer o melhor desempenho. Para determinar o SDK mais recente e examinar as melhorias, consulte SDK do Azure Cosmos DB.
Usar APIs de fluxo
O SDK do .NET v3 contém APIs de fluxo que podem receber e retornar dados sem serialização.
Os aplicativos de camada intermediária que não consomem diretamente as respostas do SDK, mas as retransmitem a outras camadas de aplicativo, podem se beneficiar das APIs de fluxo. Para obter exemplos de manipulação de fluxo, consulte os exemplos de Gerenciamento de itens.
Usar um cliente do Azure Cosmos DB singleton para obter o tempo de vida do aplicativo
Cada instância CosmosClient é segura para threads e realiza um gerenciamento eficiente de conexões e cache de endereços quando opera no modo direto. Para permitir um gerenciamento de conexão eficiente e melhor desempenho do cliente SDK, recomenda-se usar uma única instância por AppDomain durante o tempo de vida do aplicativo para cada conta com a qual o seu aplicativo interage.
Para aplicativos multilocatário que lidam com várias contas, confira as melhores práticas relacionadas.
Ao trabalhar no Azure Functions, as instâncias também devem seguir as diretrizes existentes e manter uma única instância.
Evitar chamadas de bloqueio
O SDK do Azure Cosmos DB deve ser projetado de modo a processar várias solicitações simultaneamente. As APIs assíncronas permitem que um pequeno pool de threads cuide de milhares de solicitações simultâneas sem aguardar chamadas de bloqueio. Em vez de aguardar a conclusão de uma tarefa síncrona de execução longa, o thread pode trabalhar em outra solicitação.
Um problema de desempenho comum em aplicativos que usam o SDK do Azure Cosmos DB é o bloqueio de chamadas que poderiam ser assíncronas. Muitas chamadas de bloqueio síncronas levam ao esgotamento do pool de threads e à degradação dos tempos de resposta.
Não:
- Bloqueie a execução assíncrona chamando Task.Wait ou Task.Result.
- Use Task.Run para tornar uma API síncrona em assíncrona.
- Adquira bloqueios em caminhos de código comuns. O SDK do .NET do Azure Cosmos DB tem melhor desempenho quando projetado para executar código em paralelo.
- Chame Task.Run e aguarde imediatamente. O ASP.NET Core já executa o código do aplicativo em threads de Pool de Threads normais, portanto, chamar o Task.Run resulta apenas no agendamento extra desnecessário do pool de threads. Mesmo que o código agendado bloqueie um thread, Task.Run não impedirá isso.
- Não use ToList() em
Container.GetItemLinqQueryable<T>(), que utiliza chamadas de bloqueio para esvaziar a consulta de forma síncrona. Use ToFeedIterator() para esvaziar a consulta de maneira assíncrona.
Certo:
- Chame as APIs do .NET do Azure Cosmos DB de maneira assíncrona.
- Toda a pilha de chamadas é assíncrona para aproveitar os padrões async/await.
Um perfilador, como PerfView, pode ser usado para localizar threads frequentemente adicionados ao pool de threads. O evento Microsoft-Windows-DotNETRuntime/ThreadPoolWorkerThread/Start indica um thread adicionado ao pool de threads.
Desabilitar a resposta de conteúdo em operações de gravação
Para cargas de trabalho com cargas de criação pesadas, defina a opção de solicitação EnableContentResponseOnWrite como false. O serviço não retorna mais o recurso criado ou atualizado para o SDK. Normalmente, como o aplicativo tem o objeto que está sendo criado, ele não precisa que o serviço o retorne. Os valores de cabeçalho ainda são acessíveis, como uma carga de solicitação. Desabilitar a resposta de conteúdo pode ajudar a melhorar o desempenho, pois o SDK não precisa mais alocar memória ou serializar o corpo da resposta. Isso também reduz o uso de largura de banda da rede e aumenta ainda mais o desempenho.
ItemRequestOptions requestOptions = new ItemRequestOptions() { EnableContentResponseOnWrite = false };
ItemResponse<Book> itemResponse = await this.container.CreateItemAsync<Book>(book, new PartitionKey(book.pk), requestOptions);
// Resource will be null
itemResponse.Resource
Habilitar o Bulk para otimizar a taxa de transferência em vez da latência
Habilite o Em massa nos cenários em que a carga de trabalho requer uma grande quantidade de taxa de transferência e a latência não é tão importante. Para obter mais informações sobre como habilitar o recurso Bulk e saber em quais cenários ele deve ser usado, consulte Introdução ao suporte do Bulk.
Aumentar System.Net MaxConnections por host ao usar o modo de Gateway
As solicitações do Azure Cosmos DB são feitas sobre HTTPS/REST ao usar o modo de gateway. Elas estão sujeitas ao limite de conexão padrão por nome de host ou endereço IP. Pode ser necessário definir MaxConnections como um valor mais alto (de 100 a 1000) para que a biblioteca de cliente possa utilizar várias conexões simultâneas com o Azure Cosmos DB. No SDK do .NET 1.8.0 e mais recente, o valor padrão de ServicePointManager.DefaultConnectionLimit é 50. Para alterá-lo, defina Documents.Client.ConnectionPolicy.MaxConnectionLimit como um valor mais alto.
Aumentar o número de threads/tarefas
Consulte Aumentar o número de threads/tarefas na seção Rede deste artigo.
Gerenciando dependências Newtonsoft.Json
Visão geral
O SDK do Azure Cosmos DB .NET tem uma dependência de Newtonsoft.Json para operações de serialização JSON.
Essa dependência não é gerenciada automaticamente – você deve adicionar Newtonsoft.Json explicitamente como uma dependência direta em seu projeto.
O SDK é compilado internamente no Newtonsoft.Json 10.x, que tem uma vulnerabilidade de segurança conhecida. Embora o SDK seja tecnicamente compatível com o 10.x e o uso do SDK do Newtonsoft.Json não seja suscetível ao problema de segurança relatado, ainda recomendamos usar a versão 13.0.3 ou superior para evitar possíveis problemas de segurança ou conflitos. As versões 13.x incluem alterações significativas, mas os padrões de uso do SDK são compatíveis com essas alterações.
Importante
Essa dependência é necessária mesmo quando System.Text.Json usada para tipos definidos pelo usuário por meio de CosmosClientOptions.UseSystemTextJsonSerializerWithOptions, porque as operações internas do SDK ainda usam Newtonsoft.Json para tipos de sistema.
Configuração recomendada
Sempre adicione Newtonsoft.Json explicitamente a versão 13.0.3 ou superior como uma dependência direta ao usar o SDK do .NET do Azure Cosmos DB v3. Não use a versão 10.x devido a vulnerabilidades de segurança conhecidas.
Para projetos .csproj padrão
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.47.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>
Para projetos que usam o Gerenciamento Central de Pacotes
Se o seu projeto usar Directory.Packages.props:
<Project>
<ItemGroup>
<PackageVersion Include="Microsoft.Azure.Cosmos" Version="3.47.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>
</Project>
Solução de problemas de conflitos de versão
Referência de Newtonsoft.Json ausente
Se você encontrar um erro de build como:
The Newtonsoft.Json package must be explicitly referenced with version >= 10.0.2. Please add a reference to Newtonsoft.Json or set the 'AzureCosmosDisableNewtonsoftJsonCheck' property to 'true' to bypass this check.
Esse erro é gerado intencionalmente pelos destinos de build do SDK do Cosmos DB para garantir que a dependência esteja configurada corretamente.
Solução para aplicativos:
Adicione uma referência explícita a Newtonsoft.Json, conforme mostrado na seção Configuração Recomendada acima.
Solução para bibliotecas:
Se estiver criando uma biblioteca (e não um aplicativo) e se quiser adiar a dependência de Newtonsoft.Json para os consumidores dessa biblioteca, você poderá ignorar essa verificação definindo a propriedade MSBuild em seu .csproj:
<PropertyGroup>
<AzureCosmosDisableNewtonsoftJsonCheck>true</AzureCosmosDisableNewtonsoftJsonCheck>
</PropertyGroup>
Aviso
Use esse bypass somente ao criar bibliotecas em que os usuários finais fornecerão a dependência Newtonsoft.Json. Para aplicativos, adicione sempre a referência explícita.
Conflitos de versão do pacote
Se você encontrar erros de build como:
error NU1109: Detected package downgrade: Newtonsoft.Json from 13.0.4 to centrally defined 13.0.3
Solution:
Identifique a versão necessária verificando quais pacotes precisam de versões mais recentes:
dotnet list package --include-transitive | Select-String "Newtonsoft.Json"Atualize sua versão centralizada do pacote para corresponder ou exceder a versão mais alta necessária:
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />Limpar e recompilar:
dotnet clean dotnet restore dotnet build
Compatibilidade de versão
A tabela a seguir mostra as versões seguras mínimas recomendadas do Newtonsoft.Json para cada versão do SDK do Cosmos DB. Embora o SDK possa funcionar tecnicamente com 10.x, essas versões nunca devem ser usadas devido a vulnerabilidades de segurança.
| Versão do SDK do Cosmos DB | Versão mínima segura | Recommended |
|---|---|---|
| 3.47.0+ | 13.0.3 | 13.0.4 |
| 3.54.0+ | 13.0.4 | 13.0.4 |
Dica
Ao usar o .NET Aspire 13.0.0 ou posterior, verifique se Newtonsoft.Json está na versão 13.0.4 para evitar conflitos com os componentes do Azure da Aspire.
Práticas recomendadas
- Sempre adicione como uma dependência direta – o SDK não gerencia automaticamente essa dependência para você
- Usar a versão 13.0.3 ou superior – nunca use 10.x apesar da compatibilidade técnica, devido a vulnerabilidades de segurança conhecidas
-
Obrigatório mesmo com System.Text.Json – Você deve incluir Newtonsoft.Json mesmo ao usar
UseSystemTextJsonSerializerWithOptions, já que o SDK o usa internamente para tipos de sistema - Fixar a versão explicitamente – não dependa da resolução de dependência transitiva
- Avisos de monitoramento – trate os avisos de downgrade do pacote NuGet (NU1109) como erros em pipelines de CI/CD
Operações de consulta
Para operações de consulta, consulte as dicas de desempenho para consultas.
Política de indexação
Excluir caminhos não utilizados da indexação para ter gravações mais rápidas
A política de indexação do Azure Cosmos DB também permite especificar quais caminhos de documento incluir ou excluir da indexação usando caminhos de indexação (IndexingPolicy.IncludedPaths e IndexingPolicy.ExcludedPaths).
Indexar somente os caminhos necessários pode melhorar o desempenho de gravação, reduzir as cargas de RU em operações de gravação e diminuir o armazenamento de índice nos cenários em que os padrões de consulta são conhecidos com antecedência. Isso ocorre porque os custos de indexação se correlacionam diretamente com o número de caminhos exclusivos indexados. Por exemplo, o código a seguir mostra como excluir uma seção inteira dos documentos (uma subárvore) da indexação usando o * curinga:
var containerProperties = new ContainerProperties(id: "excludedPathCollection", partitionKeyPath: "/pk" );
containerProperties.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
containerProperties.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/nonIndexedContent/*");
Container container = await this.cosmosDatabase.CreateContainerAsync(containerProperties);
Para obter mais informações, consulte Políticas de indexação do Azure Cosmos DB.
Rendimento
Medição e ajustes para obter menor uso de RU/s
O Azure Cosmos DB oferece um amplo conjunto de operações de banco de dados. Essas operações incluem consultas relacionais e hierárquicas com UDFs (funções definidas pelo usuário), procedimentos armazenados e gatilhos, todas operando nos documentos dentro de uma coleção de banco de dados.
O custo associado a cada uma dessas operações varia com base na CPU, na E/S e na memória necessárias para realizar a operação. Em vez de considerar e gerenciar recursos de hardware, considere uma Unidade de Solicitação como uma medida única dos recursos necessários para executar várias operações de banco de dados e atender a uma solicitação de aplicativo.
A capacidade de processamento é provisionada com base no número de Unidades de solicitação definidas para cada contêiner. O consumo de RU é avaliado como uma taxa de unidades por segundo. Os aplicativos que excedem a taxa de RU provisionada para seu contêiner são limitados até que a taxa esteja abaixo do nível provisionado do contêiner. Se seu aplicativo exigir um nível mais alto de taxa de transferência, você poderá aumentar sua taxa de transferência provisionando mais RUs.
A complexidade de uma consulta afetará quantas RUs serão consumidas por uma operação. O número de predicados, a natureza deles, o número de arquivos UDF e o tamanho do conjunto de dados de origem influenciam o custo das operações de consulta.
Para medir a sobrecarga de qualquer operação (criar, atualizar ou excluir), inspecione o cabeçalho x-ms-request-charge (ou a propriedade equivalente RequestCharge no ResourceResponse<T>FeedResponse<T> SDK do .NET) para medir o número de RUs consumidas pelas operações:
// Measure the performance (Request Units) of writes
ItemResponse<Book> response = await container.CreateItemAsync<Book>(myBook, new PartitionKey(myBook.PkValue));
Console.WriteLine("Insert of item consumed {0} request units", response.RequestCharge);
// Measure the performance (Request Units) of queries
FeedIterator<Book> queryable = container.GetItemQueryIterator<ToDoActivity>(queryString);
while (queryable.HasMoreResults)
{
FeedResponse<Book> queryResponse = await queryable.ExecuteNextAsync<Book>();
Console.WriteLine("Query batch consumed {0} request units", queryResponse.RequestCharge);
}
A carga de solicitação retornada nesse cabeçalho é uma fração de sua taxa de transferência provisionada (ou seja, 2.000 RUs/s). Por exemplo, se a consulta anterior retornar mil documentos de 1 KB, o custo da operação será de 1.000. Assim, em um segundo, o servidor atende apenas duas dessas solicitações antes de limitar a taxa das solicitações subsequentes. Para saber mais, consulte Unidades de solicitação e Calculadora de unidades de solicitação.
Lidar com uma limitação da taxa/taxa de solicitação muito grande
Quando um cliente tenta exceder a taxa de transferência reservada para uma conta, não há degradação de desempenho no servidor e não ocorre nenhum uso da capacidade de taxa de transferência reservada além do nível reservado. O servidor encerra preventivamente a solicitação com RequestRateTooLarge (código de status HTTP 429). Ele retorna um cabeçalho x-ms-retry-after-ms que indica a quantidade de tempo, em milissegundos, que o usuário deve aguardar antes de tentar realizar novamente a solicitação.
HTTP Status 429,
Status Line: RequestRateTooLarge
x-ms-retry-after-ms :100
Os SDKs irão capturar implicitamente essa resposta, respeitarão o cabeçalho server-specified retry-after e repetirão a solicitação. A menos que sua conta esteja sendo acessada simultaneamente por vários clientes, a próxima tentativa será bem-sucedida.
Se você tiver mais de um cliente operando de forma cumulativa consistentemente acima da taxa de solicitação, a contagem de repetição padrão definida internamente no momento como 9 pelo cliente poderá não ser suficiente. Nesse caso, o cliente lançará uma CosmosException com o código de status 429 para o aplicativo.
Você pode alterar a contagem de repetição padrão definindo o RetryOptions na instância CosmosClientOptions. Por padrão, o CosmosException com o código de status 429 será retornado após uma espera cumulativa de 30 segundos se a solicitação continuar operando acima da taxa de solicitação. Este erro é retornado mesmo quando a contagem de repetições atual é menor que a contagem máxima de repetições, independentemente de o valor atual corresponder ao padrão de 9 ou a um valor definido pelo usuário.
O comportamento de repetição automatizada ajuda a melhorar a resiliência e a usabilidade da maioria dos aplicativos. Porém, pode não ser o melhor comportamento ao fazer avaliações de desempenho, especialmente para medir a latência. A latência medida pelo cliente terá um pico se o experimento atingir o limite de capacidade do servidor e levar o SDK do cliente a repetir silenciosamente. Para evitar picos de latência durante os testes de desempenho, meça a carga retornada por cada operação e verifique se as solicitações estão operando abaixo da taxa de solicitação reservada.
Para saber mais, consulte Unidades de solicitação.
Para ter uma taxa de transferência maior, leve documentos menores em conta em seu design
A carga da solicitação (ou seja, o custo de processamento dela) para uma operação especificada está diretamente correlacionada ao tamanho do documento. As operações em documentos grandes custam mais que as de documentos pequenos.