9 Punkte von GN⁺ 2024-04-22 | 3 Kommentare | Auf WhatsApp teilen
  • SQLite ist sehr schnell. Auf einem normalen Single-Server für etwa 40 €/Monat kann es gleichzeitig rund 168.000 Lesevorgänge und rund 8.000 Schreibvorgänge dauerhaft bewältigen.
  • Da SQLite eine Embedded-Bibliothek ist, die für clientseitige Anwendungen wie Embedded-Systeme, Smartphones und Desktop-Anwendungen entwickelt wurde, muss sich die SQLite-Datenbank zusammen mit dem Anwendungsserver befinden und kann nicht über das Netzwerk aufgerufen werden.
  • Wie lässt sich SQLite in Situationen nutzen, in denen mehr als eine Maschine benötigt wird?
    • Ein Wochenendprojekt könnte plötzlich explodieren und schnell skaliert werden müssen.
    • Eine der Anforderungen des CTO könnte sein, einen hochverfügbaren Service in mindestens zwei verschiedenen Rechenzentren zu betreiben.
  • In den vergangenen Jahren sind einige Projekte entstanden, die SQLite zu einer Backend-Datenbank für Backend-Anwendungen umbauen wollen.
  • Dieser Artikel untersucht, ob das ein Paradigmenwechsel ist, der Organisationen hilft, schneller eine bessere User Experience bereitzustellen, oder nur Marketing-Hype von Unternehmen, die ihr „Unique Selling Proposition“ aufblähen wollen.

SQLite als Edge-Datenbank nutzen

  • SQLite wird nicht einfach als Backend-Datenbank, sondern als Edge-Datenbank vermarktet.
  • Die bekanntesten Akteure sind Cloudflare D1, fly.io mit LiteFS und Turso.
  • Die meisten SQLite-Derivate funktionieren auf ähnliche Weise.
    • Es gibt eine primäre Datenbank, die Schreibvorgänge annimmt, und diese wird asynchron in andere Regionen repliziert.
    • Die Replikation erfolgt meist, indem das SQLite Write-Ahead Log gestreamt wird, das alle auf der Datenbank ausgeführten Transaktionen protokolliert.
    • In dieser Architektur können Lesevorgänge theoretisch in Edge-Rechenzentren verarbeitet werden, Schreibvorgänge müssen aber weiterhin an einen zentralen Standort weitergeleitet werden.
  • In der Praxis möchte man nicht, dass ein Kunde in einer E-Commerce-Anwendung eine Bestellung erfolgreich abschließt, die Bestellung in der primären SQLite-Datenbank bestätigt wurde, die lokale Lesereplik jedoch hinterherhinkt, die aktualisierten Daten noch nicht erhalten hat und deshalb eine Fehlermeldung „nicht gefunden“ anzeigt.
  • Willkommen in der „schmerzhaften Welt der Eventual Consistency“.

LiteFS’ Lösung und ihre Grenzen

  • LiteFS schlägt eine hackartige Lösung vor. Die Anwendung setzt ein __txid-Cookie, um die letzte Transaktion zu verfolgen, über die die lokale Replik verfügt. Ist sie zu alt, werden Leseabfragen an die primäre Datenbank weitergeleitet.
  • Damit ist die Anwendung nun eng an Datenbank und Reverse Proxy gekoppelt.
  • LiteFS erwähnt nicht, dass es nur ungefähr 100 Schreibvorgänge pro Sekunde unterstützt.

Die wichtigsten Nachteile der meisten verteilten SQLite-Systeme

  • Die meisten verteilten SQLite-Systeme unterstützen keine interaktiven Transaktionen, bei denen zwischen verschiedenen Abfragen innerhalb einer Transaktion Berechnungen durchgeführt werden.
  • Es kann immer nur eine Schreibtransaktion gleichzeitig aktiv sein. In einer normalen SQLite-Datenbank ist das meist in Ordnung, weil die meisten Schreibvorgänge nicht länger als einige Dutzend Mikrosekunden dauern.
  • Führt man jedoch Netzwerklatenz zwischen Anwendung und SQLite-Datenbank ein, bricht das System zusammen. Die Datenbank bleibt für die Dauer der Round-Trip-Zeit der Transaktion gesperrt und wird auf einige wenige Schreibvorgänge pro Sekunde begrenzt sein.
  • Turso „löst“ das mit Batching. Mehrere Abfragen können zu einem Batch zusammengefasst und als eine einzelne Transaktion ausgeführt werden. Cloudflare D1 „löst“ das Problem mit Batches und Stored Procedures.

