Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

DynamoDB : les erreurs que la plupart des équipes commettent avant même d'écrire une ligne de code

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

By Joseph AllamJul 20, 20268 min read
Joseph Allam

About Joseph Allam

Databases have been my craft for a long time — long before the cloud, and deep into it across AWS and GCP. I know what breaks, what costs too much, and what needs rethinking before it hurts. I also know how to bring AI into the work: into how databases are designed, operated, and accessed by the intelligent systems being built on top of them.

My personal page

Lors du Prime Day 2025, Amazon DynamoDB a atteint un pic de 151 millions de requêtes par seconde. C'est la base de données qui alimente certains des workloads les plus exigeants de la planète, et ce depuis près de vingt ans. La plupart des ingénieurs qui travaillent sur AWS en ont entendu parler. Beaucoup l'ont utilisée. Mais lors du DynamoDB Immersion Day que j'ai récemment animé avec l'équipe AWS, le même problème est apparu dans presque chaque session : des équipes qui avaient choisi DynamoDB pour les bonnes raisons rencontraient malgré tout des difficultés, parce qu'elles concevaient leurs schémas de la mauvaise manière.

C'est le sujet de cet article. Pas les bases de DynamoDB (on en trouve largement ailleurs), mais la démarche de conception qui distingue les équipes pour qui tout fonctionne de celles qui se retrouvent avec des coûts incontrôlés et des tables qui ne passent pas à l'échelle.

PerfectScale™ for Kubernetes

Ready to optimize?

Get your free Kubernetes savings analysis

DynamoDB est-il le bon choix ?

Avant de parler conception, soyons directs sur la question de l'adéquation. DynamoDB est un bon choix lorsque vous avez besoin d'une latence constante de quelques millisecondes à pratiquement n'importe quelle échelle, que vos patterns d'accès sont connus et prévisibles dès le départ, et que votre workload est intensif en lectures/écritures plutôt qu'analytiquement complexe. Bons exemples : API destinées aux utilisateurs, stockage de sessions, classements, paniers d'achat, ingestion IoT, event sourcing.

C'est un mauvais choix lorsque vous avez besoin de requêtes ad hoc sur de nombreuses dimensions, que vos patterns d'accès évoluent encore, ou que vous devez gérer des jointures relationnelles complexes. Si vous remplacez une base de données de reporting ou construisez un système dont les besoins en requêtes changeront de mois en mois, vous vous battrez contre DynamoDB en permanence.

La taille des items compte plus que la plupart des équipes ne l'imaginent

Avant de vous engager sur DynamoDB, modélisez le coût correctement. DynamoDB facture la capacité d'écriture par incréments de 1 Ko, arrondis à l'unité supérieure. En mode à la demande, un item de 20 Ko consomme 20 Write Request Units (WRU) ; en mode provisionné, la même écriture consomme 20 Write Capacity Units (WCU). Les lectures fonctionnent de manière similaire, facturées par incréments de 4 Ko par Read Capacity Unit (RCU) : la taille des items pèse donc sur les deux volets de votre coût de capacité.

Cela paraît simple, mais la taille des items est l'une des variables les plus souvent négligées lorsque les équipes modélisent les coûts de DynamoDB. Nous voyons régulièrement des clients migrer depuis des bases relationnelles comme PostgreSQL, où la facturation à l'octet des écritures n'existe pas, et leurs estimations de coûts initiales sont largement erronées parce qu'ils n'ont pas correctement pris en compte la taille des items. Fiabiliser ce chiffre avant de s'engager change complètement l'équation économique.

Le propos n'est pas de dire que DynamoDB est cher. Le propos est que son modèle de coût diffère de ce à quoi la plupart des ingénieurs sont habitués, et que les variables qui le déterminent (taille des items, efficacité des patterns d'accès, capacité à la demande ou provisionnée) doivent être comprises avant de s'engager, pas après.

Le déclic mental qui change tout

Voici le réflexe que la plupart des ingénieurs issus du relationnel appliquent à DynamoDB : concevoir d'abord le schéma, puis réfléchir aux requêtes.

