Le jour où la ville redécoupe ses arrondissements
Une ville qui grossit finit par se découper. Trois arrondissements, chacun sa mairie, chacun ses registres. Chaque habitant sait où aller, chaque agent sait qui il sert. Le système tient.
Puis la population double et le conseil municipal vote un quatrième arrondissement. Sur la carte, c'est un trait. Sur le terrain, c'est trois dossiers sur quatre qui changent de mairie, des cartons dans des camionnettes, et six mois de guichets qui répondent « ce n'est plus nous ».
Une base de données partitionnée vit exactement ça le jour où on ajoute une machine. Le découpage initial se décide en une réunion. Le redécoupage, lui, se paie en semaines de migration et en incidents.
Découper une base est un problème d'une demi-journée. Redécouper une base déjà découpée est un problème de plusieurs semaines. Le hachage cohérent existe pour transformer le second en une variante du premier.
Le billet De zéro à un million d'utilisateurs plaçait le partitionnement en neuvième et dernière étape, celle qu'on repousse le plus longtemps possible. Voici ce qu'il y a dedans.
Grandir vers le haut ou vers le côté
Un quartier saturé a deux issues. Construire plus haut sur les parcelles existantes, ou ouvrir un nouveau quartier. La première est plus rapide, la seconde n'a pas de plafond.
Côté machines, la mise à l'échelle verticale consiste à remplacer le serveur par un plus gros. Elle ne demande aucune ligne de code, ce qui explique sa popularité. Elle a trois défauts : il existe une plus grosse machine jusqu'au jour où il n'y en a plus, le prix grimpe bien plus vite que la capacité, et cette machine reste un point de défaillance unique, sujet traité dans le billet Haute disponibilité.
La mise à l'échelle horizontale ajoute des machines au lieu d'en changer. La couche applicative s'y prête sans effort quand elle est sans état : on double le nombre d'instances derrière le répartiteur et c'est réglé. La couche de données résiste, parce qu'une donnée a une place.
Le sharding est la mise en œuvre de l'horizontale sur le stockage : la même table, découpée en tranches de lignes, chaque tranche sur sa machine, avec sa propre mémoire, son propre disque et ses propres index.
Reste à savoir quand franchir le pas. Le déclencheur n'est presque jamais le disque, c'est la mémoire. Un exemple chiffré, avec une plateforme de 500 millions de fiches utilisateur :
500 000 000 fiches
x 2 Ko par fiche = 1 000 000 000 Ko = 1 To de données
+ index secondaires, environ 20 % = 200 Go
--------------------------
total données + index = 1,2 To
RAM de la machine = 256 Go
Tant que les accès restent concentrés sur une petite fraction des fiches, la mémoire suffit. Le jour où le motif d'accès devient dispersé, le jeu de travail se rapproche du volume total, chaque lecture repart sur le disque et les temps de réponse deviennent erratiques. C'est le symptôme classique du seuil de partitionnement.
Le même To réparti sur 8 nœuds donne 125 Go de données et 25 Go d'index par machine, soit 150 Go dans 256 Go de RAM. Le problème disparaît, et sept autres apparaissent.
On ne partitionne pas parce que la base est grosse. On partitionne parce que le jeu de travail ne tient plus en mémoire sur une seule machine, ou parce que le débit d'écriture dépasse ce qu'un nœud absorbe.
La suite du billet déroule ces sept problèmes dans l'ordre : les deux façons de découper, la fonction de placement naïve et son échec, l'anneau qui la remplace, les nœuds virtuels qui corrigent l'anneau, le choix de la clé, ce que le découpage fait perdre, et la migration en production.
Partitionnement vertical et horizontal
Une mairie peut se diviser de deux façons. Séparer les services (état civil d'un côté, urbanisme de l'autre, dans deux bâtiments), ou séparer les habitants (les mêmes services, dupliqués dans quatre mairies d'arrondissement).
Le partitionnement vertical découpe par colonnes. Les colonnes lues à chaque requête restent ensemble, les colonnes volumineuses et rarement lues partent ailleurs.
-- Table de départ : tout dans la même ligne
CREATE TABLE utilisateur (
id BIGINT PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
mot_de_passe VARCHAR(255) NOT NULL,
nom_affiche VARCHAR(80),
bio TEXT,
preferences JSON,
derniere_visite TIMESTAMP
);
-- Découpe verticale : les colonnes chaudes d'un côté, les froides de l'autre
CREATE TABLE utilisateur_identite (
id BIGINT PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
mot_de_passe VARCHAR(255) NOT NULL
);
CREATE TABLE utilisateur_profil (
id BIGINT PRIMARY KEY,
nom_affiche VARCHAR(80),
bio TEXT,
preferences JSON
);
Le gain est mécanique : la table d'authentification devient trois fois plus petite, donc trois fois plus de lignes par page mémoire, donc un index qui tient plus longtemps en RAM. Le coût aussi est mécanique : afficher une page de profil complète demande maintenant deux lectures au lieu d'une, et la jointure entre les deux moitiés traverse le réseau si elles vivent sur deux machines.
Le partitionnement horizontal découpe par lignes. La table garde ses colonnes, mais ses lignes sont réparties selon une fonction de placement appliquée à une colonne choisie, la clé de partition.
partition = hachage(utilisateur.id) mod 4
partition 0 -> nœud A
partition 1 -> nœud B
partition 2 -> nœud C
partition 3 -> nœud D
| Partitionnement vertical | Partitionnement horizontal | |
|---|---|---|
| Découpe | par colonnes | par lignes |
| Ce qui grandit | le nombre de tables | le nombre de machines |
| Décision structurante | quelles colonnes vont ensemble | la clé de partition |
| Plafond | le nombre de colonnes de la table | aucun plafond théorique |
| Impact sur le code | modéré, deux lectures au lieu d'une | fort, tout accès doit connaître la clé |
| Ce qu'on perd d'abord | la jointure entre les deux moitiés | la jointure entre deux partitions |
Une précision de vocabulaire, parce qu'elle génère beaucoup de malentendus en réunion. Le partitionnement horizontal existe aussi à l'intérieur d'une seule instance : PostgreSQL sait découper une table en partitions déclaratives qui restent sur le même serveur. Le sharding, c'est le partitionnement horizontal réparti sur plusieurs machines. Le premier réduit le coût des balayages, le second ajoute de la capacité.
Le partitionnement vertical repousse l'échéance. Seul le partitionnement horizontal réparti ajoute de la capacité, et c'est le seul qui change la forme du code applicatif.
Le hachage modulo, et pourquoi il ne tient pas
L'attribution la plus naturelle consiste à numéroter les arrondissements et à distribuer les habitants au prorata. Elle a la propriété d'être calculable par tout le monde, sans annuaire central. Et elle a le défaut de dépendre du nombre d'arrondissements.
En informatique, ça donne partition = hachage(clé) mod N. Trois nœuds, mod 3. On ajoute un nœud, mod 4. Voici le résultat, empreinte par empreinte, sur douze valeurs.
| Empreinte | mod 3 |
mod 4 |
La clé déménage |
|---|---|---|---|
| 0 | 0 | 0 | non |
| 1 | 1 | 1 | non |
| 2 | 2 | 2 | non |
| 3 | 0 | 3 | oui |
| 4 | 1 | 0 | oui |
| 5 | 2 | 1 | oui |
| 6 | 0 | 2 | oui |
| 7 | 1 | 3 | oui |
| 8 | 2 | 0 | oui |
| 9 | 0 | 1 | oui |
| 10 | 1 | 2 | oui |
| 11 | 2 | 3 | oui |
Neuf clés sur douze changent de nœud, soit 75 %. Ce n'est pas un tirage malheureux, c'est la règle générale :
une clé reste en place seulement si h mod N == h mod (N + 1)
ce qui arrive quand h mod (N x (N+1)) est inférieur à N
pour N = 3 : h mod 12 vaut 0, 1 ou 2 -> 3 cas sur 12
proportion qui reste = 3 / 12 = 1 / 4 = 1 / (N + 1) = 25 %
proportion déplacée = 1 - 1/4 = 75 %
La formule 1 / (N + 1) a une conséquence désagréable : plus le parc est grand, pire c'est. Passer de 10 nœuds à 11 laisse en place une clé sur onze.
proportion qui reste = 1 / 11 = 9,1 %
proportion déplacée = 10 / 11 = 90,9 %
500 000 000 clés x 90,9 % = 454 500 000 clés à déplacer
454 500 000 clés x 2 Ko par clé = 909 Go à transférer
909 000 Mo / 100 Mo par seconde = 9 090 secondes ≈ 2 h 32
Deux heures et demie de transfert réseau saturé, dans le meilleur des cas, avec des nœuds qui servent le trafic pendant ce temps. Mais le vrai problème n'est pas la durée : c'est que le nouveau placement n'est correct qu'une fois la totalité du déplacement terminée. Pendant la migration, mod 10 et mod 11 donnent deux réponses différentes pour la même clé, et aucun client ne sait laquelle croire.
Le hachage modulo attache la place d'une donnée au nombre de machines. Ajouter une machine ne rajoute pas de la capacité, ça réécrit la carte entière.
Le hachage cohérent
Le principe du redécoupage acceptable est connu des urbanistes : on ne renumérote pas la ville, on découpe un arrondissement existant en deux. Seuls les habitants de cet arrondissement changent de mairie, les autres ne remarquent rien.
Le hachage cohérent applique exactement ça. On projette l'espace des empreintes sur un anneau, en général de 0 à 2^32 - 1, et on referme le segment sur lui-même : après la valeur maximale, on revient à 0.
Les serveurs sont placés sur cet anneau en hachant leur nom ou leur adresse. Les clés sont placées sur le même anneau en hachant leur identifiant. La règle tient en une ligne : une clé appartient au premier serveur rencontré en tournant dans le sens des aiguilles d'une montre.
Voici un anneau réduit à 0..99 pour la lisibilité, avec trois serveurs en 12, 47 et 78, puis un quatrième ajouté en 60.
position 12"] --> S1["S1
position 47"] S1 --> S3["S3 ajouté
position 60"] S3 --> S2["S2
position 78"] S2 --> S0 K1["clé empreinte 5"] --> S0 K2["clé empreinte 30"] --> S1 K3["clé empreinte 55
quitte S2 pour S3"] --> S3 K4["clé empreinte 90
reboucle par 0"] --> S0 classDef serveur fill:#b5651d,stroke:#8a4d16,color:#f5f2ec; classDef nouveau fill:#a0413e,stroke:#8a4d16,color:#f5f2ec; classDef cle fill:#ede9e1,stroke:#8a4d16,color:#2c3338; class S0,S1,S2 serveur; class S3 nouveau; class K1,K2,K3,K4 cle;
La clé d'empreinte 90 dépasse la fin de l'anneau, reboucle par 0 et atterrit sur S0. C'est ce rebouclage qui fait que l'anneau n'a jamais de trou.
L'ajout de S3 en position 60 ne touche qu'une chose : les clés dont l'empreinte tombe entre 48 et 60. Elles appartenaient à S2, elles passent à S3. Les clés de S0 et de S1 ne bougent pas, et personne n'a besoin de les relire pour s'en assurer.
Le retrait fonctionne symétriquement. Si S1 disparaît, ses clés (empreintes 13 à 47) glissent au serveur suivant sur l'anneau. Aucune autre partition n'est concernée.
Le résultat général, avec des positions tirées uniformément : quand un nœud entre ou sort d'un anneau de n nœuds, la fraction de clés déplacées est d'environ 1 / n. Comparons avec le même parc que tout à l'heure.
| Fonction de placement | Passage de 10 à 11 nœuds | Clés déplacées sur 500 millions | Volume transféré |
|---|---|---|---|
hachage mod N |
10 / 11 des clés, soit 90,9 % | 454 500 000 | 909 Go |
| Anneau cohérent | 1 / 11 des clés, soit 9,1 % | 45 500 000 | 91 Go |
Un facteur dix sur le volume, et surtout un changement de nature : le déplacement est localisé. Une seule paire de nœuds travaille, le reste du parc sert le trafic normalement, et l'opération peut être interrompue puis reprise.
L'idée vient d'un papier de David Karger et de ses coauteurs au MIT, paru en 1997 et conçu à l'origine pour des caches web répartis. Elle est devenue la référence des magasins répartis avec le papier Dynamo d'Amazon, publié à SOSP en 2007, dont descendent directement Cassandra et Riak.
L'anneau ne réduit pas le travail de migration par magie. Il le rend local, donc incrémental, donc interruptible. C'est cette dernière propriété qui change la vie d'une équipe d'exploitation.
Les nœuds virtuels
Un anneau à trois serveurs a un défaut que le schéma précédent cachait poliment : les positions sont tirées au hasard, et le hasard ne répartit rien équitablement sur trois tirages.
Reprenons l'anneau 0..99 avec un tirage moins chanceux, S0 en 8, S1 en 15 et S2 en 70.
| Serveur | Arc possédé | Part de l'anneau |
|---|---|---|
| S0 | de 70 à 8, en passant par 0 | 38 % |
| S1 | de 8 à 15 | 7 % |
| S2 | de 15 à 70 | 55 % |
S2 encaisse huit fois plus de trafic que S1, avec le même matériel. Il tombera le premier, et sa disparition renverra tout son arc au serveur suivant, qui héritera alors de 93 % de l'anneau. Le déséquilibre se propage en cascade.
La parade consiste à cesser de placer un serveur en un point. Chaque serveur physique reçoit un ensemble de positions, calculées en hachant S0#0, S0#1, S0#2 et ainsi de suite. Ces points sont les nœuds virtuels, ou jetons.
Avec cent points par serveur au lieu d'un, chaque serveur possède cent petits arcs dispersés partout sur l'anneau au lieu d'un seul gros. La charge d'un serveur devient une somme de cent tirages indépendants, et la dispersion relative décroît en gros comme l'inverse de la racine du nombre de points. Cent fois plus de points, dix fois moins d'écart.
Le second bénéfice compte autant que le premier. Quand un serveur disparaît, ses cent arcs sont récupérés par une centaine de successeurs différents, répartis sur tout le parc. La charge orpheline se dilue au lieu de s'abattre sur un voisin. Le rééquilibrage qui suit mobilise également tout le parc, donc va beaucoup plus vite.
Le réglage a un prix. Chaque nœud virtuel occupe une entrée dans la table de routage que chaque membre du cluster garde en mémoire et propage à ses voisins, donc multiplier les jetons alourdit les métadonnées et les échanges d'appartenance. Cassandra expose ce nombre sous le nom num_tokens dans cassandra.yaml, et le bon réglage dépend de la taille du cluster.
Sans nœuds virtuels, le hachage cohérent règle le problème du redécoupage et en crée un autre : le déséquilibre de charge. Les deux mécanismes ne s'utilisent jamais l'un sans l'autre.
Choisir la clé de partition
Un conseil municipal qui découpe par rue obtient des arrondissements équilibrés. Un conseil qui découpe par nom de famille obtient une mairie qui ne désemplit pas et une autre qui ouvre le mardi matin.
La clé de partition est la décision la plus lourde de conséquences de tout le système, parce qu'elle est la plus coûteuse à changer. Elle se juge sur trois critères.
La cardinalité. Le nombre de valeurs distinctes fixe le nombre maximum de partitions possibles. Une clé booléenne donne deux partitions, définitivement. Une clé sur un pays donne au mieux deux cents partitions, ce qui suffit jusqu'à ce que ça ne suffise plus.
L'uniformité. Les valeurs doivent se répartir régulièrement. Un identifiant utilisateur haché satisfait ce critère. Une date ne le satisfait pas du tout, parce que toutes les écritures du jour visent la même valeur : la partition courante prend 100 % du débit d'écriture pendant que les autres dorment. C'est le point chaud, la panne la plus fréquente d'un système partitionné.
L'adéquation au motif de lecture. C'est le critère qu'on oublie, et celui qui coûte le plus cher. Si la requête dominante lit une conversation entière et que la clé est l'identifiant de l'auteur du message, chaque affichage interroge toutes les partitions et attend la plus lente. Les latences deviennent celles de la queue de distribution, pas celles de la moyenne.
| Clé retenue | Symptôme observé | Clé de remplacement |
|---|---|---|
| Un pays | 70 % des lignes sur une seule partition | hachage(id_utilisateur) |
| Une date ou un horodatage | toutes les écritures sur la partition du jour, les autres inertes | id_entité composé avec une tranche de temps |
| Un booléen ou un statut | deux partitions au total, quel que soit le parc | abandonner comme clé, en faire un index |
| Un identifiant auto-incrémenté | écritures séquentielles concentrées sur le dernier nœud | empreinte de l'identifiant plutôt que l'identifiant |
id_client en B2B |
un client pèse 40 % du volume et sature son nœud | id_client composé avec id_commande |
id_auteur alors qu'on lit par fil de discussion |
chaque lecture éveille toutes les partitions | id_conversation |
La clé composite est la réponse à deux problèmes différents. Elle borne la taille d'une partition quand une valeur unique grossit sans limite (un canal de discussion très actif, un gros client), et elle préserve la localité de lecture quand on l'associe à une clé de tri bien choisie. Le scénario B ci-dessous en donne l'exemple canonique.
Une clé de partition se choisit à partir de la requête qu'on fera le plus souvent, pas à partir de la structure de la table. C'est un exercice de motif d'accès, pas de modélisation.
Ce que le découpage fait perdre
Le jour où la ville passe à quatre mairies, quelque chose disparaît : plus personne ne peut répondre à « combien d'habitants au total » sans passer quatre appels et faire l'addition.
Une base partitionnée perd les mêmes garanties, et il vaut mieux les avoir listées avant de découper que pendant l'incident.
| Ce qu'on perd | Ce qui se passe | Contournement usuel |
|---|---|---|
| La jointure entre partitions | le moteur ne voit plus les deux tables ensemble | dénormaliser, ou joindre côté application |
| La transaction multi-partitions | plus d'atomicité garantie par le moteur | SAGA ou coordinateur, avec le prix associé |
| L'unicité globale d'une colonne | deux partitions acceptent le même e-mail | index d'unicité externe, ou clé dérivée de la clé de partition |
| Les identifiants auto-incrémentés | chaque partition repart à 1 et fabrique des collisions | identifiants tirés d'un générateur réparti |
| Les balayages et agrégats | un COUNT(*) interroge toutes les partitions |
compteurs maintenus à l'écriture, ou magasin analytique séparé |
| Le tri global | trier impose de tout rassembler | trier dans la partition, ou accepter un tri approché |
Les transactions qui traversent deux partitions relèvent d'un sujet à part entière, traité dans le billet Transactions distribuées. Retiens pour l'instant qu'elles reviennent à choisir entre un coordinateur qui bloque et une compensation qui laisse voir des états intermédiaires.
La perte des identifiants auto-incrémentés est moins spectaculaire mais tout aussi structurante. Il faut un générateur qui produise des identifiants uniques sans coordination par écriture, et de préférence croissants dans le temps pour rester utilisables comme clé de tri. Les trois familles de solutions sont détaillées dans l'étude de cas du raccourcisseur d'URL.
Enfin, chaque partition garde ses propres index, avec ses propres coûts d'écriture. Le sujet du billet suivant.
Partitionner revient à échanger des garanties fournies par le moteur contre de la capacité. Le contrat est acceptable, à condition d'avoir écrit noir sur blanc ce qu'on rend.
Rééquilibrer sans interruption
Une mairie ne ferme pas six mois pour transférer ses dossiers. Elle ouvre le nouveau guichet, duplique l'enregistrement pendant la transition, vérifie, puis redirige les administrés.
Le rééquilibrage d'une partition suit la même chorégraphie, en cinq temps.
La copie de fond se fait sous limitation de débit. Une migration qui sature le nœud source dégrade le service qu'elle était censée améliorer, et personne ne remerciera l'équipe pour la rapidité du transfert.
La double écriture est la phase délicate. Pendant sa durée, une écriture partie vers la source et perdue vers la cible crée une divergence silencieuse, qui ne se manifestera qu'après la bascule des lectures. D'où la vérification par échantillonnage avant de basculer, et la règle qui prime sur toutes les autres : la bascule reste réversible tant que la source n'est pas purgée.
Un détail d'architecture rend tout cela praticable. L'application ne doit jamais calculer elle-même l'adresse d'un nœud. Elle calcule une partition logique, et une couche de routage traduit cette partition en adresse physique. Déplacer des données devient alors la mise à jour d'une ligne dans une table de correspondance, et non un redéploiement applicatif.
Cette indirection ouvre une variante du hachage cohérent qui mérite d'être connue : le pré-découpage en partitions logiques fixes. On décide dès le premier jour d'un nombre de partitions largement surdimensionné, disons 1 024, et on les répartit sur les nœuds disponibles. Ajouter une machine ne recalcule jamais aucune empreinte, ça déplace des partitions entières. Redis Cluster applique ce principe avec 16 384 emplacements de hachage figés dans la spécification du protocole.
| Approche | Ce qui bouge à l'ajout d'un nœud | Contrainte |
|---|---|---|
hachage mod N |
la quasi-totalité des clés | inutilisable au-delà du prototype |
| Anneau cohérent avec nœuds virtuels | environ 1 / n des clés |
table d'appartenance à propager |
| Partitions logiques pré-découpées | des partitions entières, jamais des clés | le nombre de partitions est figé à vie |
Le rééquilibrage se conçoit le jour du découpage initial, pas le jour où on ajoute la onzième machine. Une couche de routage et un pré-découpage généreux coûtent une journée au départ et évitent un trimestre plus tard.
Scénario B : Discord et les milliards de messages
En janvier 2017, Discord a publié How Discord Stores Billions of Messages, un billet d'ingénierie qui raconte précisément le sujet traité ici.
Le point de départ est le seuil décrit plus haut. Les messages vivaient dans une unique collection MongoDB. Fin 2015, autour de cent millions de messages stockés, les données et leurs index ont cessé de tenir en mémoire, et les latences sont devenues imprévisibles. L'équipe a évalué plusieurs magasins et retenu Cassandra, pour sa mise à l'échelle linéaire par ajout de nœuds et l'absence de nœud maître à gérer.
La partie intéressante est le choix de la clé. La requête dominante d'un service de discussion est « donne-moi les derniers messages de ce canal ». Partitionner par identifiant de message aurait dispersé une conversation sur tout le cluster. Discord a donc pris l'identifiant de canal comme base de la clé de partition, pour qu'une lecture de conversation touche une seule partition.
Mais un identifiant de canal seul ne borne rien : un canal très actif produit des messages sans limite, et Cassandra recommande de garder les partitions sous une centaine de mégaoctets. L'équipe a donc composé la clé avec un compartiment temporel fixe, de dix jours, et utilisé l'identifiant de message comme clé de tri à l'intérieur de la partition. La clé de partition finale est le couple canal et fenêtre de temps, exactement la clé composite décrite dans la section précédente.
Le billet raconte aussi l'incident qui a suivi, et c'est là qu'il devient précieux. Des utilisateurs signalaient des canaux dont l'historique ne se chargeait plus. La cause : ces canaux avaient vu tous leurs messages supprimés, et Cassandra matérialise une suppression par un marqueur de suppression conservé un temps. Lire l'historique revenait à parcourir des millions de marqueurs pour ne rien renvoyer, jusqu'au délai d'attente. Le motif de lecture, encore lui, mais du côté de ce qui n'existe plus.
Six ans plus tard, How Discord Stores Trillions of Messages raconte la suite : passage à ScyllaDB, et le problème des partitions chaudes, ces canaux dont l'activité concentre le trafic sur quelques nœuds. Le même sujet, deux ordres de grandeur plus loin.
Ce que le cas Discord montre : la clé de partition se déduit de la requête dominante, et la composition avec une fenêtre temporelle est la façon standard de borner une partition qui grossirait sans limite.
Points clés
- Le hachage modulo lie la place d'une donnée au nombre de machines. En passant de N à N+1 nœuds, seule une clé sur N+1 reste en place, soit plus de 90 % de déplacements à partir de dix nœuds.
- Le hachage cohérent place serveurs et clés sur un même anneau et n'affecte qu'un arc à chaque changement de parc, ce qui ramène le déplacement à environ
1 / ndes clés, et le rend local et interruptible. - Les nœuds virtuels sont indissociables de l'anneau : ils corrigent le déséquilibre du tirage aléatoire et diluent la charge d'un nœud tombé sur tout le parc.
- La clé de partition se juge sur trois critères, cardinalité, uniformité et adéquation au motif de lecture, et se choisit à partir de la requête dominante. La clé composite borne les partitions qui grossiraient sans limite.
- Partitionner rend des garanties au moteur : jointures, transactions multi-partitions, unicité globale, agrégats. La liste se dresse avant le découpage, pas pendant l'incident.
Dans la série
Palier 3 : Tenir les registres. Domaine : Mise à l'échelle.
- Précédent : Haute disponibilité : redondance, réplication, bascule
- Suivant : L'indexation : ce qui se passe vraiment sous une requête
- Vue d'ensemble : System design : par où commencer
Pour aller plus loin
- Concevoir un magasin clé-valeur, l'étude de cas qui assemble l'anneau, les nœuds virtuels, la réplication et le quorum dans un système complet.
- De zéro à un million d'utilisateurs, étape par étape, pour replacer le partitionnement à sa place dans la trajectoire, en neuvième étape.
- SQL ou NoSQL : choisir son magasin de données, parce que le partitionnement natif ou non fait partie des critères de choix.
- How Discord Stores Billions of Messages et sa suite, How Discord Stores Trillions of Messages.
- Dynamo: Amazon's Highly Available Key-value Store, SOSP 2007, la source d'origine du hachage cohérent avec nœuds virtuels en production.
- Consistent hashing pour la formulation mathématique et le papier fondateur de 1997.