Melhores práticas para o dimensionamento do débito aprovisionado (RU/s)

APLICA-SE A: NoSQL MongoDB Cassandra Gremlin Tabela

Este artigo descreve as práticas recomendadas e estratégias para dimensionar a taxa de transferência (RU/s) do seu banco de dados ou contêiner (coleção, tabela ou gráfico). Os conceitos se aplicam quando você está aumentando a RU/s manual provisionada ou a escala automática máxima de RU/s de qualquer recurso para qualquer uma das APIs do Azure Cosmos DB.

Pré-requisitos

Informações básicas sobre o dimensionamento de RU/s

Quando você envia uma solicitação para aumentar o RU/s do banco de dados ou contêiner, dependendo do RU/s solicitado e do layout de partição física atual, a operação de expansão será concluída instantaneamente ou de forma assíncrona (normalmente de 4 a 6 horas).

  • Escalonamento instantâneo
    • Quando o RU/s solicitado pode ser suportado pelo layout de partição física atual, o Azure Cosmos DB não precisa dividir ou adicionar novas partições.
    • Como resultado, a operação é concluída imediatamente e os RU/s estão disponíveis para uso.
  • Escalonamento assíncrono
    • Quando as RU/s pedidas são superiores às que o esquema de partição física consegue suportar, o Azure Cosmos DB divide as partições físicas existentes. Esta situação ocorre até que o recurso tenha o número mínimo de partições necessárias para suportar as RU/s pedidas.
    • Como resultado, a operação pode demorar algum tempo a concluir, normalmente 4 a 6 horas. Cada partição física pode suportar um máximo de 10 000 RU/s (aplica-se a todas as APIs) de débito e 50 GB de armazenamento (aplica-se a todas as APIs, exceto Cassandra, que tem 30 GB de armazenamento).

Nota

Se você executar uma operação manual de failover de região ou adicionar/remover uma nova região enquanto uma operação de expansão assíncrona estiver em andamento, a operação de expansão de taxa de transferência será pausada. Ele será retomado automaticamente quando a operação de failover ou adicionar/remover região for concluída.

  • Redução instantânea da escala
    • Para operações de redução de escala, o Azure Cosmos DB não precisa dividir ou adicionar novas partições.
    • Como resultado, a operação é concluída imediatamente e os RU/s estão disponíveis para uso,
    • O principal resultado desta operação é que os RUs por partição física serão reduzidos.

Como aumentar a escala de RU/s sem alterar o layout da partição

Passo 1: Encontre o número atual de partições físicas.

Navegue até Consumo de RU normalizado de taxa de>transferência do Insights>(%) por PartitionKeyRangeID. Conte o número distinto de PartitionKeyRangeIds.

Conte o número distinto de PartitionKeyRangeIds no consumo normalizado de RU (%) pelo gráfico PartitionKeyRangeID

Nota

O gráfico mostrará apenas um máximo de 50 PartitionKeyRangeIds. Se seu recurso tiver mais de 50, você poderá usar a API REST do Azure Cosmos DB para contar o número total de partições.

Cada PartitionKeyRangeId mapeia para uma partição física e é atribuído para armazenar dados para um intervalo de possíveis valores de hash.

O Azure Cosmos DB distribui seus dados entre partições lógicas e físicas com base em sua chave de partição para habilitar o dimensionamento horizontal. À medida que os dados são gravados, o Azure Cosmos DB usa o hash do valor da chave de partição para determinar em qual partição lógica e física os dados vivem.

Etapa 2: Calcular a taxa de transferência máxima padrão

O RU/s mais alto para o qual você pode ser dimensionado sem acionar o Azure Cosmos DB para dividir partições é igual a Current number of physical partitions * 10,000 RU/s. Você pode obter esse valor do Provedor de Recursos do Azure Cosmos DB. Execute uma solicitação GET em seu banco de dados ou contêiner definindo objetos de configuração e recupere a instantMaximumThroughput propriedade. Esse valor também está disponível na página Escala e Configurações do seu banco de dados ou contêiner no portal.

