Partilhar via


Dicas de desempenho para Azure Cosmos DB Sync Java SDK v2

Importante

Este não é o SDK Java mais recente para o Azure Cosmos DB! Deves atualizar o teu projeto para o Azure Cosmos DB Java SDK v4 e depois ler o guia de dicas de desempenho do Azure Cosmos DB Java SDK v4. Siga as instruções no guia Migrate to Azure Cosmos DB Java SDK v4 e no guia Reactor vs RxJava para atualizar.

Estas dicas de desempenho são apenas para o Azure Cosmos DB Sync Java SDK v2. Por favor, consulte o repositório Maven para mais informações.

Importante

A 29 de fevereiro de 2024, o Azure Cosmos DB Sync Java SDK v2.x será retirado; o SDK e todas as aplicações que utilizam o SDK continuarão a funcionar; O Azure Cosmos DB simplesmente deixará de fornecer manutenção e suporte adicionais para este SDK. Recomendamos seguir as instruções acima para migrar para o SDK Java v4 do Azure Cosmos DB.

O Azure Cosmos DB é um banco de dados distribuído rápido e flexível que pode ser dimensionado perfeitamente com latência e taxa de transferência garantidas. Não é necessário fazer grandes alterações na arquitetura ou escrever código complexo para dimensionar seu banco de dados com o Azure Cosmos DB. Escalar para cima e para baixo é tão fácil quanto fazer uma única chamada de API. Para saber mais, veja como provisionar o throughput do contentor ou como provisionar o throughput da base de dados. No entanto, como o Azure Cosmos DB é acedido através de chamadas de rede, existem otimizações do lado do cliente que pode fazer para alcançar o desempenho máximo ao usar o Azure Cosmos DB Sync Java SDK v2.

Portanto, se você estiver perguntando "Como posso melhorar o desempenho do meu banco de dados?", considere as seguintes opções:

Rede

  1. Modo de ligação: Usar DirectHttps

    A forma como um cliente se liga ao Azure Cosmos DB tem implicações importantes no desempenho, especialmente em termos da latência observada do lado do cliente. Existe uma configuração principal disponível para configurar o cliente ConnectionPolicy – o ConnectionMode. Os dois ConnectionModes disponíveis são:

    1. Gateway (predefinido)

    2. DirectHttps

      O modo Gateway é suportado em todas as plataformas SDK e é o padrão configurado. Se a sua aplicação corre dentro de uma rede corporativa com restrições rigorosas de firewall, o Gateway é a melhor escolha, pois utiliza a porta HTTPS padrão e um único endpoint. A desvantagem de desempenho, no entanto, é que o modo Gateway envolve um salto adicional de rede sempre que dados são lidos ou escritos no Azure Cosmos DB. Por causa disso, o modo DirectHttps oferece melhor desempenho devido a menos saltos na rede.

      O Azure Cosmos DB Sync Java SDK v2 utiliza HTTPS como protocolo de transporte. O HTTPS utiliza TLS para autenticação inicial e encriptação do tráfego. Ao usar o Azure Cosmos DB Sync Java SDK v2, apenas a porta HTTPS 443 precisa de estar aberta.

      O ConnectionMode é configurado durante a construção da instância DocumentClient com o parâmetro ConnectionPolicy.

    Sync Java SDK v2 (Maven com.microsoft.azure::azure-documentdb)

    public ConnectionPolicy getConnectionPolicy() {
      ConnectionPolicy policy = new ConnectionPolicy();
      policy.setConnectionMode(ConnectionMode.DirectHttps);
      policy.setMaxPoolSize(1000);
      return policy;
    }
    
    ConnectionPolicy connectionPolicy = new ConnectionPolicy();
    DocumentClient client = new DocumentClient(HOST, MASTER_KEY, connectionPolicy, null);
    

    O diagrama mostra a política de ligação do Azure Cosmos DB.

  2. Coloque clientes na mesma região do Azure para desempenho

    Quando possível, coloque todos os aplicativos que chamam o Azure Cosmos DB na mesma região do banco de dados do Azure Cosmos DB. Para uma comparação aproximada, as chamadas para o Azure Cosmos DB dentro da mesma região são concluídas dentro de 1 a 2 ms, mas a latência entre a costa oeste e leste dos EUA é >de 50 ms. Essa latência provavelmente pode variar de solicitação para solicitação, dependendo da rota tomada pela solicitação à medida que ela passa do cliente para o limite do datacenter do Azure. A menor latência possível é alcançada garantindo que a aplicação que realiza a chamada esteja localizada na mesma região do Azure que o endpoint provisionado do Azure Cosmos DB. Para obter uma lista de regiões disponíveis, consulte Regiões do Azure.

    O diagrama mostra pedidos e respostas em duas regiões, onde os computadores se ligam a uma Conta Azure Cosmos DB através de serviços de nível intermédio.