Avec une base relationnelle, cela fonctionne globalement. On normalise les données, on crée les index plus tard, on écrit des requêtes avec des jointures entre tables. Le moteur de base de données gère une grande partie de la complexité des requêtes.

DynamoDB ne fonctionne pas ainsi. Contrairement aux bases relationnelles, il n'optimise pas des requêtes arbitraires via un planificateur de requêtes. Il route chaque requête directement vers la partition qui détient les données, à partir du hash de la clé de partition, ce qui est l'une des raisons pour lesquelles DynamoDB peut offrir de façon constante une latence de quelques millisecondes, quelle que soit la taille de la table. La contrepartie, c'est que la base est optimisée pour une seule chose : récupérer efficacement des items via des patterns d'accès basés sur les clés, par la clé primaire ou les index secondaires. Tout le reste (filtrer, trier sur des attributs hors clé, interroger des relations entre entités) est soit coûteux, soit exige des index supplémentaires conçus à l'avance.

Le déclic est le suivant : vous devez connaître vos patterns d'accès avant de concevoir votre table. Pas approximativement. Précisément. "Récupérer toutes les commandes d'un utilisateur, triées par date" est une donnée de conception. "Récupérer les 10 tickets de support escaladés les plus récents pour un compte donné" est une donnée de conception. Votre schéma se construit à rebours à partir de ces questions, pas à partir de la forme des données.

En pratique, cela signifie qu'une seule table DynamoDB stocke souvent plusieurs types d'entités côte à côte, avec des clés de partition et des clés de tri construites pour répondre efficacement à des questions précises. Cela semble aberrant pour quiconque vient d'un univers SQL normalisé. Ce n'est pas une erreur. C'est justement tout l'intérêt.

Les clés de tri composites

Prenons un exemple courant : les commandes d'un utilisateur, que vous devez interroger par statut et par date. L'approche naïve stocke le statut et la date comme attributs séparés, puis filtre à la lecture. Vous finissez par lire toutes les commandes de cet utilisateur et par écarter celles qui ne correspondent pas.

L'approche qui part des patterns d'accès encode la requête directement dans la clé de tri :

PK SK
user#123 ACTIVE#2024-07-15
user#123 ACTIVE#2024-07-01
user#123 COMPLETED#2024-06-20
user#123 COMPLETED#2024-06-10

Désormais, une seule requête avec BEGINS_WITH("ACTIVE#") ne renvoie que les commandes actives, triées par date, sans lire une seule commande terminée. Vous payez exactement pour ce que vous récupérez.

Si cela fonctionne, c'est parce que BEGINS_WITH est une requête par préfixe sur la clé de tri. Le regroupement le plus large doit venir en premier pour que DynamoDB puisse s'en servir pour restreindre la plage. Une approche courante consiste à placer la condition la plus large à gauche et des composants de plus en plus spécifiques vers la droite, de sorte que les requêtes par préfixe puissent cibler efficacement le sous-ensemble qui vous intéresse.

Les Global Secondary Indexes épars

Autre pattern qui découle d'une réflexion centrée sur les patterns d'accès : si seule une petite fraction de vos items remplit un jour une condition (tickets escaladés, enregistrements signalés, items en attente de validation), modélisez cette condition sous forme d'un attribut qui n'existe que sur ces items. Un GSI construit sur cet attribut n'indexe que les items où il est présent.

