Intermédiaire8 min de lecture

Lectures DynamoDB : cohérence forte ou à terme

Tu mets à jour un item, tu le relis immédiatement, et tu obtiens l'ancienne valeur. L'écriture a réussi — un instant plus tard la même lecture renvoie la nouvelle valeur. Rien n'est cassé : tu as heurté la lecture à cohérence à terme par défaut de DynamoDB, et tu peux t'en désengager par requête.

C'est l'un des rares boutons de correction que DynamoDB te confie directement, et il a un vrai prix attaché. Le maîtriser, c'est savoir ce que chaque mode garantit, ce qu'il coûte, et là où les lectures fortes ne sont tout simplement pas disponibles.

Quelle est la différence entre les lectures strongly consistent et eventually consistent dans DynamoDB ?

Une lecture eventually consistent (le défaut) est servie par n'importe quel replica, donc elle peut brièvement renvoyer des données périmées juste après une écriture, mais coûte moitié moins. Une lecture strongly consistent, optée par requête avec ConsistentRead=true, est routée vers le leader de partition et reflète toujours chaque écriture commitée — à 2× la capacité de lecture.

  • Eventually consistent (le défaut) — peut brièvement renvoyer des données périmées juste après une écriture. Mode de lecture le moins cher.
  • Strongly consistent — reflète toujours chaque écriture commitée avant la lecture. Opt-in par requête avec ConsistentRead=true.
  • Les lectures strong coûtent 2× eventual. Une lecture strongly consistent consomme deux fois la capacité de lecture d'une lecture eventually consistent pour les mêmes données.
  • Pas partout. Tu as des lectures strong sur le table de base et sur un Local Secondary Index. Un Global Secondary Index est eventual-only — pas d'opt-in.
  • Default vers eventual. Atteins strong seulement quand tu lis tes propres données tout juste écrites et qu'être périmé d'un instant serait faux.

Le problème : une lecture qui ne voit pas la dernière écriture

Disons que tu gères des comptes utilisateurs. Un utilisateur change son email de notification, ton app écrit l'update, et l'écran de confirmation relit immédiatement le profile pour montrer la nouvelle adresse. Avec le mode de lecture par défaut, cette relecture peut atterrir sur un replica qui n'a pas encore reçu le changement — donc l'utilisateur voit son ancien email et assume que la save a échoué.

La fenêtre est petite (typiquement bien sous une seconde) et se ferme toute seule. Mais « généralement correct » ne suffit pas pour une confirmation read-after-write. C'est exactement le cas pour lequel la strong consistency existe.

Pourquoi la cohérence à terme arrive

DynamoDB stocke chaque partition sur trois storage nodes — un primary et deux replicas — à travers des Availability Zones séparées. Une écriture est acknowledged une fois qu'elle atterrit sur le primary et un replica ; elle se propage ensuite vers le troisième nœud de façon asynchrone.

Les lectures, pour étaler la charge, peuvent être servies par n'importe lequel des trois nœuds. Une lecture eventually consistent peut frapper un nœud qui n'a pas encore reçu ta écriture la plus récente — donc elle renvoie une valeur légèrement périmée. Une lecture strongly consistent est routée vers le leader de la partition, qui tient toujours les dernières données commitées, donc elle ne renvoie jamais de résultats périmés.

sync, acknowledgedasync, lag brefpeut frapper un nœud en retardÉcriture : nouvel emailNœud primaryReplica 1Replica 2Lecture strongly consistentLecture eventually consistent

Ce lag de réplication est toute la différence. Il explique aussi le coût 2× : les lectures strong ne peuvent pas être load-balancées à travers les replicas comme les lectures eventual, donc DynamoDB les prix à deux fois la capacité.

Le coût, rendu concret

Les lectures sont mesurées en Read Capacity Units (RCU), chacune couvrant jusqu'à 4 KB. Une RCU achète une lecture strongly consistent ou deux lectures eventually consistent d'un item de 4 KB. Donc basculer ConsistentRead=true sur un chemin de lecture hot double son coût de lecture — sur un endpoint high-traffic c'est une ligne que tu remarqueras.