Exemplo

Suponha que temos um contêiner existente com cinco partições físicas e 30.000 RU/s de taxa de transferência provisionada manual. Podemos aumentar o RU/s para 5 * 10.000 RU/s = 50.000 RU/s instantaneamente. Da mesma forma, se tivéssemos um contêiner com escala automática máxima de RU/s de 30.000 RU/s (escalas entre 3000 - 30.000 RU/s), poderíamos aumentar nosso máximo de RU/s para 50.000 RU/s instantaneamente (escalas entre 5000 - 50.000 RU/s).

Gorjeta

Se você estiver ampliando o RU/s para responder a exceções muito grandes da taxa de solicitação (429s), é recomendável primeiro aumentar o RU/s para o RU/s mais alto suportado pelo layout de partição física atual e avaliar se o novo RU/s é suficiente antes de aumentar ainda mais.

Como garantir uma distribuição uniforme dos dados durante o dimensionamento assíncrono

Fundo

Quando você aumenta a RU/s além do número atual de partições físicas * 10.000 RU/s, o Azure Cosmos DB divide as partições existentes, até o novo número de partições = ROUNDUP(requested RU/s / 10,000 RU/s). Durante uma divisão, as partições pai são divididas em duas partições filhas.

Por exemplo, suponha que temos um contêiner com três partições físicas e 30.000 RU/s de taxa de transferência provisionada manual. Se aumentarmos a taxa de transferência para 45.000 RU/s, o Azure Cosmos DB dividirá duas das partições físicas existentes para que, no total, haja ROUNDUP(45,000 RU/s / 10,000 RU/s) = 5 partições físicas.

Nota

As aplicações podem sempre ingerir ou consultar dados durante uma divisão. Os SDKs e o serviço do cliente do Azure Cosmos DB lidam automaticamente com esse cenário e garantem que as solicitações sejam roteadas para a partição física correta, portanto, nenhuma ação adicional do usuário é necessária.

Se você tiver uma carga de trabalho distribuída de forma muito uniforme em relação ao armazenamento e ao volume de solicitações — normalmente realizada por particionamento por campos de cardinalidade alta, como /id — é recomendável ao aumentar a escala e definir RU/s de modo que todas as partições sejam divididas uniformemente.

Para ver o porquê, vamos dar um exemplo em que temos um contêiner existente com 2 partições físicas, 20.000 RU/s e 80 GB de dados.

Graças à escolha de uma boa chave de partição com alta cardinalidade, os dados são distribuídos aproximadamente uniformemente em ambas as partições físicas. A cada partição física é atribuído aproximadamente 50% do espaço de chave, que é definido como o intervalo total de valores de hash possíveis.

Além disso, o Azure Cosmos DB distribui RU/s uniformemente em todas as partições físicas. Como resultado, cada partição física tem 10.000 RU/s e 50% (40 GB) do total de dados. O diagrama a seguir mostra nosso estado atual.

Dois PartitionKeyRangeIds, cada um com 10.000 RU/s, 40 GB e 50% do espaço total de chaves

Agora, suponha que queremos aumentar nosso RU/s de 20.000 RU/s para 30.000 RU/s.

Se simplesmente aumentarmos o RU/s para 30.000 RU/s, apenas uma das partições será dividida. Após a divisão, teremos:

  • Uma partição que contém 50% dos dados (esta partição não foi dividida)
  • Duas partições que contêm 25% dos dados cada (estas são as partições filhas resultantes do pai que foi dividido)

Como o Azure Cosmos DB distribui RU/s uniformemente em todas as partições físicas, cada partição física ainda receberá 10.000 RU/s. No entanto, agora temos uma distorção no armazenamento e na distribuição de solicitações.

No diagrama a seguir, vemos que as partições 3 e 4 (as partições filhas da partição 2) têm cada uma 10.000 RU/s para atender solicitações de 20 GB de dados, enquanto a partição 1 tem 10.000 RU/s para atender solicitações para o dobro da quantidade de dados (40 GB).

