Partitionnement pour une scalabilité horizontale dans Azure Cosmos DB for MongoDB vCore
Azure Cosmos DB for MongoDB vCore prend en charge le partitionnement pour distribuer horizontalement les données et le trafic. Les documents d’une collection sont divisés en plusieurs parties appelées partitions logiques.
Le partitionnement est défini individuellement pour chaque collection à l’aide d’une clé de partition désignée de la structure de documents de la collection. Les données sont ensuite compartimentées en plusieurs parties et chacune d’elles correspond à une partition logique. Les documents pour chaque valeur unique de la propriété de clé de partition résident dans la même partition logique.
Pour chaque document inséré dans une collection partitionnée, la valeur de la propriété de clé de partition fait l’objet d’un hachage pour calculer la partition logique désignée. Le placement de la partition logique et la distribution de toutes les partitions logiques au sein du cluster n’incombent pas à l’utilisateur, car ils sont entièrement gérés par le service.
Partitions logiques
Tous les documents contenant la même valeur pour la clé de partition appartiennent à la même partition logique.
Prenons par exemple une collection appelée Employees avec la structure de document ci-dessous.
Ce tableau montre un mappage des valeurs de clé de partition à des partitions logiques.
ID document | Valeur de clé de partition | Partition logique |
---|---|---|
"12345" | "Steve Smith" | Partition 1 |
"23456" | "Jane Doe" | Partition 2 |
"34567" | "Steve Smith" | Partition 1 |
"45678" | "Michael Smith" | Partition 3 |
"56789" | "Jane Doe" | Partition 2 |
Le nombre de partitions logiques d’une collection est illimité. Une collection peut avoir autant de partitions logiques que de documents avec une valeur unique pour la propriété de clé de partition dans chaque document.
La taille d’une partition logique est également illimitée.
De plus, le service ne limite pas les transactions à l’étendue d’une partition logique. Le service basé sur vCore pour Azure Cosmos DB for MongoDB prend en charge les transactions de lecture et d’écriture applicables sur plusieurs partitions logiques et sur plusieurs partitions physiques du cluster.
Partitions physiques
Les partitions physiques sont les machines et disques sous-jacents responsables de la persistance des données et de la réalisation des transactions de base de données. Contrairement aux partitions logiques, le service gère les partitions physiques en sous-marin.
Le nombre de partitions physiques est défini lors de la création d’un cluster. Les clusters à partition unique ont une partition physique entièrement responsable du stockage et des transactions de base de données du cluster. Les clusters à plusieurs partitions distribuent le volume de données et de transactions entre les partitions physiques du cluster.
Mappage de partitions logiques à des partitions physiques
Lorsque de nouvelles partitions logiques sont ajoutées, le cluster met à jour de façon transparente le mappage des partitions logiques aux partitions physiques. De même, l’affectation de l’espace d’adressage à chaque partition physique est modifiée au fur et à mesure que de nouvelles partitions physiques sont ajoutées au cluster, à la suite de quoi les partitions logiques sont rééquilibrées sur le cluster.
La plage de hachage utilisée pour mapper les partitions logiques et physiques est répartie uniformément entre les partitions physiques du cluster. Chaque partition physique possède un compartiment de taille égale de la plage de hachage. Pour chaque document écrit, la valeur de la propriété de clé de partition est hachée et la valeur de hachage détermine le mappage du document à la partition physique sous-jacente. En interne, plusieurs partitions logiques sont mappées à une seule partition physique. De plus, les partitions logiques ne sont jamais réparties entre les partitions physiques et tous les documents d’une partition logique sont mappés à une seule partition physique.
En se basant sur l’exemple précédent et en utilisant un cluster avec deux partitions physiques, ce tableau montre un exemple de mappage de documents à des partitions physiques.
ID document | Valeur de clé de partition | Partition logique | Partition physique |
---|---|---|---|
"12345" | "Steve Smith" | Partition 1 | Partition physique 1 |
"23456" | "Jane Doe" | Partition 2 | Partition physique 2 |
"34567" | "Steve Smith" | Partition 1 | Partition physique 1 |
"45678" | "Michael Smith" | Partition 3 | Partition physique 1 |
"56789" | "Jane Doe" | Partition 2 | Partition physique 2 |
Capacité des partitions physiques
Le niveau de cluster sélectionné lorsque le cluster est approvisionné détermine la capacité du processeur et de la mémoire d’une partition physique. De même, la référence SKU de stockage détermine la capacité du stockage et des IOPS d’une partition physique. Les niveaux de cluster supérieurs fournissent une plus grande puissance de calcul et une plus grande mémoire, tandis que les disques de stockage supérieurs fournissent davantage de stockage et d’IOPS. Les charges de travail lourdes en lecture bénéficient d’un niveau de cluster supérieur, tandis que les charges de travail lourdes en écriture bénéficient d’une référence SKU de stockage supérieure. Le niveau de cluster peut faire l’objet d’un scale-up une fois le cluster créé en fonction des besoins changeants de l’application.
Dans un cluster à plusieurs partitions, la capacité de chaque partition physique est la même. Le scale-up du niveau du cluster ou de la référence SKU de stockage ne change pas le placement des partitions logiques sur les partitions physiques. Après une opération de scale-up, le nombre de partitions physiques reste le même, ce qui évite de devoir rééquilibrer les données dans le cluster.
La capacité de calcul, de mémoire, de stockage et d’IOPS de la partition physique détermine les ressources disponibles pour les partitions logiques. Les clés de partition qui n’ont pas une distribution égale des volumes de stockage et de requête peuvent entraîner une consommation inégale de stockage et de débit au sein du cluster. Les partitions à chaud peuvent entraîner une utilisation inégale des partitions physiques, ce qui aboutit à un débit et des performances imprévisibles. C’est pourquoi les clusters partitionnés nécessitent une planification minutieuse pour garantir des performances constantes à mesure que les besoins de l’application changent.
Jeux de réplicas
Chaque partition physique se compose d’un ensemble de réplicas, également appelé jeu de réplicas. Chaque réplica héberge une instance du moteur de base de données. Avec un jeu de réplicas, le stockage des données dans la partition physique est durable, hautement disponible et constant. Chaque réplica qui compose la partition physique hérite du stockage et de la capacité de calcul de la partition physique. Azure Cosmos DB for MongoDB vCore gère automatiquement les jeux de réplicas.
Bonnes pratiques pour le partitionnement des données
Le partitionnement dans Azure Cosmos DB for MongoDB vCore n’est pas nécessaire, sauf si les volumes de stockage et de transactions de la collection peuvent dépasser la capacité d’une seule partition physique. Par exemple, le service fournit des disques de 32 To par partition. Si une collection nécessite plus de 32 To, elle doit être partitionnée.
Il n’est pas nécessaire de partitionner chaque collection d’un cluster avec plusieurs partitions physiques. Les collections partitionnées et non partitionnées peuvent coexister dans le même cluster. Le service distribue de façon optimale les collections au sein du cluster pour utiliser les ressources de calcul et de stockage du cluster aussi uniformément que possible.
Pour les applications lourdes en lecture, la clé de partition doit être sélectionnée en fonction des modèles de requête les plus fréquents. Le filtre de requête le plus couramment utilisé pour une collection doit être choisi comme clé de partition pour optimiser le pourcentage le plus élevé de transactions de base de données en localisant la recherche sur une seule partition physique.
Pour les applications lourdes en écriture qui favorisent les performances d’écriture par rapport aux lectures, une clé de partition doit être choisie pour répartir uniformément les données entre les partitions physiques. Les clés de partition avec la cardinalité la plus élevée constituent la meilleure option pour distribuer aussi uniformément que possible.
Pour des performances optimales, la taille de stockage d’une partition logique doit être inférieure à 4 To.
Pour des performances optimales, les partitions logiques doivent être distribuées uniformément dans le volume de stockage et de requête sur les partitions physiques du cluster.
Comment partitionner une collection
Considérez le document suivant dans la base de données « cosmicworks » et la collection « employés »
{
"firstName": "Steve",
"lastName": "Smith",
"companyName": "Microsoft",
"division": "Azure",
"subDivision": "Data & AI",
"timeInOrgInYears": 7
}
L’exemple suivant partitionne la collection Employees dans la base de données cosmicworks sur la propriété firstName.
use cosmicworks;
sh.shardCollection("cosmicworks.employee", {"firstName": "hashed"})
La collection peut également être partitionnée à l’aide d’une commande d’administrateur :
use cosmicworks;
db.adminCommand({
"shardCollection": "cosmicworks.employee",
"key": {"firstName": "hashed"}
})
Même s’il n’est pas idéal de changer la clé de partition lorsque le volume de stockage de la collection augmente considérablement, la commande reshardCollection peut être utilisée pour modifier la clé de partition.
use cosmicworks;
sh.reshardCollection("cosmicworks.employee", {"lastName": "hashed"})
La collection peut également être repartitionnée à l’aide d’une commande d’administrateur :
use cosmicworks;
db.adminCommand({
"reshardCollection": "cosmicworks.employee",
"key": {"lastName": "hashed"}
})
En guise de bonne pratique, un index doit être créé sur la propriété de clé de partition.
use cosmicworks;
db.runCommand({
createIndexes: "employee",
indexes: [{"key":{"firstName":1}, "name":"firstName_1", "enableLargeIndexKeys": true}],
blocking: true
})