Modélise la différence pour tes propres tailles d'item et taux de requête avec le calculateur de pricing DynamoDB avant de faire des lectures strong ton défaut — ça vaut rarement de payer deux fois partout.

Où les lectures strong sont (et ne sont pas) disponibles

Lecture contreStrongly consistent ?
Table de baseOui — opt-in avec ConsistentRead=true
Local Secondary Index (LSI)Oui — même opt-in que le table de base
Global Secondary Index (GSI)Non — eventual seulement, pas d'override

Un GSI maintient sa propre copie des données, répliquée depuis le table de base de façon asynchrone, donc il ne peut jamais offrir une lecture strong. Si un modèle d'accès a vraiment besoin de read-after-write et que tu prévoyais de le servir depuis un GSI, c'est un signal de le servir depuis le table de base ou un LSI à la place.

Pièges + étapes suivantes

  • Ne fais pas des lectures strong le défaut. La plupart des lectures tolèrent une fenêtre périmée sub-seconde ; payer 2× partout est de la dépense gaspillée.
  • N'attends pas de read-after-write d'un GSI. Il est eventual by design — vois pourquoi un GSI est en cohérence à terme.
  • Les transactions lisent strongly. TransactGetItems est toujours strongly consistent — vois transactions DynamoDB.
  • La cohérence interagit avec la capacité. Le multiplicateur 2× se relie directement à la planification de coût on-demand vs provisioned.

Envie d'explorer tes tables et indexes DynamoDB sans écrire d'appels API ? Télécharge DynoTable et inspecte tes données directement.

Comparaison RCU concrète

Deux lectures du même item de 6 KB sur le table de base :

ModeBlocs 4 KBRCU consomméesQuand l'utiliser
Strongly consistent2 (6 KB arrondit)2 RCUÉcrans de confirmation après ta propre écriture
Eventually consistent21 RCUDashboards, listes, analytics

À 1 000 telles lectures par seconde, le mode strong coûte environ deux fois la dépense de lecture on-demand du mode eventual — modélise le delta dans le calculateur de pricing avant de basculer un chemin hot vers ConsistentRead=true globalement.

Cohérence BatchGetItem

Chaque entrée de table dans BatchGetItem peut setter ConsistentRead indépendamment. Un dashboard qui charge un user profile (strong) et des settings liés (eventual) peut mixer les flags dans un seul appel batch — toujours sujet aux règles de disponibilité de lecture strong par table (pas de strong sur GSI).

Read-after-write dans le code applicatif

Pattern pour la confirmation d'update de profile :

  1. UpdateItem avec le nouvel email.
  2. GetItem immédiat avec ConsistentRead: true sur le table de base.

L'étape 2 coûte 2× la RCU d'une lecture eventual mais garantit que l'écran de confirmation matche l'écriture. Skip les lectures strong sur les agrégations de background qui tolèrent un lag sub-seconde.

Défauts DynoTable

Les lectures exploratoires dans DynoTable utilisent des queries du table de base eventually consistent sauf si tu optes pour des sémantiques plus fortes dans les settings avancés — matching la plupart des cas d'usage dashboard. Après avoir stagé une écriture, le refresh de l'éditeur d'item montre les valeurs commitées depuis la réponse réussie sans toggle de cohérence séparé pour le chemin courant.

Utilise le query builder pour émettre des lectures d'exemple avec ConsistentRead setté explicitement quand tu copies du code SDK dans des services qui ont besoin de garanties read-after-write.

Note Global Tables

Les Global Tables répliquent de façon asynchrone entre Regions. La strong consistency s'applique dans le replica d'une Region, pas globalement. Une écriture dans us-east-1 n'est pas instantanément strong-readable dans eu-west-1 — planifie l'UX cross-Region en conséquence. Vois global tables pour les attentes de lag de réplication.

Mis à jour