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
- Se você é novo em particionamento e dimensionamento no Azure Cosmos DB, é recomendável ler primeiro o artigo Particionamento e dimensionamento horizontal no Azure Cosmos DB.
- Se você estiver planejando dimensionar seu RU/s devido a 429 exceções, revise as orientações em Diagnosticar e solucionar problemas de exceções de taxa de solicitação do Azure Cosmos DB muito grandes (429). Antes de aumentar o RU/s, identifique a causa raiz do problema e se aumentar o RU/s é a solução correta.
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.
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.
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).
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.
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 P
fí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 compartilhadosInitial 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
- Monitore o consumo normalizado de RU/s do seu banco de dados ou contêiner.
- Diagnosticar e solucionar problemas de exceções de taxa de solicitação muito grande (429).
- Habilite o dimensionamento automático em um banco de dados ou contêiner.