Cloudflare D1
SQLite
Serverless
Banco de Dados
Edge

Cloudflare D1 : La base de données SQLite à la périphérie — et pourquoi « edge » ne signifie pas ce qu'il semble être

D1 n'exécute pas ses requêtes dans tous les centres de données Cloudflare : il dispose d'une région principale où toutes les écritures ont lieu et de répliques de lecture avec une cohérence éventuelle.

Cloudflare D1 : La base de données SQLite à la périphérie — et pourquoi « edge » ne signifie pas ce qu'il semble être

Appeler D1 une «base de données à la périphérie» crée une attente à laquelle l'architecture ne répond pas entièrement. L'image mentale est celle de SQLite s'exécutant simultanément dans les 300 centres de données Cloudflare, avec ses requêtes répondant à partir du point géographique le plus proche de l'utilisateur. La réalité est plus restreinte : il existe une région principale où toutes les écritures ont lieu, et des réplicas en lecture répartis sur le réseau qui reçoivent ces écritures avec un délai pouvant atteindre 60 secondes. Si votre banque principale se trouve en Amérique du Nord et que vous écrivez à partir d'un travailleur travaillant à São Paulo, cette écriture parcourt 80 à 150 millisecondes aller-retour avant d'être confirmée. Quickstart ne le mentionne pas.

La véritable architecture de la D1

D1 utilise SQLite comme moteur de base de données – le même SQLite qui s'exécute dans les navigateurs, les appareils mobiles et les applications de bureau. Au-dessus de ce moteur, Cloudflare a construit une couche de réplication : une instance principale reçoit toutes les écritures et propage les modifications vers les réplicas en lecture distribués sur le réseau mondial.

Lorsque vous créez une banque D1, vous choisissez (ou laissez Cloudflare choisir automatiquement) votre région principale. Ce choix détermine où atterrissent les écrits. Une lecture effectuée par un Worker exécuté à São Paulo peut être servie par une réplique à proximité, avec une latence supplémentaire de 5 à 20 millisecondes par rapport au temps d'exécution du Worker. Une écriture effectuée par le même Worker va vers la région principale - et si cette région est us-east-1, l'aller-retour dure 80 à 150 ms de réseau seul avant que vous receviez une confirmation.

Le temps de propagation des réplicas est pertinent en production : une écriture sur le réplica principal peut mettre jusqu'à 60 secondes pour apparaître sur toutes les réplicas. Pendant cet intervalle, un Worker lisant à partir d’une réplique obsolète voit les données de pré-écriture. Ce comportement est appelé cohérence éventuelle : la réplique convergera vers l’état correct, mais pas immédiatement.

Le problème de cohérence que vous rencontrerez en production

Le modèle qui rompt avec la cohérence éventuelle est l’écriture suivie immédiatement de la lecture. Vous créez un utilisateur, redirigez vers la page de profil et la requête qui charge le profil atteint une réplique qui n'a pas encore reçu l'INSERT. Le résultat est un profil vide, ou une erreur 404, ou un état incohérent que l'utilisateur voit et ne comprend pas.

Ce problème existe dans n'importe quelle base de données avec réplication — mais avec D1, il apparaît sans avertissement car l'abstraction de liaison masque la réplique consultée. Cloudflare a créé l'API Sessions exactement pour ce cas : au sein de la même session D1, une écriture garantit que la lecture suivante verra les données écrites, quelle que soit la réplique qui sert la requête.

L'API Sessions fonctionne en créant une session avec env.DB.withSession(). Dans le rappel, toutes les requêtes partagent le contexte de session et D1 garantit que les lectures post-écriture renvoient des données mises à jour. Pour les flux combinant écriture et lecture immédiate (création de compte, mises à jour de paramètres, exécution de commandes), l'utilisation de l'API Sessions est le moyen direct d'éviter les incohérences visibles par l'utilisateur.

Pour les flux purement en lecture seule, tels que les listes et les tableaux de bord, la cohérence à terme n'est pas un problème : les données peuvent être retardées de quelques secondes sans aucun impact notable.

Prix réel : quand le niveau gratuit ne suffit plus

Le niveau gratuit de D1 offre 5 Go de stockage, 5 millions de lignes lues par jour et 100 000 lignes écrites par jour. Ces chiffres semblent généreux dans le résumé, mais le coût de lecture de D1 n'est pas basé sur les lignes renvoyées, mais sur les lignes examinées par le moteur de base de données.

Une requête qui analyse 100 000 lignes pour en renvoyer 5 000 consomme 100 000 lectures, et non 5 000. Une application avec un millier d'utilisateurs actifs effectuant des requêtes de listage sans index adéquats peut épuiser 5 millions de lectures quotidiennes en quelques heures. Le niveau gratuit est suffisant pour le développement, les outils internes à faible volume et le prototypage, mais pas pour les applications avec un trafic utilisateur réel.

Lorsque le niveau gratuit ne suffit pas, l'étape suivante nécessite le plan Workers Paid (5 $/mois pour la plate-forme) plus les coûts variables de D1 : 0,001 $ par million de lignes lues, 1 $ par million de lignes écrites et 0,75 $ par Go-mois de stockage. Le coût d'écriture a une arithmétique simple : un flux d'enregistrement qui insère 10 lignes par utilisateur équivaut à 10 $ en frais d'écriture pour chaque million d'utilisateurs enregistrés. Pour les applications à croissance rapide, ce nombre apparaît plus tôt que prévu.

Le coût des lectures dépend presque entièrement de la qualité des index. Avec des index appropriés, une requête qui renvoie 20 lignes lit 20 lignes. Sans index, la même requête peut lire 500 000 lignes et coûter 500 fois plus.

Comment planifier la région principale avant de créer la banque

La région primaire D1 est une décision irréversible dans la création de la banque. Il n'y a pas d'option pour déplacer la base de données principale ultérieurement : l'alternative consiste à exporter les données, à créer une nouvelle base de données dans la région souhaitée et à importer. Cela fait du choix de la région l’une des rares décisions d’infrastructure qui nécessite un examen attentif avant d’écrire la première ligne de code.

La règle générale : la région principale doit être celle où proviennent la plupart des écrits. Pour un produit brésilien avec des utilisateurs brésiliens, Worker fonctionne probablement sur le PoP de São Paulo (GRU) ou similaire. Cloudflare propose southamerica-east1 comme option de région principale D1 : le choix de cette région pour un produit brésilien réduit la latence d'écriture de 80 à 150 ms à 5 à 20 ms.

Pour vérifier quelle région est la plus logique, mesurez la latence du réseau du Worker pour la région candidate à l'aide d'un simple fetch avec horodatage avant et après. Le coût d'un mauvais choix de région principale n'apparaît pas lors du développement : il apparaît lorsque l'application est en production et que chaque écriture ajoute 100 ms de latence notable pour l'utilisateur.

La limite de 2 Go par banque et de 10 banques dans le forfait payant est également incluse dans la planification initiale. Si l'application a tendance à dépasser 2 Go, il faut penser au partitionnement des données entre plusieurs banques D1 avant l'arrivée des premières données. Refactoriser ce partitionnement plus tard, avec les données en production, demande beaucoup plus de travail.

A lire aussi

-Cloudflare KV : ce que signifie une distribution mondiale lorsque vous devez écrire