Particionamento e escala horizontal no Azure Cosmos DB

APLICA-SE A: API do SQL API do Cassandra API do Gremlin API de Tabela API do Azure Cosmos DB para MongoDB

O Azure Cosmos DB usa o particionamento para dimensionar contêineres individuais em um banco de dados para atender às necessidades de desempenho do aplicativo. No particionamento, os itens em um contêiner são divididos em subconjuntos distintos, chamados de partições lógicas. As partições lógicas são formadas com base no valor de uma chave de partição associada a cada item em um contêiner. Todos os itens em uma partição lógica têm o mesmo valor de chave de partição.

Por exemplo, um contêiner contém itens. Cada item tem um valor exclusivo para a propriedade UserID. Se UserID for a chave de partição dos itens no contêiner e houver 1.000 valores UserID exclusivos, 1.000 partições lógicas serão criadas para o contêiner.

Além de uma chave de partição que determina a partição lógica do item, cada item em um contêiner tem uma ID de item (que é exclusivo dentro de uma partição lógica). A combinação da chave de partição com a ID do item cria o índice do item, que o identifica exclusivamente. A escolha de uma chave de partição é uma decisão importante que afetará o desempenho do aplicativo.

Este artigo explica a relação entre partições lógicas e físicas. Ele também aborda as práticas recomendadas para particionamento e fornece uma visão detalhada de como funciona a escala horizontal no Azure Cosmos DB. Não é necessário entender esses detalhes internos para selecionar a chave de partição, mas eles são abordados para que você entenda claramente como o Azure Cosmos DB funciona.

Partições lógicas

Uma partição lógica é composta de um conjunto de itens que têm a mesma chave de partição. Por exemplo, em um contêiner que contém dados sobre nutrição alimentar, todos os itens contêm uma propriedade foodGroup. Você pode usar foodGroup como a chave de partição para o contêiner. Grupos de itens que têm valores específicos para foodGroup, como Beef Products, Baked Products e Sausages and Luncheon Meats, formam partições lógicas distintas. Você não precisa se preocupar em excluir uma partição lógica quando os dados subjacentes são excluídos.

Uma partição lógica também define o escopo das transações de banco de dados. Você pode atualizar itens dentro de uma partição lógica usando uma transação com isolamento de instantâneo. Quando novos itens são adicionados a um contêiner, novas partições lógicas são criadas transparentemente pelo sistema.

Não há limite para o número de partições lógicas em seu contêiner. Cada partição lógica pode armazenar até 20 GB de dados. Boas opções de chave de partição têm uma grande variedade de valores possíveis. Por exemplo, em um contêiner em que todos os itens contêm uma propriedade foodGroup, os dados dentro da partição lógica Beef Products podem crescer até 20 GB. A seleção de uma chave de partição com uma grande variedade de valores possíveis garante que o contêiner consiga dimensionar.

Partições físicas

Um contêiner é escalado ao distribuir dados e taxa de transferência entre partições físicas. Internamente, uma ou mais partições lógicas são mapeadas até uma única partição física. Contêineres menores costumam ter muitas partições lógicas, mas exigem apenas uma única partição física. Ao contrário das partições lógicas, as partições físicas são uma implementação interna do sistema e são totalmente gerenciadas pelo Azure Cosmos DB.

O número de partições físicas no contêiner dependerá do seguinte:

  • O número de taxa de transferência provisionado (cada partição física individual pode fornecer uma taxa de transferência de até 10.000 unidades de solicitação por segundo).
  • O armazenamento de dados total (cada partição física individual pode armazenar até 50 GB de dados).

Observação

As partições físicas são uma implementação interna do sistema e são totalmente gerenciadas pelo Azure Cosmos DB. Ao desenvolver as soluções, não se concentre em partições físicas porque não é possível controlá-las. Em vez disso, concentre-se nas chaves de partição. Se você escolher uma chave de partição que distribua uniformemente o consumo de taxa de transferência entre partições lógicas, você garantirá que o consumo de taxa de transferência entre partições físicas seja equilibrado.