Was, wenn es eine einfachere Lösung gibt?

  • Für Webanwendungen gibt es bereits eine sehr einfache und leistungsfähige Methode, sie weltweit sehr schnell zu machen: HTTP-Caching mit Cache-Control- und ETag-Headern.
  • Mit HTTP-Caching muss man keine Techniken verwenden, die schwach konsistenten Datenbanken ähneln, wodurch Webanwendungen nicht unnötig komplex werden oder anfällig für Race Conditions sind.
  • Der Autor dieses Artikels widmet in seinem neuen Buch „Cloudflare for Speed and Security“ viel Zeit der Erklärung verschiedener Caching-Strategien, mit denen sich Webanwendungen nicht nur schneller machen lassen, sondern mit minimalen Ressourcen auch sehr viele gleichzeitige Nutzer bedienen können.

Datenbanken als Abstraktion

  • Latenz war nicht das einzige Problem, das verteiltes SQLite lösen wollte. Ein weiteres ist die betriebliche Komplexität.
  • Einen Cluster vernetzter Server zu verwalten ist schwierig und führt oft zu Ausfällen und Umsatzeinbußen. Ganz zu schweigen vom Datenbankbetrieb, der ständige Aufmerksamkeit und eine gute Sicherheitskultur erfordert, um Katastrophen wie bei GitLab im Jahr 2017 zu vermeiden.
  • Die Idee ist daher, die Datenbank mit der Anwendung zu bündeln und alles auf einem einzelnen Server zu platzieren.
  • Das ist gut, wenn es nur einen einzelnen Entwickler gibt, aber in großen Organisationen gibt es meist Personen oder Teams, die speziell für die Wartung von Datenbankservern zuständig sind.
  • Genau deshalb sind Datenbanken, auf die über Sockets statt als Embedded-Bibliothek zugegriffen wird, eine hervorragende Abstraktion: nicht als technische, sondern als organisatorische Abstraktion. Während der Entwicklung kann das ein einfacher Container auf dem Rechner des Entwicklers sein, in Produktion aber alles Mögliche — von einem Container auf demselben Server wie die Anwendung bis zu einem verteilten Cluster, auf den über das Netzwerk zugegriffen wird. Entwickler müssen nur eine einzige Konfigurationsvariable austauschen, nämlich DATABASE_URL, und das Betriebsteam kümmert sich um den Rest.
  • Umgekehrt war das traditionelle Unix-Dateisystem keine geeignete Abstraktion für verteiltes Computing. Natürlich gibt es NFS (Network File System), aber weil das Unix-Dateisystem für den Zugriff auf einer einzelnen Maschine entworfen wurde, ist die Performance eher schlecht. Das S3-Protokoll hingegen ist eine ziemlich gute Abstraktion, um große Mengen unstrukturierter Daten effizient, skalierbar und zuverlässig zu speichern. Entwickler verwenden einfach ein S3-kompatibles SDK und können es dann vergessen; das Betriebsteam oder der Cloud-Anbieter kümmert sich um Performance, Haltbarkeit, Zuverlässigkeit und alles andere.

Fazit

  • SQLite ist eine wirklich beeindruckende Datenbank, aber die meisten Teams sollten SQLite meiden und stattdessen PostgreSQL wählen.
  • Unzählige Stunden an Engineering-Arbeit wurden investiert, um PostgreSQL zur besten Backend-Datenbank zu machen. Wer SQLite wählt, muss zwangsläufig auf fragile und fehleranfällige Weise Dinge neu erfinden, die PostgreSQL seit Langem bereits bietet.
  • Die aktuelle Bewegung, SQLite zu einer Backend-Datenbank zu machen, ist aus Sicht des Autors lediglich ein Marketing-Coup von Unternehmen, die Edge-Computing-Infrastruktur verkaufen und erkannt haben, dass Computing ohne Datenspeicher nichts ist. Sein ungefragter Rat an sie lautet: Statt ein CDN aufzubauen und Anwendungen zusätzliche Komplexität aufzuzwingen, sollten sie in HTTP-Caching investieren. Das bringt deutlich bessere Ergebnisse.
  • Wegen der dadurch verursachten Komplexität werden 99,9 % der Backend-Anwendungen keinen Vorteil daraus ziehen, an den Edge verlagert zu werden. Stattdessen sollte man sich darauf konzentrieren, gute Caching-Strategien auszurollen, um weltweit eine hervorragende Erfahrung mit unter 100 ms zu bieten.
  • Und genau hier endet das SQLite-Experiment für serverseitige Anwendungen. PostgreSQL gewinnt.
  • „Amateure diskutieren Taktik, Profis diskutieren Logistik. (Amateurs discuss tactics. Professionals discuss logistics.)“
    Für den Erfolg sind nicht taktische Entscheidungen vor Ort am wichtigsten, sondern die unterstützenden Systeme und Prozesse, die solche Entscheidungen erst möglich machen — also Logistik und Betrieb.