Após a divisão, existem 3 PartitionKeyRangeIds, cada um com 10.000 RU/s. No entanto, um dos PartitionKeyRangeIds tem 50% do espaço total de chaves (40 GB), enquanto dois dos PartitionKeyRangeIds têm 25% do espaço total de chaves (20 GB)

Para manter uma distribuição de armazenamento uniforme, podemos primeiro aumentar nossa RU/s para garantir que cada partição seja dividida. Então, podemos baixar nosso RU/s de volta para o estado desejado.

Então, se começarmos com duas partições físicas, para garantir que as partições sejam mesmo pós-divisão, precisamos definir RU/s de tal forma que acabaremos com quatro partições físicas. Para conseguir isso, primeiro definiremos RU/s = 4 * 10.000 RU/s por partição = 40.000 RU/s. Então, após a conclusão da divisão, podemos reduzir nosso RU/s para 30.000 RU/s.

Como resultado, vemos no diagrama a seguir que cada partição física recebe 30.000 RU/s / 4 = 7500 RU/s para atender a solicitações de 20 GB de dados. No geral, mantemos armazenamento uniforme e distribuição de solicitações entre partições.

Depois que a divisão for concluída e o RU/s tiver sido reduzido de 40.000 RU/s para 30.000 RU/s, há 4 PartitionKeyRangeIds, cada um com 7500 RU/s e 25% do espaço total de chaves (20 GB)

Fórmula geral

Passo 1: Aumente o seu RU/s para garantir que todas as partições se dividem uniformemente

Em geral, se você tiver um número inicial de partições Pfísicas e quiser definir um RU/s desejado:S