Utilização do SDK

  1. Instalar o SDK mais recente

    Os SDKs do Azure Cosmos DB estão sendo constantemente aprimorados para fornecer o melhor desempenho. Para determinar as melhorias mais recentes do SDK, visite o SDK do Azure Cosmos DB.

  2. Use um cliente singleton do Azure Cosmos DB durante o tempo de vida da sua aplicação

    Cada instância DocumentClient é thread-safe e realiza uma gestão eficiente de ligação e cache de endereços quando opera em Modo Direto. Para permitir uma gestão eficiente da ligação e um melhor desempenho pelo DocumentClient, recomenda-se usar uma única instância de DocumentClient por AppDomain durante toda a vida útil da aplicação.

  3. Aumentar o MaxPoolSize por host ao usar o modo Gateway

    Os pedidos do Azure Cosmos DB são feitos via HTTPS/REST quando se utiliza o modo Gateway, e estão sujeitos ao limite de ligação predefinido por nome de host ou endereço IP. Pode ser necessário definir o MaxPoolSize para um valor superior (200-1000) para que a biblioteca cliente possa utilizar múltiplas ligações simultâneas ao Azure Cosmos DB. No Azure Cosmos DB Sync Java SDK v2, o valor predefinido para ConnectionPolicy.getMaxPoolSize é 100. Utilize setMaxPoolSize para alterar o valor.

  4. Ajuste de consultas paralelas para coleções particionadas

    O Azure Cosmos DB Sync Java SDK versão 1.9.0 e superiores suporta consultas paralelas, que permitem consultar uma coleção particionada em paralelo. Para mais informações, consulte exemplos de código relacionados com o trabalho com SDKs. As consultas paralelas são concebidas para melhorar a latência e a taxa de transferência das consultas em relação à sua contraparte serial.

    (a) Tuning setMaxDegreeOfParallelism: As consultas paralelas funcionam através da consulta a múltiplas partições em paralelo. No entanto, os dados de uma coleção particionada individual são obtidos em série relativamente à consulta. Assim, use setMaxDegreeOfParallelism para definir o número de partições que tem a maior probabilidade de alcançar a consulta de maior desempenho, desde que todas as outras condições do sistema permaneçam iguais. Se não souberes o número de partições, podes usar setMaxDegreeOfParallelism para definir um número elevado, e o sistema escolhe o mínimo (número de partições, entrada fornecida pelo utilizador) como o grau máximo de paralelismo.

    É importante notar que as consultas paralelas produzem os melhores benefícios se os dados estiverem distribuídos uniformemente por todas as partições relativamente à consulta. Se a coleção particionada for particionada de tal forma que todos ou a maior parte dos dados devolvidos por uma consulta estejam concentrados em poucas partições (uma partição no pior dos casos), então o desempenho da consulta ficaria limitado por essas partições.

    (b) Tuning setMaxBufferedItemCount: A consulta paralela foi concebida para pré-buscar resultados enquanto o lote atual de resultados está a ser processado pelo cliente. A pré-busca ajuda na melhoria geral da latência de uma consulta. setMaxBufferedItemCount limita o número de resultados pré-buscados. Ao definir setMaxBufferedItemCount para o número esperado de resultados devolvidos (ou um número superior), isto permite que a consulta obtenha o máximo benefício da pré-busca.

    O pré-carregamento funciona da mesma maneira, independentemente do MaxDegreeOfParallelism, e existe um único buffer para os dados de todas as partições.

  5. Implementar o backoff em intervalos de getRetryAfterInMilliseconds

    Durante os testes de desempenho, deve-se aumentar a carga até que uma pequena taxa de pedidos seja controlada. Se for limitado, a aplicação cliente deve reduzir a redução da aceleração durante o intervalo de retentativa especificado pelo servidor. Respeitar o mecanismo de backoff garante que você passe o mínimo tempo possível a aguardar entre tentativas. O suporte para políticas de retentativa está incluído na versão 1.8.0 e superior do Azure Cosmos DB Sync Java SDK. Para mais informações, consulte getRetryAfterInMilliseconds.

  6. Dimensione a carga de trabalho do cliente

    Se estiver a testar a níveis elevados de taxa de transferência (>50.000 RU/s), a aplicação cliente poderá ser o gargalo devido aos limites de utilização da CPU ou da rede pela máquina. Se você chegar a esse ponto, poderá continuar a expandir a conta do Azure Cosmos DB ao distribuir seus aplicativos cliente por vários servidores.

  7. Use endereçamento baseado no nome

    Use endereçamento baseado no nome, onde as ligações têm o formato dbs/MyDatabaseId/colls/MyCollectionId/docs/MyDocumentId, em vez de SelfLinks (_self), que têm o formato dbs/<database_rid>/colls/<collection_rid>/docs/<document_rid> para evitar recuperar ResourceIds de todos os recursos usados para construir a ligação. Além disso, à medida que estes recursos são recriados (possivelmente com o mesmo nome), armazená-los em cache pode não ajudar.

  8. Ajuste o tamanho da página para consultas/feeds de leitura para melhor desempenho

    Ao realizar uma leitura em massa de documentos utilizando funcionalidades de feed de leitura (por exemplo, readDocuments) ou ao emitir uma consulta SQL, os resultados são devolvidos de forma segmentada se o conjunto de resultados for demasiado grande. Por defeito, os resultados são devolvidos em blocos de 100 itens ou 1 MB, consoante o limite atingido primeiro.

    Para reduzir o número de idas e voltas de rede necessárias para obter todos os resultados aplicáveis, pode aumentar o tamanho da página usando o cabeçalho de pedido x-ms-max-item-count até 1000. Nos casos em que precisar de mostrar apenas alguns resultados, como quando a sua interface de utilizador ou API de aplicação retorna apenas 10 resultados de cada vez, pode também reduzir o tamanho da página para 10 para diminuir a largura de banda consumida por leituras e consultas.

    Também pode definir o tamanho da página usando o método setPageSize.