Não há limite para o número total de partições físicas em seu contêiner. À medida que a taxa de transferência ou tamanho dos dados cresce, o Azure Cosmos DB criará automaticamente novas partições físicas ao dividir as existentes. As divisões de partição física não afetam a disponibilidade do aplicativo. Após essa divisão, todos os dados em uma única partição lógica ainda serão armazenados na mesma partição física. Uma divisão de partição física cria um novo mapeamento de partições lógicas para partições físicas.

A taxa de transferência provisionada para um contêiner é dividida igualmente entre as partições físicas. Um design de chave de partição que não distribui solicitações uniformemente pode resultar em muitas solicitações direcionadas a um pequeno subconjunto de partições que se tornam "dinâmicas". As partições dinâmicas levam ao uso ineficiente de taxa de transferência provisionada, o que pode resultar em limitação de taxa e custos mais altos.

Você pode ver as partições físicas do contêiner na seção Armazenamento da folha Métricas do portal do Azure:

Exibição do número de partições físicas

Na captura de tela acima, um contêiner tem /foodGroup como a chave de partição. Cada uma das três barras no grafo representa uma partição física. Na imagem, o alcance de chaves de partição é o mesmo que uma partição física. A partição física selecionada contém as três principais partições lógicas de tamanho mais significativo: Beef Products, Vegetable and Vegetable Products e Soups, Sauces, and Gravies.

Se você provisionar uma taxa de transferência de 18.000 RU/s (unidades de solicitação por segundo), cada uma das três partições físicas poderá utilizar 1/3 da taxa de transferência total provisionada. Na partição física selecionada, as chaves de partição lógica Beef Products, Vegetable and Vegetable Products e Soups, Sauces, and Gravies podem, coletivamente, utilizar as 6.000 RU/s provisionadas da partição física. Como a taxa de transferência provisionada é dividida uniformemente entre as partições físicas do contêiner, é importante escolher uma chave de partição que distribua uniformemente o consumo da taxa de transferência escolhendo a chave de partição lógica correta.

Gerenciamento de partições lógicas

O Azure Cosmos DB gerencia de forma transparente e automática o posicionamento de partições lógicas em partições físicas para atender com eficiência as necessidades de escalabilidade e desempenho do contêiner. À medida que os requisitos de taxa de transferência e armazenamento de um aplicativo aumentam, o Azure Cosmos DB move as partições lógicas para distribuir automaticamente a carga entre um maior número de partições físicas. Saiba mais sobre partições físicas.

O Azure Cosmos DB usa particionamento baseado em hash para distribuir partições lógicas entre partições físicas. O Azure Cosmos DB corta o valor de chave de partição de um item. O resultado cortado determina a partição física. Depois, o Azure Cosmos DB aloca o espaço de chave dos hashes de chave de partição uniformemente entre as partições físicas.

Transações (em procedimentos armazenados ou gatilhos) são permitidas somente em itens em uma única partição lógica.

Conjuntos de réplicas

Cada partição física consiste em um conjunto de réplicas, também conhecido como um conjunto de réplicas. Cada conjunto de réplicas hospeda uma instância do mecanismo de banco de dados. Um conjunto de réplicas torna os dados armazenados dentro da partição física duráveis, altamente disponíveis e consistentes. Cada réplica que compõe a partição física herda a cota de armazenamento da partição. Todas as réplicas de uma partição física dão suporte, coletivamente, à taxa de transferência alocada para a partição física. O Azure Cosmos DB gerencia automaticamente os conjuntos de réplicas.

Normalmente, contêineres menores exigem uma única partição física, mas eles ainda terão pelo menos 4 réplicas.

A imagem a seguir mostra como as partições lógicas são mapeadas para partições físicas distribuídas globalmente:

Uma imagem que demonstra o particionamento do Azure Cosmos DB

Escolhendo uma chave de partição

Uma chave de partição tem dois componentes: caminho da chave de partição e o valor da chave de partição. Por exemplo, considere um item { "userId" : "Andrew", "worksFor": "Microsoft" } se você escolher "userId" como a chave de partição, estes são os dois componentes da chave de partição:

  • O caminho da chave de partição (por exemplo: "/userId"). O caminho da chave de partição aceita caracteres alfanuméricos e sublinhados (_). Você também pode usar objetos aninhados usando a notação de caminho padrão (/).

  • O valor da chave de partição (por exemplo, "Andrew"). O valor da chave de partição pode ser de tipos de cadeia de caracteres ou numéricos.

