Avancé7 min de lecture

Du papier Dynamo à DynamoDB

Le papier de 2007 « Dynamo: Amazon's Highly Available Key-value Store » et le DynamoDB que tu appelles aujourd'hui partagent un nom et un objectif — des performances prévisibles à n'importe quelle échelle — mais ce ne sont pas le même système. Le papier décrivait un magasin interne à cohérence à terme, que tu exploitais toi-même. DynamoDB est un service managé qui a gardé les leçons et jeté la plupart de la machinerie.

DynamoDB repose-t-il sur le papier Dynamo ?

En partie. DynamoDB tire son nom et ses objectifs fondamentaux — des performances prévisibles et une haute disponibilité à grande échelle — du papier Amazon Dynamo de 2007, et il a gardé l'idée du hachage de la clé de partition presque mot pour mot. Mais c'est un système différent et managé : les vector clocks, l'appartenance par gossip et les quorums de lecture/écriture réglables du papier ont disparu, remplacés par des internes appartenant à AWS.

  • Le papier résolvait la disponibilité, pas l'ergonomie. Son boulot était de ne jamais rejeter une écriture pendant un pic de trafic de fêtes, même au prix de renvoyer une lecture périmée.
  • DynamoDB a gardé la forme, remplacé les internes. Partitionné par un hash de la clé, répliqué à travers les AZ, scalé horizontalement — mais les entrailles de résolution de conflits (vector clocks, gossip, read-repair) ont disparu.
  • Tu ne règles plus les boutons. N, R et W du papier sont devenus un seul choix : ConsistentRead true ou false. AWS possède le reste.
  • Le modèle mental paie toujours. Connaître la lignée explique pourquoi un Scan est coûteux et pourquoi une lecture de GSI peut être en retard — les deux découlent du design d'origine.

Ce que le papier résolvait réellement

Le panier d'achat d'Amazon ne pouvait pas tomber. Une base de données relationnelle qui refusait les écritures sous charge — ou bloquait sur une réplique défaillante — était inacceptable. Le papier Dynamo de 2007 a choisi la disponibilité plutôt que la cohérence : toujours accepter l'écriture, réconcilier les désaccords plus tard. Ce compromis est la racine de tout ce qui suit.

Pour faire ça sans master unique, Dynamo devait répondre à deux questions par lui-même : où vit une clé, et combien de copies doivent s'accorder avant qu'une lecture ou une écriture ne compte ?

Hachage cohérent : où vit une clé

Le papier plaçait chaque nœud sur un anneau de hachage. La position d'une clé est le hash de sa clé ; elle est possédée par le nœud suivant dans le sens horaire, et répliquée vers les N-1 nœuds suivants. Ajouter ou retirer un nœud ne remanie que les clés de ses voisins — pas tout le jeu de données. C'est le hachage cohérent, et c'est l'unique idée que DynamoDB a gardée presque mot pour mot.

DynamoDB hache toujours ta clé de partition pour décider quelle partition physique stocke l'item. Choisis une clé de partition à faible cardinalité — disons STATUS avec deux valeurs — et chaque item avec la même valeur atterrit dans la même partition. C'est le piège de la partition chaude, et c'est une conséquence directe de l'anneau : le hash envoie les clés identiques vers des foyers identiques.

Quorum : combien de copies doivent s'accorder

Le second bouton du papier était un quorum. Avec N répliques, une écriture réussit une fois que W d'entre elles acquittent, et une lecture consulte R d'entre elles. Fixe R + W > N et toute lecture chevauche au moins un nœud détenant la plus récente écriture — cohérence forte. Fixe-les plus bas et tu échanges la fraîcheur contre de la vitesse et de la disponibilité.

Dynamo exécutait des quorums « sloppy » : si un nœud cible était en panne, l'écriture allait à un remplaçant et était rendue plus tard (hinted handoff). Les versions conflictuelles étaient étiquetées avec des vector clocks et réconciliées par l'application à la lecture.

Ce que DynamoDB a gardé contre ce qu'il a changé

DynamoDB a hérité des objectifs et du partitionnement, puis a supprimé les parties qui rendaient l'original difficile à exploiter.

PréoccupationPapier Dynamo 2007DynamoDB aujourd'hui
Placement de cléAnneau de hachage cohérentHash de la clé de partition → partition managée
RéplicationN nœuds, tu choisis3 copies à travers les AZ, fixé par AWS
Boutons de cohérenceRéglage de quorum R, WUn seul flag : ConsistentRead
Résolution de conflitsVector clocks, fusion côté appli à la lectureLast-writer-wins ; tu optes pour les écritures conditionnelles
AppartenanceProtocole de gossip entre pairsEntièrement managé ; invisible pour toi
Opérations multi-clésAucune — pur clé-valeurQuery, GSI, transactions empilés par-dessus

L'API du papier était deux appels : get(key) et put(key, value). DynamoDB a ajouté une clé de tri, des index et des requêtes par-dessus le même cœur clé-valeur — c'est pourquoi un Query est bon marché (une partition) et un Scan ne l'est pas (il parcourt chaque partition que l'anneau ait jamais créée).

Comment une écriture voyage, hier et aujourd'hui

Le flux ci-dessous oppose l'écriture par quorum du papier à celle, managée, de DynamoDB. La forme rime ; la responsabilité s'est déplacée de ton code vers AWS.

Papier : tu réglais N,R,WDynamoDB : 3 copies AZ fixesput(key, value)Hacher la clé sur l'anneauÉcrire vers N répliquesW acks reçus ?Réconcilier via vector clocks à lalectureLast-writer-wins, quorum caché

Dans le papier, tu possédais le calcul de quorum et la fusion ; dans DynamoDB, toute cette moitié inférieure est managée, et tu ne choisis que ConsistentRead par requête.

Là où la lignée fuit dans ton code

La cohérence à terme par défaut est le papier qui transparaît. Un global secondary index est répliqué de façon asynchrone, donc un item fraîchement écrit peut manquer de l'index un instant — le même marché « réconcilier plus tard », juste à la couche d'index. Vois GSI vs LSI pour comprendre quand ce retard importe.

Tu rachètes la cohérence forte de deux façons. Utilise ConsistentRead: true sur une lecture de table de base (elle route vers la copie leader), ou protège une écriture avec une ConditionExpression pour qu'elle n'atterrisse que si l'état actuel de l'item correspond. Esquisse-en une dans le constructeur d'expressions DynamoDB — par exemple attribute_not_exists(PK) pour faire d'un PutItem une opération d'insertion seulement, le substitut moderne de la détection de conflits du papier.

La seule chose à retenir

Le papier optimisait pour ne jamais dire non à une écriture. DynamoDB a hérité de ce biais, c'est pourquoi ses défauts favorisent la disponibilité et pourquoi les lectures fortes coûtent plus. Modélise tes clés pour des Query mono-partition, comme dans le single-table design, et n'attrape un Scan que quand tu le dois vraiment — l'anneau rend un parcours de table complète aussi coûteux qu'il en a l'air.

Essaie DynoTable pour inspecter tes partitions, lancer des lectures cohérentes à la demande, et regarder un GSI rattraper son retard contre tes propres tables.

Mis à jour