Compartilhamento para escalabilidade horizontal no Azure Cosmos DB para MongoDB vCore
O Azure Cosmos DB para MongoDB vCore suporta fragmentação para distribuir horizontalmente dados e tráfego. Os documentos dentro de uma coleção são divididos em pedaços chamados fragmentos lógicos.
O compartilhamento é definido individualmente para cada coleção usando uma chave de fragmento designada da estrutura de documentos da coleção. Os dados são então agrupados em partes com cada parte correspondendo a uma partição lógica. Os documentos para cada valor exclusivo da propriedade da chave de fragmento residem no mesmo fragmento lógico.
Para cada documento inserido em uma coleção fragmentada, o valor da propriedade da chave de fragmento é colocado em hash para calcular o fragmento lógico designado. O ônus de colocar o fragmento lógico e distribuir todos os fragmentos lógicos dentro do cluster são abstraídos do usuário e totalmente gerenciados pelo serviço.
Fragmentos lógicos
Todos os documentos que contêm o mesmo valor para a chave de fragmento pertencem ao mesmo fragmento lógico.
Por exemplo, vamos considerar uma coleção chamada Funcionários com a estrutura do documento abaixo.
Esta tabela mostra um mapeamento de valores de chave de estilhaço para partições lógicas.
ID do Documento | Valor da chave de estilhaço | Fragmento lógico |
---|---|---|
"12345" | "Steve Smith" | Shard 1 |
"23456" | "Jane Doe" | Shard 2 |
"34567" | "Steve Smith" | Shard 1 |
"45678" | "Michael Smith" | Shard 3 |
"56789" | "Jane Doe" | Shard 2 |
Não há limites para o número de fragmentos lógicos para uma coleção. Uma coleção pode ter tantos fragmentos lógicos quanto documentos com um valor exclusivo para a propriedade de chave de fragmento em cada documento.
Também não há limites para o tamanho de um único fragmento lógico.
Além disso, o serviço não limita as transações ao escopo de um fragmento lógico. O serviço baseado em vCore para Azure Cosmos DB para MongoDB dá suporte a transações de leitura e gravação que são aplicáveis em vários fragmentos lógicos e em vários fragmentos físicos no cluster.
Fragmentos físicos
Os fragmentos físicos são as máquinas e discos subjacentes responsáveis por persistir os dados e realizar transações de banco de dados. Ao contrário dos fragmentos lógicos, o serviço gerencia fragmentos físicos sob as cobertas.
O número de fragmentos físicos é definido quando um cluster é criado. Os clusters de fragmento único têm um fragmento físico que é inteiramente responsável pelas transações de armazenamento e banco de dados do cluster. Os clusters de vários fragmentos distribuem os dados e o volume de transações pelos fragmentos físicos no cluster.
Mapeando fragmentos lógicos para fragmentos físicos
Quando novos fragmentos lógicos são adicionados, o cluster atualiza perfeitamente o mapeamento de fragmentos lógicos para físicos. Da mesma forma, a atribuição do espaço de endereço a cada fragmento físico é alterada à medida que novos fragmentos físicos são adicionados ao cluster, após o que os fragmentos lógicos são rebalanceados no cluster.
O intervalo de hash usado para mapear fragmentos lógicos e físicos é distribuído uniformemente entre os fragmentos físicos no cluster. Cada fragmento físico possui um bucket de tamanho uniforme do intervalo de hash. Para cada documento gravado, o valor da propriedade da chave de fragmento é colocado em hash e o valor de hash determina o mapeamento do documento para o fragmento físico subjacente. Internamente, vários fragmentos lógicos são mapeados para um único fragmento físico. Além disso, os fragmentos lógicos nunca são divididos entre fragmentos físicos e todos os documentos para um fragmento lógico são mapeados apenas para um fragmento físico.
Com base no exemplo anterior usando um cluster com dois fragmentos físicos, esta tabela mostra um exemplo de mapeamento de documentos para fragmentos físicos.
ID do Documento | Valor da chave de estilhaço | Fragmento lógico | Fragmento Físico |
---|---|---|---|
"12345" | "Steve Smith" | Shard 1 | Fragmento Físico 1 |
"23456" | "Jane Doe" | Shard 2 | Fragmento Físico 2 |
"34567" | "Steve Smith" | Shard 1 | Fragmento Físico 1 |
"45678" | "Michael Smith" | Shard 3 | Fragmento Físico 1 |
"56789" | "Jane Doe" | Shard 2 | Fragmento Físico 2 |
Capacidade dos estilhaços físicos
A camada de cluster selecionada quando o cluster é provisionado determina a CPU e a capacidade de memória de um fragmento físico. Da mesma forma, a SKU de armazenamento determina a capacidade de armazenamento e IOPS de um fragmento físico. Camadas de cluster maiores fornecem mais poder de computação e maior memória, enquanto discos de armazenamento maiores fornecem mais armazenamento e IOPS. As cargas de trabalho pesadas de leitura se beneficiam de uma camada de cluster maior, enquanto as cargas de trabalho pesadas de gravação se beneficiam de uma SKU de armazenamento maior. A camada de cluster pode ser dimensionada para cima e para baixo depois que o cluster é criado com base nas necessidades variáveis do aplicativo.
Em um cluster de vários estilhaços, a capacidade de cada fragmento físico é a mesma. A expansão da camada de cluster ou da SKU de armazenamento não altera o posicionamento de fragmentos lógicos nos fragmentos físicos. Após uma operação de expansão, o número de fragmentos físicos permanece o mesmo, evitando assim a necessidade de reequilibrar os dados no cluster.
A capacidade de computação, memória, armazenamento e IOPS do fragmento físico determinam os recursos disponíveis para os fragmentos lógicos. As chaves de estilhaço que não têm uma distribuição uniforme de volumes de armazenamento e solicitação podem causar armazenamento desigual e consumo de taxa de transferência dentro do cluster. As partições quentes podem fazer com que os fragmentos físicos sejam utilizados de forma desigual, levando a uma taxa de transferência e desempenho imprevisíveis. Assim, clusters fragmentados exigem um planejamento inicial cuidadoso para garantir que o desempenho permaneça consistente à medida que os requisitos do aplicativo mudam ao longo do tempo.
Conjuntos de réplicas
Cada fragmento físico consiste em um conjunto de réplicas, também conhecido como 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 do fragmento físico durável, altamente disponível e consistente. Cada réplica que compõe o fragmento físico herda a capacidade de armazenamento e computação do fragmento físico. O Azure Cosmos DB para MongoDB vCore gerencia automaticamente conjuntos de réplicas.
Práticas recomendadas para fragmentação de dados
O compartilhamento no Azure Cosmos DB para MongoDB vCore não é necessário, a menos que os volumes de armazenamento e transação da coleção possam exceder a capacidade de um único fragmento físico. Por exemplo, o serviço fornece discos de 32 TB por estilhaço. Se uma coleção requer mais de 32 TB, ela deve ser fragmentada.
Não é necessário fragmentar todas as coleções em um cluster com vários fragmentos físicos. Coleções fragmentadas e não fragmentadas podem coexistir no mesmo cluster. O serviço distribui de forma ideal as coleções dentro do cluster para utilizar uniformemente os recursos de computação e armazenamento do cluster da forma mais uniforme possível.
Para aplicativos de leitura pesada, a chave de estilhaço deve ser selecionada com base nos padrões de consulta mais frequentes. O filtro de consulta mais comumente usado para uma coleção deve ser escolhido como a chave de fragmento para otimizar a maior porcentagem de transações de banco de dados localizando a pesquisa para um único fragmento físico.
Para aplicativos pesados de gravação que favorecem o desempenho de gravação em detrimento das leituras, uma chave de estilhaço deve ser escolhida para distribuir uniformemente os dados entre os fragmentos físicos. As teclas de estilhaços com a cardinalidade mais alta oferecem a melhor oportunidade de distribuir uniformemente o mais uniformemente possível.
Para um desempenho ideal, o tamanho de armazenamento de um fragmento lógico deve ser inferior a 4 TB.
Para um desempenho ideal, os fragmentos lógicos devem ser distribuídos uniformemente no armazenamento e no volume de solicitações pelos fragmentos físicos do cluster.
Como fragmentar uma coleção
Considere o seguinte documento dentro do banco de dados 'cosmicworks' e da coleção 'employee'
{
"firstName": "Steve",
"lastName": "Smith",
"companyName": "Microsoft",
"division": "Azure",
"subDivision": "Data & AI",
"timeInOrgInYears": 7
}
O exemplo a seguir fragmenta a coleção de funcionários dentro do banco de dados cosmicworks na propriedade firstName.
use cosmicworks;
sh.shardCollection("cosmicworks.employee", {"firstName": "hashed"})
A coleção também pode ser fragmentada usando um comando admin:
use cosmicworks;
db.adminCommand({
"shardCollection": "cosmicworks.employee",
"key": {"firstName": "hashed"}
})
Embora não seja ideal alterar a chave de fragmento depois que a coleção cresceu significativamente em volume de armazenamento, o comando reshardCollection pode ser usado para alterar a chave de estilhaço.
use cosmicworks;
sh.reshardCollection("cosmicworks.employee", {"lastName": "hashed"})
A coleção também pode ser reharded usando um comando admin:
use cosmicworks;
db.adminCommand({
"reshardCollection": "cosmicworks.employee",
"key": {"lastName": "hashed"}
})
Como prática recomendada, um índice deve ser criado na propriedade da chave de estilhaço.
use cosmicworks;
db.runCommand({
createIndexes: "employee",
indexes: [{"key":{"firstName":1}, "name":"firstName_1", "enableLargeIndexKeys": true}],
blocking: true
})