Compartilhar via


Práticas recomendadas para escalar a taxa de transferência provisionada (RU/s)

APLICA-SE AO: NoSQL MongoDB Cassandra Gremlin Table

Este artigo descreve as melhores práticas e estratégias para dimensionar a produtividade (RU/s) do banco de dados ou contêiner (coleção, tabela ou grafo). Os conceitos se aplicam quando você está aumentando as RU/s manuais provisionadas ou o máximo de RU/s de escala automática de qualquer recurso para qualquer uma das APIs de banco de dados Cosmos Azure.

Pré-requisitos

Plano de fundo sobre o dimensionamento de RU/s

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

  • Escala de escala instantânea
    • Quando as RU/s solicitadas podem ser suportadas pelo layout de partição física atual, o Azure Cosmos DB não precisa dividir nem adicionar novas partições.
    • Como resultado, a operação é concluída imediatamente e as RU/s estão disponíveis para uso.
  • Escalamento assíncrono
    • Quando as RU/s solicitadas são maiores do que as que podem ser suportadas pelo layout de partição física, o banco de dados Cosmos Azure dividirá as partições físicas existentes. Isso ocorre até que o recurso tenha o número mínimo de partições necessárias para dar suporte às RU/s solicitadas.
    • Como resultado, a operação pode levar algum tempo para ser concluída, normalmente de 4 a 6 horas. Cada partição física pode dar suporte a um máximo de 10.000 RU/s (aplica-se a todas as APIs) de taxa de transferência e 50 GB de armazenamento (aplica-se a todas as APIs, exceto Cassandra, que tem 30 GB de armazenamento).

Observação

Se você executar uma operação de failover de região manual 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 da taxa de transferência será pausada. Ela será retomada automaticamente quando a operação de failover ou adicionar/remover região for concluída.

  • Redução vertical instantânea
    • Para a operação de redução vertical, o Azure Cosmos DB não precisa dividir nem adicionar novas partições.
    • Como resultado, a operação é concluída imediatamente e as RUs ficam disponíveis para serem usadas.
    • O resultado principal dessa operação é que as RUs por partição física serão reduzidas.

Como escalar em escala as RU/s sem alterar o layout da partição

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

Navegue até Insights>Taxa de Transferência>Consumo de RU Normalizado (%) Por PartitionKeyRangeID. Conte o número distinto de PartitionKeyRangeIds.

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

Observação

O gráfico mostrará apenas um máximo de 50 PartitionKeyRangeIds. Se o 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 é mapeado para uma partição física e é atribuído para manter dados para um intervalo de valores de hash possíveis.

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 residem.

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

As RU/s mais altas para as que você pode dimensionar sem disparar o banco de dados Cosmos Azure para dividir partições é igual a Current number of physical partitions * 10,000 RU/s. Você pode obter esse valor junto ao Provedor de recursos do Azure Cosmos DB. Execute uma solicitação GET em seus objetos de configuração de taxa de transferência de banco de dados ou contêiner e recupere a propriedade instantMaximumThroughput. Esse valor também está disponível na página Dimensionamento 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 as RU/s para 5 * 10.000 RU/s = 50.000 RU/s instantaneamente. Da mesma forma, se tivéssemos um contêiner com dimensionar automaticamente o máximo de RU/s de 30.000 RU/s (dimensiona entre 3000 a 30.000 RU/s), poderíamos aumentar nosso máximo de RU/s para 50.000 RU/s instantaneamente (dimensiona entre 5000 e 50.000 RU/s).

Dica

Se você estiver dimensionando RU/s para responder à taxa de solicitação exceções muito grandes (429s), é recomendável aumentar primeiro as RU/s para as RU/s mais altas com suporte pelo layout de partição física atual e avaliar se as novas RU/s são suficientes antes de aumentar ainda mais.

Como garantir até mesmo a distribuição de dados durante o dimensionamento assíncrono

Tela de fundo

Quando você aumenta as RU/s além do número atual de partições físicas * 10 mil 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 filho.

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 produtividade para 45.000 RU/s, o BD Cosmos do Azure 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.

Observação

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

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

Para ver por quê, vamos dar um exemplo em que temos um contêiner existente com duas 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. Cada partição física é atribuída a aproximadamente 50% do keyspace, que é definido como o intervalo total de possíveis valores de hash.

Além disso, o banco de Cosmos Azure distribui RU/s de maneira desatada 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.

Duas PartitionKeyRangeIds, cada uma com 10.000 RU/s, 40 GB e 50% do keyspace total

Agora, suponha que desejamos aumentar nossas RU/s de 20.000 RU/s para 30.000 RU/s.

Se simplesmente aumentarmos as 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 (essa partição não foi dividida)
  • Duas partições que contêm 25% dos dados (essas são as partições filho resultantes do pai que foi dividido)

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

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

Após a divisão, há três PartitionKeyRangeIds, cada uma com 10.000 RU/s. No entanto, um dos PartitionKeyRangeIds tem 50% do keyspace total (40 GB), enquanto dois dos PartitionKeyRangeIds têm 25% do keyspace total (20 GB)

Para manter uma distribuição de armazenamento uniforme, primeiro podemos escalar as RU/s para garantir que cada partição seja dividida. Em seguida, podemos reduzir nossas RU/s de volta para o estado desejado.