Para saber mais sobre os limites de taxa de transferência, armazenamento e comprimento da chave de partição, confira o artigo Cotas de serviço do Azure Cosmos DB.

A seleção da chave de partição é uma escolha de design simples e importante no Azure Cosmos DB. Depois de selecionar a chave de partição, não é possível alterá-la no local. Se você precisar alterar a chave de partição, mova seus dados para um novo contêiner com a nova chave de partição desejada.

Para todos os contêineres, a chave de partição deve:

  • Ser uma propriedade com um valor que não é alterado. Se uma propriedade for a chave de partição, você não poderá atualizar o valor dessa propriedade.

  • Tenha uma alta cardinalidade. Em outras palavras, a propriedade deve ter uma grande variedade de valores possíveis.

  • Distribua armazenamento de dados e consumo de RU (unidade de solicitação) uniformemente em todas as partições lógicas. Isso garante o consumo de RU e a distribuição de armazenamento uniformes nas partições físicas.

Se você precisar de transações ACID com vários itens no Azure Cosmos DB, será necessário usar procedimentos armazenados ou gatilhos. Todos os procedimentos armazenados e gatilhos baseados em JavaScript têm como escopo uma única partição lógica.

Chaves de partição para contêineres de leitura pesada

Para a maioria dos contêineres, os critérios acima são tudo o que você precisa considerar ao escolher uma chave de partição. No entanto, para contêineres grandes de leitura pesada, é bom escolher uma chave de partição que aparece com frequência como um filtro nas suas consultas. Consultas podem ser roteadas com eficiência somente para as partições físicas relevantes ao incluir a chave de partição no predicado de filtro.

Se a maioria das solicitações de carga de trabalho for consultas e a maioria das consultas tiver um filtro de igualdade na mesma propriedade, essa propriedade poderá ser uma boa opção de chave de partição. Por exemplo, se você executar com frequência uma consulta que filtra em UserID, selecionar UserID como a chave de partição reduziria o número de consultas entre partições.

No entanto, se o contêiner for pequeno, você provavelmente não terá partições físicas suficientes para se preocupar com o impacto no desempenho de consultas entre partições. A maioria dos contêineres pequenos no Azure Cosmos DB requer apenas uma ou duas partições físicas.

Se o contêiner puder aumentar para mais de algumas partições físicas, você deverá selecionar uma chave de partição que minimize as consultas entre partições. O contêiner exigirá mais do que algumas partições físicas quando qualquer uma das seguintes opções se aplicar:

  • O contêiner terá mais de 30.000 RUs provisionadas

  • O contêiner armazenará mais de 100 GB de dados

Usar a ID do item como a chave de partição

Se o contêiner tiver uma propriedade com uma grande variedade de valores possíveis, provavelmente será uma ótima opção de chave de partição. Um exemplo possível de tal propriedade é a ID do item. Para contêineres pequenos de leitura pesada ou contêineres de gravação pesada de qualquer tamanho, a ID do item é naturalmente uma ótima opção para a chave de partição.

A ID do item de propriedade do sistema existe em cada item em seu contêiner. Você pode ter outras propriedades que representam uma ID lógica do item. Em muitos casos, essas também são ótimas opções de chave de partição pelos mesmos motivos da ID do item.

A ID do item é uma ótima opção de chave de partição pelos seguintes motivos:

  • Há uma grande variedade de valores possíveis (uma única ID do item por item).
  • Como há uma única ID do item por item, a ID do item faz um ótimo trabalho em equilibrar uniformemente o consumo de RU e o armazenamento de dados.
  • Você poderá facilmente fazer leituras eficientes de ponto, pois você sempre saberá a chave de partição de um item se souber a ID do item.

Algumas coisas a serem consideradas ao selecionar a ID do item como a chave de partição incluem:

  • Se a ID do item for a chave de partição, ela se tornará um identificador exclusivo em todo o contêiner. Você não poderá ter itens com uma ID do item duplicada.
  • Se tiver um contêiner de leitura pesada com muitas partições físicas, as consultas serão mais eficientes se tiverem um filtro de igualdade com a ID do item.
  • Não será possível executar procedimentos armazenados ou gatilhos entre várias partições lógicas.

Próximas etapas