Aumente o seu RU/s para: 10,000 * P * (2 ^ (ROUNDUP(LOG_2 (S/(10,000 * P)))). Isso dá o RU/s mais próximo do valor desejado que garantirá que todas as partições sejam divididas uniformemente.

Nota

Quando você aumenta o RU/s de um banco de dados ou contêiner, isso pode afetar o RU/s mínimo para o qual você pode diminuir no futuro. Normalmente, o mínimo de RU/s é igual a MAX (400 RU/s, armazenamento atual em GB * 1 RU/s, maior RU/s já provisionado / 100). Por exemplo, se o RU/s mais alto que você já escalou for 100.000 RU/s, o menor RU/s que você pode definir no futuro será 1000 RU/s. Saiba mais sobre o mínimo de RU/s.

Passo 2: Abaixe o seu RU/s para o RU/s desejado

Por exemplo, suponha que temos cinco partições físicas, 50.000 RU/s e queremos dimensionar para 150.000 RU/s. Devemos primeiro definir: 10,000 * 5 * (2 ^ (ROUND(LOG_2(150,000/(10,000 * 5)))) = 200.000 RU/s, e depois diminuir para 150.000 RU/s.

Quando ampliamos para 200.000 RU/s, o menor RU/s manual que podemos definir no futuro é 2000 RU/s. A escala automática máxima mais baixa que podemos definir é de 20.000 RU/s (escalas entre 2000 - 20.000 RU/s). Como nosso RU/s alvo é de 150.000 RU/s, não somos afetados pelo RU/s mínimo.

Como otimizar RU/s para ingestão de dados grandes

Quando você planeja migrar ou ingerir uma grande quantidade de dados para o Azure Cosmos DB, é recomendável definir o RU/s do contêiner para que o Azure Cosmos DB pré-provisione as partições físicas necessárias para armazenar a quantidade total de dados que você planeja ingerir antecipadamente. Caso contrário, durante a ingestão, o Azure Cosmos DB pode ter que dividir partições, o que adiciona mais tempo à ingestão de dados.

Podemos aproveitar o fato de que, durante a criação de contêineres, o Azure Cosmos DB usa a fórmula heurística de iniciar RU/s para calcular o número de partições físicas para começar.

Passo 1: Reveja a escolha da chave de partição

Siga as práticas recomendadas para escolher uma chave de partição para garantir que você terá uma distribuição uniforme do volume de solicitações e do armazenamento pós-migração.

Etapa 2: Calcule o número de partições físicas necessárias

Number of physical partitions = Total data size in GB / Target data per physical partition in GB

Cada partição física pode conter um máximo de 50 GB de armazenamento (30 GB para API para Cassandra). O valor que você deve escolher para o Target data per physical partition in GB depende de quão totalmente compactado você deseja que as partições físicas sejam e quanto você espera que o armazenamento cresça após a migração.

Por exemplo, se você prevê que o armazenamento continuará a crescer, poderá optar por definir o valor como 30 GB. Supondo que você tenha escolhido uma boa chave de partição que distribua uniformemente o armazenamento, cada partição estará ~60% cheia (30 GB de 50 GB). À medida que os dados futuros são gravados, eles podem ser armazenados no conjunto existente de partições físicas, sem exigir que o serviço adicione imediatamente mais partições físicas.

Por outro lado, se você acredita que o armazenamento não crescerá significativamente após a migração, pode optar por definir o valor mais alto, por exemplo, 45 GB. Isso significa que cada partição estará ~90% cheia (45 GB de 50 GB). Isso minimiza o número de partições físicas pelas quais seus dados estão espalhados, o que significa que cada partição física pode obter uma fração maior do total de RU/s provisionados.

Passo 3: Calcular o número de RU/s para começar para todas as partições

Starting RU/s for all partitions = Number of physical partitions * Initial throughput per physical partition.

Vamos começar com um exemplo com um número arbitrário de RU/s de destino por partição física.

  • Initial throughput per physical partition = 10.000 RU/s por partição física ao usar o dimensionamento automático ou bancos de dados de taxa de transferência compartilhados
  • Initial throughput per physical partition = 6000 RU/s por partição física ao usar a taxa de transferência manual

Exemplo

Digamos que temos 1 TB (1000 GB) de dados que planejamos ingerir e queremos usar a taxa de transferência manual. Cada partição física no Azure Cosmos DB tem uma capacidade de 50 GB. Vamos supor que pretendemos empacotar partições para estar 80% cheio (40 GB), deixando-nos espaço para crescimento futuro.

Isso significa que, para 1 TB de dados, precisaremos de 1000 GB / 40 GB = 25 partições físicas. Para garantir que obteremos 25 partições físicas, se estivermos usando taxa de transferência manual, primeiro provisionamos 25 * 6000 RU/s = 150.000 RU/s. Então, depois que o recipiente é criado, para ajudar a nossa ingestão a ir mais rápido, aumentamos o RU/s para 250.000 RU/s antes da ingestão começar (acontece instantaneamente porque já temos 25 partições físicas). Isso permite que cada partição obtenha o máximo de 10.000 RU/s.

Se estivermos usando a taxa de transferência de dimensionamento automático ou um banco de dados de taxa de transferência compartilhado, para obter 25 partições físicas, primeiro provisionaremos 25 * 10.000 RU/s = 250.000 RU/s. Como já estamos no RU/s mais alto que pode ser suportado com 25 partições físicas, não aumentaríamos ainda mais nosso RU/s provisionado antes da ingestão.

Em teoria, com 250.000 RU/s e 1 TB de dados, se assumirmos documentos de 1 kb e 10 RUs necessários para a escrita, a ingestão pode teoricamente completar em: 1000 GB * (1.000.000 kb / 1 GB) * (1 documento / 1 kb) * (10 RU / documento) * (1 seg / 250.000 RU) * (1 hora / 3600 segundos) = 11,1 horas.

Esse cálculo é uma estimativa assumindo que o cliente que executa a ingestão pode saturar totalmente a taxa de transferência e distribuir gravações em todas as partições físicas. Como prática recomendada, recomenda-se "embaralhar" seus dados no lado do cliente. Isso garante que a cada segundo, o cliente está gravando em muitas partições lógicas (e, portanto, físicas) distintas.

Quando a migração terminar, podemos reduzir o RU/s ou ativar o dimensionamento automático conforme necessário.

Próximos passos