Política de Indexação

  1. Excluir os caminhos não utilizados da indexação para assegurar escritas mais rápidas

    A política de indexação do Azure Cosmos DB permite-lhe especificar quais os caminhos dos documentos a incluir ou excluir da indexação utilizando Caminhos de Indexação (setIncludedPaths e setExcludedPaths). O uso de caminhos de indexação pode oferecer melhor desempenho de gravação e menor armazenamento de índice para cenários nos quais os padrões de consulta são conhecidos de antemão, já que os custos de indexação estão diretamente correlacionados ao número de caminhos exclusivos indexados. Por exemplo, o código seguinte mostra como excluir uma secção inteira (subárvore) dos documentos da indexação usando o coringa "*".

    Sync Java SDK v2 (Maven com.microsoft.azure::azure-documentdb)

    Index numberIndex = Index.Range(DataType.Number);
    numberIndex.set("precision", -1);
    indexes.add(numberIndex);
    includedPath.setIndexes(indexes);
    includedPaths.add(includedPath);
    indexingPolicy.setIncludedPaths(includedPaths);
    collectionDefinition.setIndexingPolicy(indexingPolicy);
    

    Para obter mais informações, consulte Políticas de indexação do Azure Cosmos DB.

Capacidade de processamento

  1. Meça e ajuste para reduzir o uso de unidades de requisição por segundo

    O Azure Cosmos DB oferece um conjunto avançado de operações de banco de dados, incluindo consultas relacionais e hierárquicas com UDFs, procedimentos armazenados e gatilhos, todos operando nos documentos de uma coleção de banco de dados. O custo associado a cada uma destas operações varia com base na CPU, E/S e memória necessárias para concluir a operação. Em vez de pensar e gerenciar recursos de hardware, você pode pensar em uma unidade de solicitação (RU) como uma única medida para os recursos necessários para executar várias operações de banco de dados e atender a uma solicitação de aplicativo.

    A taxa de transferência é provisionada com base no número de unidades de solicitação definidas para cada contentor. O consumo unitário de solicitação é avaliado como uma taxa por segundo. Os aplicativos que excedem a taxa unitária de solicitação provisionada para seu contêiner são limitados até que a taxa caia abaixo do nível provisionado para o 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 unidades de solicitação adicionais.

    A complexidade de uma consulta afeta quantas unidades de solicitação são consumidas para uma operação. O número de predicados, a natureza dos predicados, o número de UDFs 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 eliminar), inspecione o cabeçalho x-ms-request-charge (ou a propriedade equivalente RequestCharge no ResourceResponse<T> ou FeedResponse<T> para medir o número de unidades de pedido consumidas por estas operações).

    Sync Java SDK v2 (Maven com.microsoft.azure::azure-documentdb)

    ResourceResponse<Document> response = client.createDocument(collectionLink, documentDefinition, null, false);
    
    response.getRequestCharge();
    

    O custo de solicitação retornado neste cabeçalho é uma fração da taxa de transferência provisionada. Por exemplo, se tiver 2000 RU/s provisionadas, e se a consulta anterior devolver 1.000 documentos de 1KB, o custo da operação é de 1000. Como tal, dentro de um segundo, o servidor honra apenas duas dessas solicitações antes de limitar as solicitações subsequentes. Para obter mais informações, consulte Unidades de Solicitação e a Calculadora de Unidades de Solicitação.

  2. Lidar com limitação de 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 nenhum uso da capacidade de taxa de transferência além do nível reservado. O servidor terminará preventivamente a solicitação com RequestRateTooLarge (código de status HTTP 429) e retornará o cabeçalho x-ms-retry-after-ms indicando a quantidade de tempo, em milissegundos, que o usuário deve aguardar antes de tentar novamente a solicitação.

        HTTP Status 429,
        Status Line: RequestRateTooLarge
        x-ms-retry-after-ms :100
    

    Todos os SDKs capturam implicitamente essa resposta, respeitam o cabeçalho retry-after especificado pelo servidor e tentam novamente a solicitação. A menos que sua conta esteja sendo acessada simultaneamente por vários clientes, a próxima tentativa será bem-sucedida.

    Se tiver mais do que um cliente a operar cumulativamente acima da taxa de solicitações, a contagem de retentativas padrão, definida internamente pelo cliente para 9, pode não ser suficiente; neste caso, o cliente gera uma DocumentClientException com o código de estado 429 para a aplicação. A contagem padrão de tentativas pode ser alterada usando setRetryOptions na instância ConnectionPolicy . Por padrão, o DocumentClientException com o código de estado 429 é retornado após um tempo de espera acumulado de 30 segundos se o pedido continuar a operar acima da taxa de solicitações. Isso ocorre mesmo quando a contagem de tentativas atual é menor do que a contagem máxima de tentativas, seja o padrão de 9 ou um valor definido pelo usuário.

    Embora o comportamento de repetição automatizada ajude a melhorar a resiliência e a usabilidade para a maioria dos aplicativos, ele pode entrar em desacordo ao fazer benchmarks de desempenho, especialmente ao medir a latência. A latência observada pelo cliente aumentará se o experimento atingir o limite do servidor e fizer com que o SDK do cliente tente novamente de forma silenciosa. Para evitar picos de latência durante experimentos 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 obter mais informações, consulte Unidades de solicitação.

  3. Design de documentos menores para maior eficiência

    A taxa de solicitação (o custo de processamento da solicitação) de uma determinada operação está diretamente correlacionada com o tamanho do documento. As operações em documentos grandes custam mais do que as operações em documentos pequenos.

Próximos passos

Para saber mais sobre como projetar seu aplicativo para dimensionamento e alto desempenho, consulte Particionamento e dimensionamento no Azure Cosmos DB.