Le sharding met à l'échelle les bases de données en répartissant les données sur plusieurs nœuds, mais il ajoute du routage, du rééquilibrage et de nouveaux modes de panne qui rendent le système plus difficile à comprendre.

Le sharding (appelé aussi partitionnement horizontal) consiste à présenter à votre application ce qui ressemble à une seule base de données tout en répartissant ses données sur plusieurs machines, appelées shards. Chaque shard contient seulement un sous-ensemble des lignes, mais ensemble ils représentent l'intégralité du jeu de données.
Un modèle mental utile distingue structure logique et placement physique.
Du point de vue de l'application, on souhaite exécuter des requêtes comme s'il n'y avait qu'une table. En coulisses, le système doit décider vers quel(s) shard(s) diriger la requête.
Le sharding diffère de la réplication. La réplication crée des copies des mêmes données sur plusieurs nœuds, principalement pour la haute disponibilité et le scaling des lectures. Le sharding divise les données : chaque nœud tient des enregistrements différents.
C'est aussi différent du scale vertical, où vous conservez une seule base et la migrez sur une machine plus puissante (plus de CPU/RAM/disques). Le scale vertical peut être plus simple, mais a des limites pratiques et coûte vite cher.
Le sharding augmente la capacité, mais n'améliore pas automatiquement tous les aspects de performance :
Le sharding doit donc être compris comme un moyen de scaler le stockage et le débit — pas une mise à niveau gratuite de tous les comportements de la base.
Le sharding est rarement le premier choix. Les équipes y recourent généralement après qu'un système réussi ait atteint des limites physiques — ou quand la douleur opérationnelle devient fréquente. La motivation est moins « on veut sharder » que « il faut continuer à croître sans qu'une base unique soit un point de défaillance et de coût ».
Un nœud unique peut manquer de capacité de plusieurs façons :
Quand ces symptômes réapparaissent, le problème n'est souvent pas une requête isolée mais qu'une machine porte trop de responsabilité.
Le sharding répartit données et trafic sur plusieurs nœuds pour que la capacité augmente en ajoutant des machines plutôt qu'en améliorant verticalement une seule. Bien fait, il peut aussi isoler les workloads (pour qu'un pic d'un locataire n'empêche pas les autres) et maîtriser les coûts en évitant des instances monolithiques très onéreuses.
Des motifs récurrents : latences p95/p99 qui montent aux pics, lag de réplication plus long, sauvegardes/restaurations dépassant la fenêtre acceptable, et des petits changements de schéma devenant des événements majeurs.
Avant de s'engager, on épuise généralement les options plus simples : indexation et optimisation des requêtes, cache, réplicas en lecture, partitionnement de tables sur une seule instance, archivage des données anciennes, et upgrades matériels. Le sharding résout la montée en charge, mais ajoute coordination, complexité opérationnelle et nouveaux modes de panne — le seuil d'acceptation doit donc être élevé.
Une base shardée n'est pas une seule chose — c'est un petit système de pièces coopérantes. Le sharding paraît « difficile à raisonner » parce que la correction et la performance dépendent de l'interaction de ces pièces, pas seulement du moteur de base.
Un shard est un sous-ensemble des données, généralement stocké sur son propre serveur ou cluster. Chaque shard a typiquement :
Pour l'application, une configuration shardée tente souvent de ressembler à une base logique unique. Mais une requête qui serait « un seul lookup d'index » sur une base monoposte peut devenir « trouver le bon shard, puis faire le lookup ».
Un routeur (parfois appelé coordonnateur, query router ou proxy) est le chef d'orchestre. Il répond à la question pratique : pour cette requête, quel shard doit la traiter ?
Deux patterns courants :
Les routeurs réduisent la complexité dans l'app, mais peuvent devenir un goulot d'étranglement ou un nouveau point de panne s'ils ne sont pas conçus avec soin.
Le sharding s'appuie sur des métadonnées — une source de vérité décrivant :
Ces informations vivent souvent dans un service de config (ou un petit « plan de contrôle »). Si les métadonnées sont périmées ou incohérentes, les routeurs peuvent envoyer du trafic au mauvais endroit — même si tous les shards sont sains.
Le sharding dépend aussi de processus en arrière-plan qui maintiennent le système :
Ces tâches sont faciles à ignorer tôt, mais elles provoquent beaucoup de surprises en production — car elles changent la topologie pendant que le service répond au trafic.
La clé de shard est le champ (ou la combinaison de champs) que votre système utilise pour déterminer quel shard stocke une ligne/document. Ce choix unique détermine silencieusement la performance, le coût, et même quelles fonctionnalités seront faciles plus tard — car il contrôle si les requêtes peuvent être routées vers un seul shard ou doivent se fan-out.
Une bonne clé a tendance à avoir :
user_id plutôt que country).Exemple courant : sharder par tenant_id dans une app multi-tenant : la plupart des lectures/écritures d'un locataire restent sur un même shard, et les locataires sont assez nombreux pour répartir la charge.
Certaines clés garantissent presque la douleur :
Même si une clé basse cardinalité semble pratique pour filtrer, elle transforme souvent des requêtes routables en scatter-gather parce que les lignes correspondantes vivent partout.
La meilleure clé pour équilibrer la charge n'est pas toujours la meilleure pour les requêtes produit.
user_id) et certaines requêtes globales (reporting admin) deviennent plus lentes ou nécessitent des pipelines séparés.region) peut créer des hotspots et une capacité inégale.La majorité des équipes optimisent la clé pour les opérations fréquentes et sensibles à la latence — et traitent le reste avec des index, de la dénormalisation, des réplicas ou des tables analytiques dédiées.
Il n'y a pas une seule « meilleure » façon de shard-er. La stratégie choisie façonne la facilité de routage, l'uniformité de la répartition des données, et les types d'accès qui seront pénalisés.
Avec le range sharding, chaque shard possède une tranche contiguë d'un espace de clés — par exemple :
Le routage est simple : regardez la clé, choisissez le shard.
Le défaut : les hotspots. Si les nouveaux utilisateurs reçoivent des IDs croissants, le shard « dernier » devient le goulot d'écriture. Le range sharding est aussi sensible à la croissance inégale. L'avantage : les requêtes de type intervalle (« toutes les commandes du 1er au 31 octobre ») peuvent être efficaces car les données sont physiquement groupées.
Le hash sharding applique une fonction de hachage sur la clé de shard et utilise le résultat pour choisir un shard. Cela répartit généralement les données plus uniformément et évite le problème du shard « le plus récent ».
Compromis : les requêtes par intervalle deviennent coûteuses. Une requête « customers avec ID entre X et Y » ne se limite plus à quelques shards ; elle peut toucher beaucoup d'entre eux.
Détail pratique souvent sous-estimé : le hachage cohérent. Plutôt que de mapper directement sur le nombre de shards (ce qui remapperait tout en ajoutant un shard), beaucoup de systèmes utilisent un anneau de hachage avec des « nœuds virtuels » pour que l'ajout de capacité ne déplace qu'une portion des clés.
Le directory sharding stocke une correspondance explicite (table/service) clé → emplacement du shard. C'est la plus flexible : vous pouvez placer des locataires sur des shards dédiés, déplacer un client sans tout remapper, et supporter des tailles de shards inégales.
Le revers : une dépendance supplémentaire. Si le répertoire est lent, périmé ou indisponible, le routage souffre — même si les shards sont sains.
Les systèmes réels combinent souvent des approches. Une clé composite (ex. tenant_id + user_id) garde les locataires isolés tout en répartissant la charge à l'intérieur d'un locataire. Le sub-sharding fait de même : routez d'abord par locataire, puis hachez à l'intérieur du groupe pour éviter qu'un « gros locataire » n'occupe un seul shard.
Une base shardée a deux chemins de requête très différents. Comprendre lequel s'applique explique la plupart des surprises de performance — et pourquoi le sharding peut sembler imprévisible.
Le résultat idéal est de router une requête vers exactement un shard. Si la requête contient la clé de shard (ou quelque chose que le routeur peut mapper), le système l'envoie directement au bon shard.
C'est pourquoi les équipes cherchent à rendre les lectures courantes « shard-key aware ». Un seul shard implique moins d'aller-retours réseau, une exécution plus simple, moins de verrous et beaucoup moins de coordination. La latence dépend surtout du travail de la base, pas du cluster qui discute.
Quand une requête ne peut être routée avec précision (ex. filtre sur un champ non-clé), le système peut la diffuser à plusieurs ou tous les shards. Chaque shard exécute la requête localement, puis le routeur/coordonnateur fusionne les résultats — tri, déduplication, application de LIMIT, agrégats partiels.
Ce fan-out amplifie la latence tail : même si 9 shards répondent vite, un shard lent peut retenir la requête entière. Cela multiplie aussi la charge : une requête utilisateur devient N requêtes shard.
Les joins entre shards sont coûteux car des données qui se trouveraient « à l'intérieur » d'une base unique doivent maintenant circuler entre shards (ou vers un coordonnateur). Même des agrégations simples (COUNT, SUM, GROUP BY) peuvent nécessiter un plan en deux phases : calculer des résultats partiels sur chaque shard, puis les fusionner.
La plupart des systèmes utilisent par défaut des index locaux : chaque shard n'indexe que ses propres données. Ils sont peu coûteux à maintenir, mais n'aident pas le routage — les requêtes peuvent toujours scatter.
Des index globaux peuvent permettre le routage ciblé sur des champs non-clés, mais ils ajoutent un surcoût d'écriture, de la coordination et leurs propres problèmes de scalabilité et de cohérence.
C'est sur les écritures que le sharding cesse d'être « juste du scale » et commence à changer la conception des fonctionnalités. Une écriture qui touche un shard peut être rapide ; une écriture qui en touche plusieurs devient lente, sujette aux pannes et difficile à garantir correcte.
Si chaque requête peut être routée vers un seul shard (via la clé de shard), la base utilise sa machinerie transactionnelle normale. On obtient atomicité et isolation dans ce shard, et la plupart des problèmes opérationnels ressemblent à ceux d'une base monoposte — multipliée par N.
Quand une action logique doit mettre à jour plusieurs shards (ex. transfert d'argent, déplacement d'une commande), on entre dans le domaine des transactions distribuées.
Les transactions distribuées sont difficiles car elles requièrent une coordination entre machines qui peuvent être lentes, partitionnées ou redémarrées. Les protocoles de type two-phase commit ajoutent des allers-retours, peuvent se bloquer sur des timeouts et rendent les échecs ambigus : le shard B a-t-il appliqué le changement avant que le coordinateur ne meure ? Si le client réessaie, double-applique-t-on l'écriture ? Si on n'essaie pas, perd-on l'opération ?
Quelques tactiques réduisent la fréquence des transactions multi-shards :
Dans les systèmes shardés, les retries sont inévitables. Rendez les écritures idempotentes en utilisant des IDs d'opération stables (ex. clé d'idempotence) et en stockant des marqueurs « déjà appliqué ». Ainsi, si un timeout survient et que le client réessaie, la seconde tentative devient un no-op au lieu d'une double facturation ou d'un doublon.
Le sharding répartit les données, mais n'enlève pas le besoin de redondance. La réplication maintient un shard disponible quand un nœud meurt — et rend plus difficile la réponse à « que reflète la vérité maintenant ? ».
La plupart des systèmes répliquent à l'intérieur de chaque shard : un primaire accepte les écritures, un ou plusieurs réplicas copient ces changements. Si le primaire échoue, on promeut un réplique. Les réplicas peuvent aussi servir des lectures.
Le compromis est temporel : un réplica peut être en retard de quelques millisecondes — voire secondes. Cet écart est normal, mais il compte quand l'utilisateur attend de voir immédiatement sa mise à jour.
Dans les architectures shardées, on obtient souvent une cohérence forte au sein d'un shard et des garanties plus faibles entre shards, en particulier pour les opérations multi-shards.
Avec le sharding, « source unique de vérité » signifie généralement : pour chaque morceau de données, il existe un lieu d'écriture autoritaire (souvent le leader du shard). Mais globalement, il n'y a pas de machine capable de confirmer instantanément l'état de tout. On a plusieurs vérités locales à synchroniser via la réplication.
Les contraintes globales sont difficiles lorsque les données à vérifier résident sur différents shards :
Ces choix ne sont pas de simples détails d'implémentation — ils définissent ce que « correct » signifie pour votre produit.
Le rééquilibrage maintient la viabilité d'une base shardée à mesure que la réalité change : croissance inégale, dérive du bon équilibrage, ajout de nœuds, retraite de matériel. N'importe lequel de ces événements peut transformer un shard parfait en nouveau goulot.
Contrairement à une base unique, le sharding intègre la localisation des données dans la logique de routage. Déplacer des données ne copie pas que des octets — on change aussi où les requêtes doivent aller. Le rééquilibrage concerne donc autant les métadonnées et les clients que le stockage.
Le flux en ligne typique vise à éviter une fenêtre « stop the world » :
Un changement de shard map casse si les clients cachent leurs décisions de routage. Les bons systèmes traitent les métadonnées de routage comme de la configuration : les versionner, les rafraîchir fréquemment, et définir explicitement le comportement lorsqu'un client adresse une clé déplacée (redirect, retry, ou proxy).
Le rééquilibrage provoque souvent des baisses temporaires de perf (écritures additionnelles, churn de cache, charge de copie en arrière-plan). Les migrations partielles sont courantes — certaines plages migrent avant d'autres — donc prévoyez une observabilité claire et un plan de rollback avant le cutover.
Le sharding suppose que la charge va se répartir. La surprise est qu'un cluster peut paraître « équilibré » en nombre de lignes tout en se comportant de façon très inégale en production.
Un hotspot survient quand une petite portion de l'espace de clés concentre la majorité du trafic — compte célèbre, produit viral, un locataire qui lance un job, ou une clé temporelle où « aujourd'hui » attire tout. Si ces clés mappent à un seul shard, ce shard devient le goulot même si les autres sont au repos.
Le « skew » n'est pas unique :
Ils ne concordent pas forcément : un shard moins volumineux peut être le plus chaud s'il possède les clés les plus demandées.
Commencez par des dashboards par shard :
Si la latence d'un shard monte avec son QPS pendant que les autres restent stables, vous avez probablement un hotspot.
Les remèdes échangent simplicité contre équilibre :
Le sharding ajoute non seulement des serveurs, mais aussi des façons supplémentaires de casser des choses, et des lieux supplémentaires à inspecter. Beaucoup d'incidents ne sont pas « la base est down » mais « un shard est down » ou « le système ne sait plus où résident les données ».
Sur une base monoposte, on suit un seul log et des métriques. Dans un système shardé, il faut l'observabilité qui suit une requête à travers les shards.
Les échecs liés au sharding apparaissent souvent comme des bugs de correction :
« Restaurer la base » devient « restaurer plusieurs pièces dans le bon ordre ». Il peut être nécessaire de restaurer d'abord les métadonnées, puis chaque shard, et vérifier que les frontières et règles de routage correspondent au point de restauration. Les plans DR doivent inclure des répétitions pour prouver qu'on peut réassembler un cluster cohérent, pas seulement récupérer des machines individuelles.
Le sharding est souvent présenté comme l'interrupteur de montée en charge, mais c'est aussi une augmentation permanente de la complexité. Si vous pouvez atteindre vos objectifs de perf et de fiabilité sans répartir les données, vous aurez généralement une architecture plus simple, un débogage plus facile et moins de cas limites opérationnels.
Avant de shard-er, essayez :
Une manière pratique de réduire les risques est de prototyper le plumbing (bornes de routage, idempotence, workflows de migration, observabilité) avant d'engager la prod.
Par exemple, avec Koder.ai vous pouvez rapidement déployer un petit service réaliste depuis un chat — souvent une UI d'administration React plus un backend Go et PostgreSQL — et expérimenter des APIs conscience de la clé de shard, des clés d'idempotence et des comportements de cutover dans un bac à sable. Grâce au mode planning, aux snapshots/rollback et à l'export du code source, on peut itérer sur les décisions de sharding (routage, forme des métadonnées) puis reprendre le code et les runbooks dans la stack principale.
Le sharding convient mieux quand votre dataset ou votre débit d'écriture dépasse clairement les limites d'un nœud et que vos patrons de requêtes peuvent majoritairement être routés par une clé de shard (peu de joins cross-shard, peu de scatter-gather).
Il est inadapté quand le produit nécessite beaucoup de requêtes ad hoc, des transactions multi-entités fréquentes, des contraintes d'unicité globale, ou quand l'équipe ne peut pas assumer la charge opérationnelle (resharding, rééquilibrage, gestion d'incidents).
Demandez-vous :
Même si vous retardez le sharding, planifiez une voie de migration : choisissez des identifiants qui ne bloqueront pas une clé de shard future, évitez d'encapsuler des hypothèses monocœur, et répétez comment vous déplaceriez les données avec un downtime minimal. Le meilleur moment pour préparer le resharding est avant d'en avoir besoin.
Le sharding (partitionnement horizontal) répartit un seul jeu de données logique sur plusieurs machines (« shards »), chaque shard stockant des enregistrements différents.
La réplication, en revanche, conserve des copies des mêmes données sur plusieurs nœuds — principalement pour la disponibilité et la montée en charge en lecture.
Le scale-up (montée en charge verticale) consiste à améliorer un seul serveur de base de données (plus de CPU/RAM/disque). C'est plus simple opérationnellement, mais on finit par atteindre des limites physiques ou des coûts très élevés.
Le sharding permet de scaler horizontalement en ajoutant des machines, mais il introduit du routage, du rééquilibrage et des défis de cohérence inter-shards.
Les équipes shardent quand un nœud unique devient un goulot d'étranglement récurrent, par exemple :
Le sharding répartit données et trafic pour que la capacité croisse en ajoutant des nœuds.
Un système shardé typique comprend :
La performance et la correction dépendent de la cohérence entre ces composants.
La clé de shard est le ou les champs utilisés pour décider où vit une ligne. Elle détermine en grande partie si une requête touche un seul shard (rapide) ou plusieurs (lent).
De bonnes clés présentent souvent une haute cardinalité, une distribution homogène et sont alignées sur vos patrons d'accès courants (par ex. tenant_id ou user_id).
Les « mauvaises » clés de shard courantes incluent :
Elles provoquent souvent des hotspots ou transforment des requêtes simples en scatter-gather.
Trois stratégies répandues :
Si la requête inclut la clé de shard (ou quelque chose mappable), le routeur peut l'envoyer à un seul shard — le chemin rapide.
Sinon, le système peut fan-out la requête à de nombreux shards (scatter-gather). Chacun exécute la requête localement, puis un coordonnateur fusionne les résultats. Un shard lent peut bloquer l'ensemble et multiplier la charge par N.
Les écritures qui touchent un seul shard utilisent les transactions locales et restent simples.
Dès qu'une action logique doit modifier plusieurs shards (transfert d'argent, déplacement d'une commande, mise à jour d'un agrégat ailleurs), on entre dans les transactions distribuées. Celles-ci nécessitent une coordination (type two-phase commit), augmentent la latence et rendent les échecs ambigus.
Atténuations pratiques :
La réplication reste nécessaire au sein de chaque shard : un primaire accepte les écritures, des réplicas copient les changements. Si le primaire tombe, un réplique est promue.
Le compromis est la latence de réplique : une lecture sur un réplica peut être légèrement en retard. En pratique, on a souvent une cohérence forte au sein d'un shard mais des garanties plus faibles entre shards.
Les contraintes globales sont difficiles :
Le rééquilibrage vise à garder le système utilisable à mesure que la réalité change (croissance inégale, skew, ajout/retrait de nœuds). C'est difficile car déplacer des données change aussi où les requêtes doivent aller.
Le pattern de migration en ligne courant : copier → écriture doublée (overlap) → cutover → nettoyage.
Les cartes de shard (shard maps) doivent être versionnées et rafraîchies : si les clients cachent le routage, un changement peut casser l'accès. Préparez des plans de rollback et surveillez les impacts (charge additionnelle, churn de cache).
Le hotspot survient quand une petite portion de l'espace de clés concentre la majorité du trafic (compte célèbre, produit populaire, clé temporelle où « aujourd'hui » attire tout). Le skew peut être :
Détection : tableaux de bord par shard (p95, QPS, stockage). Atténuations : choisir une clé qui répartit le trafic, bucketing/salting, cache, quotas/rate limits, ou scinder les shards chauds.
Le sharding ajoute des modes de panne supplémentaires : un shard indisponible provoque des dégradations partielles, un routeur mal configuré peut mal router les requêtes, des métadonnées obsolètes créent des incohérences, des problèmes réseau partiels provoquent des timeouts amplifiés par les retries.
Le débogage exige d'autres outils : IDs de corrélation propagés, tracing distribué, et métriques découpées par shard (latence, profondeur de file, erreurs). Les incidents de correction des données incluent duplications, lignes manquantes après migrations, et écritures en split-brain.
Les sauvegardes/restaurations deviennent la remise en place coordonnée de plusieurs pièces (métadonnées d'abord, puis chaque shard) ; entraînez-vous à ces opérations.
Avant de shard-er, essayez d'abord des solutions qui conservent une base logique unique :
Le sharding convient mieux quand vous avez dépassé les limites d'un nœud ET que la majorité des requêtes critiques peuvent être routées par une clé de shard (peu de joins/scatter-gather). Planifiez une voie de migration en amont et testez vos workflows (idempotence, routage, cutover).