Le comportement clé ici est que DynamoDB n'inclut pas un item dans un GSI lorsque l'attribut indexé est absent (pas simplement null, mais totalement absent de l'item). Vous pouvez donc rendre un GSI épars par conception, simplement en omettant l'attribut sur les items que vous ne voulez pas indexer.

Si 2 % de vos tickets sont escaladés, le GSI contient 2 % de la table. L'interroger coûte infiniment moins cher que de scanner la table entière puis de filtrer. Le GSI est épars par conception, pas par accident.

Your cloud bill shouldn't be a mystery

Optimization, automation, expertise. In one platform.

Les erreurs qui se voient sur votre facture

Elles méritent d'être nommées précisément, parce qu'elles sont fréquentes, invisibles tant que vous ne regardez pas vos rapports de coûts, et généralement introduites par des ingénieurs qui connaissent pourtant raisonnablement bien DynamoDB.

Les expressions de filtre

DynamoDB permet bel et bien de filtrer les résultats d'une requête après leur récupération. Le problème, c'est qu'une FilterExpression ne réduit pas les unités de capacité consommées ; elle réduit seulement ce qui est renvoyé à l'appelant. Si une requête lit 500 items avant l'exécution du filtre, vous êtes facturé pour toutes les données lues jusque-là, quel que soit le nombre d'items renvoyés à l'appelant.

Cela devient vite coûteux quand c'est la stratégie principale pour restreindre les résultats. Cela ressemble à une clause WHERE en SQL, on y recourt donc facilement sans penser au coût. La solution consiste presque toujours à repenser la structure des clés pour que la base ne récupère que ce dont vous avez besoin. Les expressions de filtre ont leur utilité, mais elles ne doivent pas porter votre stratégie de requêtage.

Les partitions chaudes liées aux clés temporelles

Un pattern courant pour les données de séries temporelles : utiliser le timestamp ou l'heure courante comme clé de partition. Le raisonnement semble intuitif : partitionner par tranche de temps. Le problème, c'est que toutes les écritures ciblent la même clé de partition logique, ce qui empêche DynamoDB de répartir uniformément le trafic d'écriture entre les partitions. À tout volume d'écriture significatif, cela conduit au throttling.

DynamoDB dispose bien de l'Adaptive Capacity, qui redistribue automatiquement le débit vers les partitions qui reçoivent le plus de trafic. Pour un déséquilibre modéré, elle gère souvent le problème de manière transparente. Mais aucune capacité adaptative ne compense une clé de partition unique soumise à un trafic extrême et soutenu, et une clé par tranche horaire sous forte charge d'écriture correspond exactement à cette situation.

La solution est le sharding des écritures : ajoutez un suffixe aléatoire à la clé de partition (par exemple EVENTS#4, où le suffixe est un nombre entre 0 et N) pour répartir les écritures sur plusieurs partitions logiques. À la lecture, interrogez chaque shard en parallèle et fusionnez les résultats. Cela demande plus de code applicatif, mais c'est ce qui évite qu'un workload d'écriture à haut débit ne s'étrangle sur une seule partition.

Les scans de table

Troisième point à souligner : les scans complets de table. DynamoDB prend en charge les opérations Scan, et les ingénieurs y recourent parfois quand ils sont à court de GSI ou doivent interroger un attribut non indexé. Le problème, c'est qu'un scan lit chaque item de la table, quel que soit le nombre de correspondances. Sur une grande table, c'est à la fois lent et coûteux.

Les scans sont parfaitement légitimes pour les migrations, les exports, les tâches d'administration ou les traitements en arrière-plan où la latence importe peu. Le problème, c'est de les utiliser dans les chemins de requête exposés aux utilisateurs. Si un scan se trouve dans le flux critique de votre application, c'est presque toujours le signe que les patterns d'accès n'ont pas été pleinement pris en compte lors de la conception du schéma. La solution passe généralement par un nouveau GSI ou une clé de tri repensée, pas par un scan plus rapide.

Pour conclure

DynamoDB est réellement puissant et, pour les bons workloads, c'est l'une des meilleures bases de données proposées par AWS. Mais l'écart entre "avoir choisi la bonne base de données" et "l'avoir bien conçue" est large, et cet écart apparaît sur votre facture AWS avant d'apparaître ailleurs. Le modèle de coût est différent, le processus de conception est différent, et les erreurs sont différentes de celles que la plupart des ingénieurs ont rencontrées jusqu'ici.

Si vous évaluez DynamoDB pour un nouveau workload, ou si vous avez déjà des tables en production et que les coûts sont plus difficiles à expliquer que vous ne le voudriez, c'est exactement le type de travail que DoiT mène chaque semaine avec des clients AWS. Notre équipe de plus de 100 experts cloud peut vous aider à valider vos patterns d'accès, à détecter les problèmes de conception en amont et à tirer le meilleur des services que vous payez déjà. Réservez une démo.