Sans sharding, toutes les données d'une collection résident sur un seul shard tandis que les autres restent inactifs. Le sharding répartit les données sur l'ensemble des shards afin que chacun traite une partie de la charge de travail.
L'exemple suivant présente la sortie de la commande db.stats() avant la configuration du sharding. Un shard (mgset-xxx65) ne contient aucune donnée, alors que les 1 000 021 objets se trouvent tous sur l'autre shard (mgset-xxx67) :
mongos> db.stats()
{
"raw" : {
"mgset-xxx65/xxx" : {
"db" : "mongodbtest",
"collections" : 0,
"views" : 0,
"objects" : 0,
"avgObjSize" : 0,
"dataSize" : 0,
"storageSize" : 0,
"numExtents" : 0,
"indexes" : 0,
"indexSize" : 0,
"fileSize" : 0,
"ok" : 1,
"$gleStats" : {
"lastOpTime" : Timestamp(0, 0),
"electionId" : ObjectId("7fffffff0000000000000001")
}
},
"mgset-xxx67/xxx" : {
"db" : "mongodbtest",
"collections" : 2,
"views" : 0,
"objects" : 1000021,
"avgObjSize" : 352.4417477232978,
"dataSize" : 352449149,
"storageSize" : 209125376,
"numExtents" : 0,
"indexes" : 1,
"indexSize" : 10141696,
"ok" : 1,
"$gleStats" : {
"lastOpTime" : Timestamp(0, 0),
"electionId" : ObjectId("7fffffff0000000000000001")
}
}
}
}
Prérequis
L'instance doit être un cluster sharded.
Sélection de la clé de sharding
Une clé de sharding détermine la manière dont MongoDB distribue les données entre les shards. Choisissez cette clé avec soin, car elle influence directement les performances des requêtes et la répartition des données. Pour en savoir plus, consultez les pages Shard keys et Comment sélectionner une clé de sharding.
Une bonne clé de sharding possède trois caractéristiques :
Cardinalité élevée : la clé comporte de nombreuses valeurs distinctes, ce qui permet une distribution fine des données.
Faible fréquence : aucune valeur unique ne domine. Les valeurs fréquentes génèrent de gros chunks impossibles à déplacer.
Variation non monotone : la clé n'augmente ni ne diminue de façon constante. Les clés monotones dirigent toutes les écritures vers un seul shard.
La mutabilité de la clé de sharding dépend de la version de MongoDB :
Avant la version 4.4 : il est impossible de modifier ou de supprimer les clés de sharding après leur création.
Version 4.4 et ultérieures : la commande refineCollectionShardKey ajoute un champ suffixe à une clé de sharding existante.
Version 5.0 et ultérieures : la commande reshardCollection modifie entièrement la clé de sharding.
Stratégies de sharding
MongoDB prend en charge le sharding par plage, le sharding haché et les clés de sharding composées.
| Propriété | Sharding par plage | Sharding haché |
|---|---|---|
| Mécanisme | Divise les données en chunks selon des plages de valeurs de la clé de sharding | Hache la valeur d'un champ unique et distribue les données par plages de hachage |
| Distribution | Peut être inégale ; risque de créer des points chauds sans répartition des écritures | Répartition homogène sur tous les nœuds de shard ; assure la distribution des écritures |
| Requêtes par plage | Efficaces. Le routeur mongos localise directement le shard cible. | Peu efficaces. Les requêtes sont diffusées à tous les nœuds de shard. |
| Meilleur cas d'usage | Clés non monotones à cardinalité élevée et faible fréquence ; charges de travail s'appuyant sur des requêtes par plage | Clés à croissance ou décroissance monotone à cardinalité élevée ; charges de travail nécessitant des lectures et écritures aléatoires |
| Valeur de la clé de sharding | 1 (croissant) ou -1 (décroissant) |
"hashed" |
Les clés de sharding composées combinent plusieurs champs. Utilisez-les lorsqu'aucun champ unique n'offre une cardinalité suffisante ou lorsque les requêtes filtrent sur plusieurs champs. Par exemple, associez une clé à faible cardinalité à une clé à croissance monotone.
Choisir une stratégie
Privilégiez le sharding par plage lorsque les requêtes analysent fréquemment une plage de valeurs de la clé de sharding. Assurez-vous que la clé est non monotone pour éviter les points chauds.
Optez pour le sharding haché lorsque le volume d'écritures est élevé et que les données doivent être distribuées uniformément. Acceptez le compromis selon lequel les requêtes par plage atteignent tous les nœuds de shard.
Sharder une collection
La procédure suivante utilise la base de données mongodbtest et la collection customer à titre d'exemple.
Étape 1 : Se connecter au cluster sharded
Connectez-vous à l'instance de cluster sharded via le shell mongo. Pour connaître les méthodes de connexion, consultez la rubrique Se connecter à une instance de cluster sharded.
Étape 2 : Activer le sharding pour la base de données
Ignorez cette étape si l'instance exécute MongoDB 6.0 ou une version ultérieure. À partir de MongoDB 6.0, la fonction sh.enableSharding() n'est plus requise.
Exécutez la commande suivante pour activer le sharding sur la base de données cible :
sh.enableSharding("mongodbtest")
Étape 3 : Créer un index sur la clé de sharding
Avant de sharder une collection, créez un index compatible avec la clé de sharding.
Syntaxe :
db.<collection>.createIndex(<keyPatterns>, <options>)
Pour plus d'informations, consultez la page db.collection.createIndex().
Exemple de sharding par plage (index croissant sur le champ name) :
db.customer.createIndex({ name: 1 })
Exemple de sharding haché (index haché sur le champ name) :
db.customer.createIndex({ name: "hashed" })
Valeurs possibles pour le type d'index :
| Valeur | Type |
|---|---|
1 |
Croissant |
-1 |
Décroissant |
"hashed" |
Haché |
Étape 4 : Sharder la collection
Exécutez la commande sh.shardCollection() pour sharder la collection.
Syntaxe :
sh.shardCollection("<database>.<collection>", { "<key>": <value> })
Exemple de sharding par plage :
sh.shardCollection("mongodbtest.customer", { "name": 1 })
Exemple de sharding haché :
sh.shardCollection("mongodbtest.customer", { "name": "hashed" })
Le paramètre <value> détermine la stratégie de sharding :
| Valeur | Stratégie |
|---|---|
1 |
Sharding par plage |
"hashed" |
Sharding haché |
Étape 5 : Attendre que le balancer distribue les données
Après la configuration du sharding, le balancer divise automatiquement les données répondant aux critères et migre les chunks entre les nœuds de shard.
Le balancer consomme des ressources de l'instance lors de la migration des données. Effectuez le sharding initial pendant les heures creuses. Définir une fenêtre active pour le balancer permet de restreindre l'activité du balancer à des périodes spécifiques et d'éviter tout impact sur les performances pendant les heures de pointe.
Vérifier la configuration du sharding
Contrôler la distribution des données
Exécutez la commande sh.status() pour afficher l'état du sharding et la distribution des données sur les nœuds de shard :
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5xxx")
}
shards:
{ "_id" : "d-bpxxx3c4", "host" : "mgset-xxx29/xxx", "state" : 1 }
{ "_id" : "d-bpxxx834", "host" : "mgset-xxx27/xxx", "state" : 1 }
active mongoses:
"3.4.6" : 2
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
51 : Success
databases:
{ "_id" : "mongodbtest", "primary" : "d-bpxxx834", "partitioned" : true }
mongodbtest.customer
shard key: { "name" : 1 }
unique: false
balancing: true
chunks:
d-bpxxx3c4 51
d-bpxxx834 52
too many chunks to print, use verbose if you want to force print
{ "_id" : "test", "primary" : "d-bpxxx834", "partitioned" : false }
Vérifier le stockage par shard
Exécutez la commande db.stats() pour afficher les statistiques de stockage de chaque nœud de shard :
mongos> db.stats()
{
"raw" : {
"mgset-xxx" : {
"db" : "mongodbtest",
"collections" : 2,
"views" : 0,
"objects" : 496075,
"avgObjSize" : 353.0421932167515,
"dataSize" : 175135406,
"storageSize" : 434943968,
"numExtents" : 0,
"indexes" : 2,
"indexSize" : 17107270,
"ok" : 1,
"$gleStats" : {
"lastOpTime" : Timestamp(0, 0),
"electionId" : ObjectId("7fffffff0000000000000001")
}
},
"mgset-xxx" : {
"db" : "mongodbtest",
"collections" : 2,
"views" : 0,
"objects" : 505423,
"avgObjSize" : 352.9883444164591,
"dataSize" : 178408428,
"storageSize" : 501801512,
"numExtents" : 0,
"indexes" : 2,
"indexSize" : 17493372,
"ok" : 1,
"$gleStats" : {
"lastOpTime" : Timestamp(0, 0),
"electionId" : ObjectId("7fffffff0000000000000001")
}
}
}
}
Après le sharding, les deux nœuds de shard stockent des volumes de données sensiblement équivalents (environ 496 075 et 505 423 objets respectivement).