Meinung von GN⁺

  • Wie der Autor argumentiert, scheint der Einsatz von SQLite in den meisten Backend-Anwendungen nur die Komplexität zu erhöhen, ohne einen echten Nutzen zu bringen. Die bessere Wahl dürfte sein, bereits bewährte und ausgereifte Datenbanken wie PostgreSQL zu verwenden.
  • Dass Anbieter von Edge-Computing-Infrastruktur SQLite so stark pushen, wirkt eher wie Teil einer Marketingstrategie als wie ein technischer Vorteil. Mehr Investitionen in HTTP-Caching und CDN würden Anwendungsentwicklern stärker helfen.
  • Die meisten Backend-Anwendungen können schon mit einer geeigneten Caching-Strategie ausreichend schnelle und skalierbare Dienste bereitstellen. Wenn Edge-Computing nicht zwingend erforderlich ist, sollte man übermäßige Komplexität vermeiden.
  • Verteiltes SQLite kann für bestimmte Use Cases nützlich sein, scheint aber noch Grenzen zu haben, um als allgemeine Lösung zu dienen. Entwicklungsfreundlichkeit, Performance und Konsistenz gleichzeitig zu erfüllen, dürfte nicht einfach sein.
  • Letztlich ist es am wichtigsten, eine Technologie zu wählen, die zu den Anforderungen der Anwendung und den Fähigkeiten des Teams passt. Statt Trends zu folgen, sollte man Vor- und Nachteile gründlich analysieren und sorgfältig entscheiden.
  • Der Autor betont, dass SQLite als Backend-Datenbank noch viele Schwächen hat, doch es könnte andere Use Cases geben, in denen sich die Stärken von SQLite ausspielen lassen. Deshalb sollte man es nicht vollständig ausschließen.

3 Kommentare

 
aer0700 2025-03-03

Statt darüber zu diskutieren, was besser ist, Postgres oder SQLite,

wäre es nicht sinnvoller, sich zu fragen, welches von beiden besser zur eigenen Situation passt?

Je nach Situation fällt die beste Wahl schließlich unterschiedlich aus.

 
[Dieser Kommentar wurde ausgeblendet.]
 
GN⁺ 2024-04-22

Hacker-News-Meinungen

  • Laut dem Autor von LiteFS ist verteiltes SQLite für Entwickler weder ein Paradigmenwechsel noch übertriebener Hype, sondern eher eine Erweiterung oder der „nächste Schritt“
    • Es adressiert Bedenken hinsichtlich der horizontalen Skalierbarkeit von SQLite
  • Der bevorstehende Paradigmenwechsel durch verteiltes SQLite wird voraussichtlich auf die Geräte der Nutzer zielen
    • Es ermöglicht Local-First-Apps und bietet schnelle UI-Interaktionen sowie durch Synchronisierung letztendliche Konsistenz
  • Der Einsatz von LiteFS in Produktionsumgebungen kann Datenbankabfragen sofort auflösen, wodurch Ladezustände in Web-Apps entfallen und schnelle Ladezeiten möglich werden
  • Es besteht Bedarf an einer einfachen, verteilten Open-Source-Storage-Lösung für Self-Hosting
    • Bestehende Lösungen wie Ceph, SeaweedFS und MinIO bringen Herausforderungen und Komplexität mit sich
  • Die Idee von LiteFS besteht darin, die Performance-Vorteile von SQLite zu nutzen, indem für lesezentrierte Anwendungen die Netzwerk-n-Tier-Architektur ersetzt wird
    • Das passt möglicherweise nicht perfekt für jede Anwendung
  • Die Behauptung des Artikels, die Nutzung von SQLite würde nur „ein paar Millisekunden sparen“, wird als Untertreibung angesehen
    • Wenn Anwendungen näher bei den Nutzern ausgeführt werden, kann die Query-Latenz erheblich sinken
  • SQLite und PostgreSQL haben unterschiedliche Anwendungsfälle und Stärken
    • Es handelt sich nicht um einen direkten Wettbewerb zwischen beiden
  • Die Behauptung des Artikels, PostgreSQL sei die beste Backend-Datenbank und mit SQLite würde man Features auf fragile Weise neu erfinden, wird infrage gestellt
    • Ähnliche Behauptungen ließen sich auch über andere Datenbanken aufstellen
  • Ein möglicher Ansatz ist es, SQLite zu sharden, indem für jeden Nutzer eine eigene Datenbank erstellt wird
    • Voraussetzung ist jedoch, dass Nutzer nicht mit den Daten anderer Nutzer interagieren müssen