Die Bezeichnung D1 als „Datenbank am Rande“ weckt eine Erwartung, die die Architektur nicht vollständig erfüllt. Die mentale Vorstellung ist, dass SQLite in allen 300 Cloudflare-Rechenzentren gleichzeitig läuft und seine Abfragen von dem Punkt aus antworten, der dem Benutzer geografisch am nächsten liegt. Die Realität ist eingeschränkter: Es gibt eine primäre Region, in der alle Schreibvorgänge stattfinden, und über das Netzwerk verteilte Lesereplikate, die diese Schreibvorgänge mit einer Verzögerung von bis zu 60 Sekunden empfangen. Wenn sich Ihre Hauptbank in Nordamerika befindet und Sie von einem in São Paulo ausgeführten Worker aus schreiben, durchläuft dieser Schreibvorgang 80 bis 150 Millisekunden hin und her, bevor er bestätigt wird. Quickstart erwähnt dies nicht.
Die wahre Architektur von D1
D1 verwendet SQLite als Datenbank-Engine – dasselbe SQLite, das in Browsern, Mobilgeräten und Desktop-Anwendungen ausgeführt wird. Auf dieser Engine baute Cloudflare eine Replikationsschicht auf: Eine primäre Instanz empfängt alle Schreibvorgänge und gibt Änderungen an Lesereplikate weiter, die über das globale Netzwerk verteilt sind.
Wenn Sie eine D1-Bank erstellen, wählen Sie Ihre primäre Region aus (oder lassen Cloudflare diese automatisch auswählen). Diese Wahl bestimmt, wo die Schriften landen. Eine von einem in São Paulo ausgeführten Worker durchgeführte Lesung kann von einer Replik in der Nähe bereitgestellt werden, mit einer zusätzlichen Latenz von 5 bis 20 Millisekunden über die Ausführungszeit des Workers hinaus. Ein vom selben Worker vorgenommener Schreibvorgang geht an die primäre Region – und wenn diese Region us-east-1 ist, beträgt der Hin- und Rückweg allein im Netzwerk 80 bis 150 ms, bevor Sie eine Bestätigung erhalten.
Die Replikat-Ausbreitungszeit ist in der Produktion relevant: Es kann bis zu 60 Sekunden dauern, bis ein Schreibvorgang auf dem Primärserver auf allen Replikaten erscheint. Während dieses Intervalls sieht ein Worker, der von einem veralteten Replikat liest, vorab geschriebene Daten. Dieses Verhalten wird als Eventualkonsistenz bezeichnet – das Replikat konvergiert in den korrekten Zustand, jedoch nicht sofort.
Das Konsistenzproblem, auf das Sie in der Produktion stoßen werden
Das Muster, das mit der letztendlichen Konsistenz bricht, ist das Schreiben, dem unmittelbar das Lesen folgt. Sie erstellen einen Benutzer, leiten zur Profilseite weiter und die Abfrage, die das Profil lädt, trifft auf ein Replikat, das den INSERT noch nicht erhalten hat. Das Ergebnis ist ein leeres Profil, ein 404-Fehler oder ein inkonsistenter Zustand, den der Benutzer sieht, aber nicht versteht.
Dieses Problem besteht in jeder Datenbank mit Replikation – bei D1 tritt es jedoch ohne Warnung auf, da die Bindungsabstraktion verbirgt, welches Replikat konsultiert wird. Cloudflare hat die Sessions-API genau für diesen Fall erstellt: Innerhalb derselben D1-Sitzung garantiert ein Schreibvorgang, dass der nachfolgende Lesevorgang die geschriebenen Daten sieht, unabhängig davon, welches Replikat die Abfrage bedient.
Die Sitzungs-API erstellt eine Sitzung mit env.DB.withSession(). Innerhalb des Rückrufs teilen alle Abfragen den Sitzungskontext und D1 stellt sicher, dass Lesevorgänge nach dem Schreiben aktualisierte Daten zurückgeben. Für Abläufe, die Schreiben und sofortiges Lesen kombinieren – Kontoerstellung, Einstellungsaktualisierungen, Auftragsabschluss – ist die Verwendung der Sessions API der direkte Weg, für den Benutzer sichtbare Inkonsistenzen zu vermeiden.
Bei rein schreibgeschützten Abläufen wie Listen und Dashboards stellt die letztendliche Konsistenz kein Problem dar: Daten können ohne spürbare Auswirkungen um einige Sekunden verzögert werden.
Echter Preis: wenn das kostenlose Kontingent nicht mehr ausreicht
Das kostenlose Kontingent von D1 bietet 5 GB Speicherplatz, 5 Millionen gelesene Zeilen pro Tag und 100.000 geschriebene Zeilen pro Tag. Diese Zahlen klingen abstrakt betrachtet großzügig, aber die Lesekosten von D1 basieren nicht auf den zurückgegebenen Zeilen, sondern auf den von der Datenbank-Engine untersuchten Zeilen.
Eine Abfrage, die 100.000 Zeilen durchsucht, um 5.000 zurückzugeben, verbraucht 100.000 Messwerte, nicht 5.000. Eine Anwendung mit tausend aktiven Benutzern, die Auflistungsabfragen ohne angemessene Indizes durchführen, kann in wenigen Stunden 5 Millionen tägliche Messwerte erschöpfen. Die kostenlose Stufe reicht für die Entwicklung, interne Tools mit geringem Volumen und Prototyping aus – nicht für Anwendungen mit echtem Benutzerverkehr.
Wenn das kostenlose Kontingent nicht ausreicht, ist im nächsten Schritt der Workers Paid-Plan (5 US-Dollar pro Monat für die Plattform) zuzüglich der variablen Kosten von D1 erforderlich: 0,001 US-Dollar pro Million gelesener Zeilen, 1 US-Dollar pro Million geschriebener Zeilen und 0,75 US-Dollar pro GB-Monat an Speicher. Die Schreibkosten lassen sich einfach rechnen: Ein Registrierungsablauf, der 10 Zeilen pro Benutzer einfügt, beläuft sich auf 10 US-Dollar an Schreibkosten pro Million registrierter Benutzer. Bei schnell wachsenden Anwendungen erscheint diese Zahl früher als erwartet.
Die Lesekosten hängen fast vollständig von der Qualität der Indizes ab. Bei geeigneten Indizes liest eine Abfrage, die 20 Zeilen zurückgibt, 20 Zeilen. Ohne Indizes kann dieselbe Abfrage 500.000 Zeilen lesen und kostet das 500-fache.
So planen Sie die Primärregion vor der Gründung der Bank
Die D1-Primärregion ist eine unumkehrbare Entscheidung bei der Gründung der Bank. Es gibt keine Möglichkeit, die primäre Datenbank später zu verschieben. Die Alternative besteht darin, die Daten zu exportieren, eine neue Datenbank in der gewünschten Region zu erstellen und zu importieren. Dies macht die Wahl der Region zu einer der wenigen Infrastrukturentscheidungen, die vor dem Schreiben der ersten Codezeile sorgfältig geprüft werden müssen.
Als Faustregel gilt: Die primäre Region sollte der Ursprungsort der meisten Schriften sein. Bei einem brasilianischen Produkt mit brasilianischen Benutzern läuft Worker wahrscheinlich auf dem São Paulo PoP (GRU) oder ähnlichem. Cloudflare bietet southamerica-east1 als D1-Primärregionsoption an – die Auswahl dieser Region für ein brasilianisches Produkt reduziert die Schreiblatenz von 80–150 ms auf 5–20 ms.
Um zu überprüfen, welche Region am sinnvollsten ist, messen Sie die Netzwerklatenz des Workers für die Kandidatenregion mithilfe eines einfachen fetch mit Zeitstempel davor und danach. Die Kosten einer falschen Wahl der primären Region fallen nicht in der Entwicklung auf, sondern erst, wenn die Anwendung in der Produktion ist und jeder Schreibvorgang für den Benutzer eine spürbare Latenz von 100 ms mit sich bringt.
Das Limit von 2 GB pro Bank und 10 Banken im kostenpflichtigen Plan ist ebenfalls in der Erstplanung enthalten. Wenn die Anwendung tendenziell über 2 GB hinaus wächst, muss über die Datenpartitionierung zwischen mehreren D1-Banken nachgedacht werden, bevor die ersten Daten eintreffen – eine spätere Umgestaltung dieser Partitionierung, wenn sich die Daten in der Produktion befinden, ist erheblich aufwändiger.
Lesen Sie auch
- Cloudflare KV: Was global verteilt bedeutet, wenn Sie schreiben müssen
- D1 in der Produktion: Leistung, Grenzen und was sich nicht alleine skalieren lässt
- Migrationen in D1: Wie man ein Schema versioniert und was passiert, wenn es schief geht
- Durable Objects von Cloudflare: Konsistenter Zustand am Rande – was sich wirklich ändert
- Cloudflare Workers in der Produktion: Was sich nach „Hello World“ ändert
- Cloudflare Workers vs. Pages: Der Unterschied, der wichtig ist, bevor Sie sich entscheiden