Portanto, se começarmos com duas partições físicas, para garantir que as partições sejam até mesmo pós-divisão, precisamos definir RU/s de modo que acabaremos com quatro partições físicas. Para fazer isso, primeiro definiremos RU/s = 4 * 10.000 RU/s por partição = 40.000 RU/s. Em seguida, após a conclusão da divisão, podemos reduzir nossas RU/s para 30.000 RU/s.

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

Após a conclusão da divisão e a redução das RU/s de 40.000 RU/s para 30.000 RU/s, há 4 PartitionKeyRangeIds, cada um com 7.500 RU/s e 25% do keyspace total (20 GB)

Fórmula geral

Etapa 1: Aumentar suas RU/s para garantir que todas as partições se dividam de maneira igual

Em geral, se você tiver um número inicial de partições físicasP e quiser \definir uma RU/s desejadaS:

Aumente sua RU/s para: 10,000 * P * (2 ^ (ROUNDUP(LOG_2 (S/(10,000 * P)))). Isso fornece as RU/s mais próximas ao valor desejado, o que garantirá que todas as partições sejam divididas de maneira igual.

Observação

Quando você aumenta as RU/s de um banco de dados ou contêiner, isso pode afetar o mínimo de RU/s que você pode reduzir no futuro. Normalmente, o mínimo de RU/s é igual a MAX(400 RU/s, Armazenamento atual em GB * 1 RU/s, RU/s mais altas já provisionadas/100). Por exemplo, se as RU/s mais altas que você já escalonou for de 100.000 RU/s, as RU/s mais baixas que você pode definir no futuro são 1000 RU/s. Saiba mais sobre RU/s mínimos.

Etapa 2: reduza suas RU/s para as RU/s desejadas

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, em seguida, diminuir para 150.000 RU/s.

Quando escalamos para 200.000 RU/s, as RU/s manuais mais baixas que podemos definir no futuro são 2000 RU/s. Agora provisionamos o dimensionamento automático máximo para 20.000 RU/s (escala entre 2.000 e 20.000 RU/s). Como nossas RU/s de destino são 150.000 RU/s, não somos afetados pelo mínimo de RU/s.

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

Quando você planeja migrar ou ingerir uma grande quantidade de dados no BD Cosmos do Azure, é recomendável definir as RU/s do contêiner para que o BD Cosmos do Azure 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 poderá ter que dividir partições, o que adiciona mais tempo à ingestão de dados.

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

Etapa 1: Revisar a escolha da chave de partição

Siga as práticas recomendadas para escolher uma chave de partição para garantir que você tenha até mesmo a distribuição do volume de solicitações e do armazenamento após a migração.

Etapa 2: Calcular o número de partições físicas de que você precisará

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

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

Por exemplo, se você prever que o armazenamento continuará crescendo, poderá optar por definir o valor como 30 GB. Supondo que você tenha escolhido uma boa chave de partição que distribui o armazenamento de maneira íntegra, cada partição estará ~60% cheia (30 GB de 50 GB). À medida que 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 aumentará significativamente após a migração, você 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 são distribuídos, o que significa que cada partição física pode obter uma fração maior do total de RU/s provisionadas.

Etapa 3: calcular o número de RU/s para começar com todas as partições

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

Vamos iniciar 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 bancos de dados de taxa de transferência compartilhada ou de dimensionamento automático
  • 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 nosso objetivo é empacotar partições para que sejam 80% completas (40 GB), deixando espaço para o crescimento futuro.

Isso significa que, para 1 TB de dados, precisamos de 1000 GB/40 GB = 25 partições físicas. Para garantir que obteremos 25 partições físicas, se estamos usando a produtividade manual, primeiro provisionaremos 25 * 6000 RU/s = 150.000 RU/s. Depois que o contêiner é criado, para ajudar nossa ingestão a acelerar, aumentamos as RU/s para 250.000 RU/s antes do início da ingestão (ocorre instantaneamente porque já temos 25 partições físicas). Isso permite que cada partição receba o máximo de 10.000 RU/s.

Se estamos usando a produtividade de autoescala ou um banco de dados de produtividade compartilhado, para obter 25 partições físicas, primeiro provisionaríamos 25 * 10.000 RU/s = 250.000 RU/s. Como já estamos nas RU/s mais altas que podem ser suportadas com 25 partições físicas, não aumentaríamos ainda mais nossas RU/s provisionadas 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árias para gravação, A ingestão pode, teoricamente, ser concluída em: 1000 GB * (1.000.000 kb /1 GB) * (1 documento /1 kb) * (10 RU/documento) * (1 s / 250.000 RU) * (1 hora /3600 segundos) = 11,1 horas.

Esse cálculo é uma estimativa supondo que o cliente que executa a ingestão possa saturar totalmente a produtividade e distribuir gravações em todas as partições físicas. Como prática recomendada, é recomendável "embaralhar" seus dados no lado do cliente. Isso garante que, a cada segundo, o cliente está escrevendo em muitas partições lógicas distintas (e, portanto, físicas).

Depois que a migração for final, podemos reduzir as RU/s ou habilitar o autoescala conforme necessário.

Próximas etapas