Particionamento e escala horizontal no Azure Cosmos DB

APLICA-SE AO: NoSQL MongoDB Cassandra Gremlin Table

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. 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 sua chave de partição, mas estamos cobrindo-as para que você possa ter clareza sobre 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.

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, o sistema cria novas partições lógicas de forma transparente. Você não precisa se preocupar em excluir uma partição lógica quando os dados subjacentes são excluídos.

Não há limite para o número de partições lógicas no 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.

Você pode usar os alertas do Azure Monitor para monitorar se o tamanho de uma partição lógica está se aproximando de 20 GB.

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 o Azure Cosmos DB gerencia completamente as partições físicas.

O número de partições físicas no contêiner dependerá das seguintes características:

  • A quantidade de taxa de transferência provisionada (cada partição física individual pode fornecer uma taxa de transferência de até dez mil unidades de solicitação por segundo). O limite de 10.000 RU/s para partições físicas implica que as partições lógicas também têm um limite de 10.000 RU/s, pois cada partição lógica é mapeada apenas para uma partição física.

  • 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 no contêiner. À medida que a taxa de transferência ou o tamanho dos dados cresce, o Azure Cosmos DB cria 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.

Por exemplo, considere um contêiner com o caminho /foodGroup especificado como a chave de partição. O contêiner pode ter qualquer número de partições físicas, mas neste exemplo assumimos que ele tem três. Uma única partição física pode conter várias chaves de partição. Por exemplo, a maior partição física pode conter 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ê atribuir uma taxa de transferência de 18 mil 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. Para obter mais informações, consulte Escolher 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 obtido por hash 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 réplica hospeda uma instância do mecanismo de banco de dados. Um conjunto de réplicas torna o armazenamento de dados dentro da partição física durável, altamente disponível e consistente. 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 quatro réplicas.

A imagem a seguir mostra como as partições lógicas são mapeadas para partições físicas distribuídas globalmente. O conjunto de partições da imagem refere-se a um grupo de partições físicas que gerenciam as mesmas chaves de partição lógicas em várias regiões:

Uma imagem que demonstra o particionamento do Azure Cosmos DB

Escolher 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 os itens { "userId" : "Andrew", "worksFor": "Microsoft" }, se você escolher "userId" como a chave de partição, os dois componentes de chave de partição serão os seguintes:

  • 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. (Os trabalhos de cópia do contêiner ajudam nesse processo.)

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.

  • Ela deverá conter apenas valores de String. O ideal que os números sejam convertidos em String, caso eles possam estar fora dos limites dos números de precisão dupla de acordo com o IEEE 754 binary64. A especificação JSON destaca os motivos pelos quais o uso de números fora desse limite em geral é uma prática ruim devido a prováveis problemas de interoperabilidade. Essas questões são relevantes principalmente para a coluna de chave de partição, pois ela é imutável e requer a migração de dados para ser alterada posteriormente.

  • 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. Esse espalhamento garante o consumo de RU e a distribuição de armazenamento uniformes nas partições físicas.

  • Tem valores que normalmente não são maiores que 2048 bytes ou 101 bytes se chaves de partição grandes não estiverem habilitadas. Para obter mais informações, consulte chaves de partição grandes

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.

Observação

Se você tiver apenas uma partição física, o valor da chave de partição poderá não ser relevante, pois todas as consultas terão como destino a mesma partição física.

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.

Essa propriedade poderá ser uma boa opção de chave de partição 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. 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 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 exige mais do que algumas partições físicas quando qualquer uma das seguintes opções se aplica:

  • O contêiner tem mais de 30.000 RUs provisionadas

  • O contêiner armazena mais de 100 GB de dados

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

Observação

Esta seção se aplica principalmente à API para NoSQL. Outras APIs, como a API para Gremlin, não dão suporte ao identificador exclusivo como a chave de partição.

Se o contêiner tiver uma propriedade com uma grande variedade de valores possíveis, provavelmente ela será uma ótima opção de chave de partição. Um exemplo possível de tal propriedade é a ID do item. Nos contêineres pequenos de leitura pesada ou contêineres de gravação pesada de qualquer tamanho, a ID do item (/id) é 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 IDs 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 só ID do item por item, a ID do item é ótimo para balancear uniformemente o consumo de RU e o armazenamento de dados.
  • Você pode facilmente fazer leituras de pontos eficientes, pois 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. Não é possível criar itens que tenham IDs de item duplicadas.
  • 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 direcionados a várias partições lógicas.