1 Punkte von GN⁺ 2024-08-11 | 1 Kommentare | Auf WhatsApp teilen

Aufbau eines hochverfügbaren Web-Service ohne Datenbank

Erkundung

  • Bei neuen Startups werden üblicherweise Web-Frameworks wie Rails, Django oder Node sowie Datenbanken wie MySQL, PostgreSQL oder MongoDB gewählt
  • Aber was wäre, wenn sich Web-Service und Datenbankinstanz zu einer Einheit zusammenführen ließen? Der Ansatz besteht darin, alle Daten im RAM zu speichern
  • Wenn RAM als Datenbank verwendet wird, müssen Daten nicht mehr über SQL-Abfragen serialisiert werden
  • Indizes lassen sich mithilfe von In-Memory-Hash-Tabellen implementieren
  • Hintergrundaufgaben können als Threads innerhalb eines großen Prozesses verarbeitet werden
  • Falls der Prozess abstürzt, ist eine Wiederherstellung möglich, indem regelmäßig Snapshots des RAM erstellt und Änderungen auf die Festplatte geschrieben werden

Skalierung

  • Wenn Kunden Hochverfügbarkeit verlangen, werden Server mithilfe des Raft-Konsensalgorithmus repliziert
  • Fällt der Leader-Server aus, wird ein neuer Leader gewählt, der die Anfragen verarbeitet
  • Auf diese Weise sind Rolling Deployments möglich, ohne die Server neu zu starten

Auslagerung

  • Wenn es viele große Kunden gibt, kann der Web-Service per Sharding aufgeteilt und verarbeitet werden
  • Jedem Enterprise-Kunden wird ein dedizierter Cluster bereitgestellt
  • Der wichtigste Engpass kann die Performance des Commit-Threads sein

Unser Stack

  • Einsatz von Common Lisp: bietet starke Unterstützung für Multithreading und eignet sich gut für Hot Reloading von Code
  • Einsatz von bknr.datastore und bknr.cluster: Für die Raft-Implementierung wird Baidus Braft-Bibliothek verwendet
  • Einsatz von EFS zur Speicherung von Bilddateien: Fehlerbehandlung und Tests sind einfacher als mit S3

Zusammenfassung

  • Diese Architektur eignet sich gut für neue Startups, und mit Common Lisp stehen bereits viele Werkzeuge bereit
  • Dank an die Mitwirkenden von bknr.datastore, Braft und Raft

GN⁺-Zusammenfassung

  • Dieser Artikel stellt eine neue Architektur zum Aufbau eines hochverfügbaren Web-Service ohne Datenbank vor
  • RAM wird als Datenbank verwendet, und Hochverfügbarkeit wird über den Raft-Konsensalgorithmus sichergestellt
  • Common Lisp unterstützt Multithreading und Hot Reloading von Code
  • Diese Architektur eignet sich für neue Startups und ermöglicht schnelle Entwicklung und Debugging
  • Projekte mit ähnlichen Funktionen sind unter anderem Redis und Memcached

1 Kommentare

 
GN⁺ 2024-08-11
Hacker-News-Kommentare
  • Es ist seltsam, ohne SQLite ein eigenes Transaktionslog zu bauen

    • Wenn die Daten auf einen Server passen, sollte man die Datenbank einfach auf diesem Server betreiben
    • Wenn die Daten in den RAM passen, ist es einfacher, ein ramdisk zu verwenden und mit Standardwerkzeugen in einen persistenten Speicher zu replizieren
  • Eine eigene In-Memory-Datenbank zu bauen, statt MySQL, Postgres, Redis, MongoDB usw. zu verwenden, ist komplex

    • Transaktionen müssen serialisiert und auf die Festplatte geschrieben werden
    • Das Transaktionslog zwischen Webservern muss synchronisiert und die In-Memory-Datenbank aktualisiert werden
    • Man muss einen Algorithmus zur Konfliktauflösung schreiben
    • Man muss Webserver nach Tenant sharden und eine Load-Balancing-Schicht schreiben
  • Die grundlegenden Aspekte von MySQL oder Postgres nicht lernen zu wollen, ist Zeitverschwendung

    • Beim Betrieb bei einem Public-Cloud-Anbieter lassen sich Nebenläufigkeitsprobleme oft schon mit dem Standard-Tuning lösen
    • 10 Millionen Zeilen hinzuzufügen ist kein großes Problem
    • Es ist klüger, zu warten und das Problem erst zu lösen, wenn wirklich eine schlechtere Situation eintritt
  • Das ähnelt der Architektur von HashiCorp Nomad, Consul und Vault

    • Die Developer Experience ist gut
    • Man kann den In-Memory-Status beliebig gestalten
    • Für neue Startups ist das nicht geeignet
    • Upgrades sind besonders schwierig
  • Es gibt den Irrglauben, dass RAM sehr billig ist

    • SSD- und vCPU-Leistung haben sich stark verbessert, aber RAM ist nicht wesentlich günstiger geworden
    • DRAM-Preise schwanken zyklisch und sind erst vor Kurzem etwas günstiger geworden
  • Ich habe schon ein Projekt gesehen, das Dateisystemverzeichnisse als Tabellen und JSON-Dateien als Zeilen verwendet hat

    • Redis, Mongo und Postgres wurden in Betracht gezogen, aber am Ende wurde eine eigene Datenbank gebaut
    • Es ist ineffizient, innovative Tokens für den Bau einer Datenbank zu verwenden
  • Die Verwendung einer relationalen Datenbank ist stabiler

    • Es gibt eingebaute Redundanz, Transaktionslogs, Backup- und Recovery-Funktionen
    • In den meisten Fällen ist es besser, eine Datenbank zu verwenden
  • Es wurde eine eigene Raft-Konsensschicht implementiert, um Komplexität zu vermeiden

    • Redis zu verwenden könnte einfacher sein
  • Moderne Desktop- und Mobile-Apps verwenden oft Datenbanken wie SQLite

    • Relationale Datenspeicherung und Abfragen sind nützlich
  • Eine eigene In-Memory-Datenbank zu bauen ist nicht einfacher, als Postgres oder SQLite zu installieren

    • SQL zu schreiben ist einfacher, als Code für Nebenläufigkeit zu schreiben