1 Punkte von GN⁺ 2025-06-07 | 1 Kommentare | Auf WhatsApp teilen
  • TigerBeetle ist eine auf doppelte Buchführung spezialisierte OLTP-Datenbank, die mit dem Ziel von Sicherheit und hoher Verarbeitungsgeschwindigkeit entwickelt wurde
  • Sie unterstützt das Konsensprotokoll Viewstamped Replication und strong serializability und ist strukturell für hoch umkämpfte, durchsatzintensive Workloads optimiert
  • Design und Testverfahren legen großen Wert auf Fehlertoleranz und Resilienz bei Störungen und zielen auf einen Betrieb ohne Datenverlust in unterschiedlichsten Ausfallsituationen ab
  • Jepsen-Tests fanden verschiedene Bugs und Performance-Probleme bei Upgrades, Tests, dem Operationsmodell und der Ausfallresilienz von Clustern; die Reaktionsfähigkeit darauf wurde verbessert
  • Die neueste Version bringt mehrere Verbesserungen und Bugfixes bei ringbasierter Replikationsleistung, Client-Fehlerbehandlung sowie Logging- und Query-Korrektheit

Einführung in TigerBeetle

  • TigerBeetle ist eine auf Double-entry bookkeeping spezialisierte Online Transaction Processing (OLTP)-Datenbank
  • Sie garantiert strong serializability auf Basis des Konsensprotokolls Viewstamped Replication (VR) und speichert nur Daten zu Konten und Transfers zwischen Konten
  • Sie eignet sich für Umgebungen mit hohem Transaktionsvolumen und starker Konkurrenz bei gleichzeitigen Zugriffen, etwa interne Bankswitches, Brokerage, Ticketing oder Strommessung
  • Die Architektur sieht vor, dass ein einzelner Node (Core) alle Schreiboperationen steuert, und fokussiert sich daher nicht auf horizontale Skalierung (Scale-out), sondern auf vertikale Skalierung (Scale-up)
  • Mit hardwarefreundlichen Optimierungen wie Batch-Verarbeitung, IO-Parallelisierung und festem Schema zielt sie auf maximalen Durchsatz pro Einzelknoten ab

Ausfallresilienz und Fehlertoleranz

  • TigerBeetle bietet explizite Modelle und Wiederherstellungsverfahren für Fehler in Speicher, Prozessen, Uhren, Storage und Netzwerk
  • Die Datendauerhaftigkeit garantiert keinen Datenverlust, solange auch nur eine einzige Replik überlebt
    • Wenn Aufzeichnungen in allen Repliken beschädigt sind, stoppt das System sicher
  • Es werden verschiedenste Störungen angenommen, darunter Hardware-/Software-Ausfälle, Uhrabweichungen, Plattenschäden sowie Netzwerklatenz, -verlust und -duplikation
  • Eingesetzt werden Viewstamped Replication, Protocol-Aware Recovery, Checksummen für Datenblöcke und Speicherung über mehrere Repliken hinweg
  • Durch Laufzeitvalidierung (assertion) werden Schäden bei Fehlern und Bugs minimiert

Upgrade-Verfahren

  • Das Binary enthält Code der aktuellen Version und mehrerer früherer Versionen
  • Ein Upgrade ist möglich, indem einfach das Binary ersetzt wird
  • Alle Nodes im Cluster wechseln automatisch per Rolling-Upgrade die Version, bei minimalem Eingriff durch Nutzer
  • Indem verhindert wird, dass in einer bestimmten Version commitete Operationen in einer anderen Version doppelt committed werden, hilft das Verfahren Zustandsabweichungen zu vermeiden

Zeitmodell

  • Verwendet werden zugleich logische Uhren anhand von VR-Views und Operationsnummern sowie hybride physische Uhren (physical time)
  • Der Leader sammelt die POSIX-Zeit aller Repliken und synchronisiert den Cluster gegenseitig innerhalb einer Fehlertoleranz
  • Wenn die Uhrsynchronisierung länger als 60 Sekunden fehlschlägt, wird der Dienst verweigert
  • Zeitstempel sind in „Nanosekunden seit der Unix-Epoche“ angegeben, weichen aber um 27 Sekunden von der tatsächlichen POSIX-Zeit ab
  • Bei Schaltsekunden oder negativen Zeitanpassungen verlangsamt sich die interne Uhr

Datenmodell

  • Unterstützt werden nur zwei Datentypen: Konten (account) und Transfers (transfer)
    • Jedes Feld hat feste Größe, folgt dem Prinzip der Unveränderlichkeit (immutable) und basiert auf unsigned ints
  • Konten sind definiert durch benutzerdefinierte 128-Bit-IDs, Ledger, Flags, Erstellungszeitpunkt und Custom Fields
  • Transfers enthalten unter anderem debit/credit account id, code, amount und Custom Fields
  • Transfers werden sowohl zur sofortigen Ausführung (einstufig) als auch als zweistufige Verarbeitung (Reservierung/Ausführungsverhandlung) unterstützt
    • Reservierte Transfers (pending) können storniert oder ablaufen gelassen werden
    • Spezielle Transfers können zum Schließen und Wiederöffnen von Konten verwendet werden

Operationsmodell und Transaktionen

  • Clients arbeiten in Form eines einzelnen Request-Batches zur Aktualisierung oder Abfrage des Datenzustands
  • Jedes Ereignis innerhalb eines Requests wird sequenziell und als atomare Transaktion verarbeitet
  • Wiederholte Ausführung, requestübergreifende Transaktionen und interaktive Queries werden nicht unterstützt
  • Es werden Strong Serializability und starke Session-Konsistenz geboten
  • Unterstützt werden Erfolg/Misserfolg jeder Operation, Rückgabe von Fehlercodes sowie komplexe Verarbeitung über Chains (Subtransaktionen)

Aufbau der Jepsen-Tests

  • Mit der Jepsen-Bibliothek wurden property-based Tests und Fault Injection durchgeführt
  • Experimente liefen auf 3- bis 6-Node-Clustern in unterschiedlichen Umgebungen wie LXC und EC2
  • Wegen der Einschränkungen des Datenmodells war eine Konsistenzprüfung im Stil klassischer Listen oder Sets schwierig → daher wurde die gesamte Operationsreihenfolge (total order) zur Prüfung von Zustands- und Zeitkonsistenz genutzt
  • Fehler wurden durch sich ergänzende Verfahren wie timestampbasierte Konsistenzchecks, Modellvalidierung und Simulation erkannt

Modellvalidierung und Erzeugung von Operationen

  • Mit einem Single-Thread-State-Machine-Modell von über 1600 Zeilen wurde die Korrektheit des TigerBeetle-Verhaltens detailliert geprüft
  • Unterschiedliche Fehlerbedingungen wie doppelte IDs, unstetige Zeitstempel, Kontostandsrestriktionen und verlinkte Chains wurden mit Inferenz- und Rollback-Verarbeitung behandelt
  • Zur effizienteren Validierung kamen verschiedene Verfahren zum Einsatz, etwa die Erzeugung von Operations- und ID-Werten, Zustandsupdates und probabilistische Query-Kombinationen

Fault Injection

  • Enthalten sind grundlegende Fehlerszenarien wie Prozessabstürze (SIGKILL), Pausierung (SIGSTOP), Netzwerkpartitionen und Uhränderungen
  • Hinzu kommen feingranulare Storage-Fehlerinjektionen wie Versionsupgrades, Simulation beschädigter Dateien und partielle Schäden nur in einzelnen Repliken
  • Mit unterschiedlichen Szenarien wie zigzag- bzw. helical-Datenträgerbeschädigung wurde geprüft, ob sich die Möglichkeit von Datenverlust minimieren lässt

Wichtige Bug-Beispiele und Verbesserungen

Probleme bei der Behandlung von Request-Timeouts (#206)

  • Nach dem Design von TigerBeetle laufen Client-Requests niemals in ein Timeout; sie werden unendlich oft wiederholt, bis eine Antwort vom Cluster kommt
  • In der Praxis können Clients wie Java bei asynchronen Operationen dennoch Timeout-Ausnahmen auslösen, und Anwendungen haben kaum eine andere Wahl als externe Timeouts zu setzen
  • Weil das Design Netzwerkfehler oder eindeutige Fehler auf uneindeutige Weise verbirgt, ist es schwierig, klare Fehler von ungewissen Fehlern zu unterscheiden
  • Jepsen empfahl unterschiedliche Rückgabemethoden je Fehlertyp (sicher/unsicher) sowie zusätzliche Retry-Optionen

JVM-Absturz durch Client-Fehler (#2435)

  • Thread-/Asynchronitäts-Wrapper zur Umgehung von Timeouts lösten ein JVM-Segfault-Problem aus
  • Ursache war die Referenz auf nicht korrekt initialisierte Felder im Java-Client; behoben in 0.16.12

Client-Absturz bei Session-Ablauf (#2484)

  • Erzwungene Client-Beendigung durch übermäßige Sessions
  • Ab 0.16.13 wurde dies auf Fehler-Rückgaben umgestellt

Sprunghafter Anstieg der Latenz bei Ausfall eines einzelnen Nodes (#2739)

  • Eine Schwäche der ringbasierten Replikation führte dazu, dass bei Ausfall einzelner Nodes die Gesamtantwortzeit extrem anstieg
  • Ursache: Standardmäßig sendet der Primary Nachrichten schrittweise an den nächsten Node; fällt ein Node aus, wartet das System wegen ausbleibender ACKs
  • Seit 0.16.30 sorgen umgekehrte Replikation und dynamische Ring-Topologie für deutlich geringere Antwortverzögerungen bei Ausfällen

Bug in der Header-API des Java-Clients (#2495)

  • Bei leeren Response-Batches wurde ein Singleton-Objekt verwendet, wodurch Header und Zeitstempel fälschlich gemeinsam genutzt wurden
  • Die Datengenauigkeit war nicht betroffen, aber die Ergebnisse der Header-API wurden verfälscht; behoben in 0.16.14

Fehlende Query-Ergebnisse (#2544)

  • In Version 0.16.13 wurde ein Bug gemeldet, bei dem in query_accounts, query_transfers u. a. ein Teil der Ergebnisse fehlte; die Antwort war fälschlich nur auf ein korrektes Prefix begrenzt

Fazit

  • TigerBeetle ist auf Umgebungen im Finanz- und Rechnungswesen mit hohen Anforderungen an Sicherheit und Fehlertoleranz spezialisiert
  • Die Jepsen-Testreihe legte verschiedenste Themen bei Resilienz, Konsistenz, Operationsmodell und Performance offen
  • Durch aktive Zusammenarbeit wurden spürbare Verbesserungen bei Ausfallresilienz, Client-Fehlerbehandlung sowie Replikations- und Upgrade-Automatisierung erreicht
  • In der neuesten Version bietet das System eine noch robustere Reaktion auf Ausfälle, verlässlichere Verbindungs- und Antwortgarantien sowie hohe Konsistenz bei Operationen

(Ein Teil dieses Inhalts wurde unter Bezug auf verschiedene Open-Source-Quellen wie GitHub, die offizielle TigerBeetle-Dokumentation und Jepsen-Testberichte erstellt.)

1 Kommentare

 
GN⁺ 2025-06-07
Hacker-News-Kommentare
  • Auch der Artikel „Fuzzer Blind Spots (Meet Jepsen!)“ sei als Hintergrundinfo lesenswert, mit Hinweis auf https://tigerbeetle.com/blog/2025-06-06-fuzzer-blind-spots-meet-jepsen/

  • Es wird die Erfahrung geteilt, Aussagen über die Zuverlässigkeit und Skalierbarkeit von TigerBeetle am Ende immer durch den Jepsen-Bericht zu verifizieren. Positiv bewertet wird, dass im aktuellen Bericht mehrere Probleme gefunden wurden, diese schnell behoben wurden und zugleich die interne Test-Suite verstärkt wurde, damit ähnliche Bugs künftig nicht wieder auftreten. Mit dieser Haltung könne TigerBeetle in zehn Jahren im Bereich finanzspezifischer Datenbanken vielleicht den Status einer Standardempfehlung à la „nimm einfach Postgres“ erreichen. Außerdem wird bestätigt, wie viel man durch aphyrs hervorragende Arbeit lernen könne.

    • TigerBeetle verfüge über mehr als 6.000 Assertions; einige davon seien übermäßig strikt und hätten teilweise selbst Crashes ausgelöst, aber genau dadurch hätten sie als Warnmechanismus wie beabsichtigt funktioniert. Tatsächlich sei nur ein kleiner Correctness-Bug in einer internen Testfunktion für die bequemere Jepsen-Prüfung auf Java-Client-Seite aufgetreten sowie ein Correctness-Bug ohne Auswirkungen auf die Durability, den Jepsen gefunden habe. Die Details dazu würden unter diesem Link erklärt. TigerBeetle werde so entworfen und getestet, dass es mehr Ausfälle als Postgres aushalte, nutze ein explizites Storage-Failure-Modell, berücksichtige Forschungsergebnisse, die es zur Zeit der Veröffentlichung von Postgres noch nicht gab, und setze auf Deterministic Simulation Testing sowie NASA-Standards für sicherheitskritischen Code und weitere Maßnahmen zur Stabilitätsgarantie. Für in der Literatur klar dokumentierte Postgres-Szenarien mit Datenverlust könne TigerBeetle in der Praxis Erkennung und Recovery bieten. Für mehr Details wird auf Kyles Abschnitt über helical fault injection oder den QCon-London-Vortrag als Video verwiesen.
    • Jedes Mal, wenn man Kyles Bericht lese, habe man das Gefühl, in verteilten Systemen eine Stufe besser zu werden.
  • Es wird Freude darüber geäußert, dass TigerBeetle von aphyr geprüft wurde und seine Versprechen einhält; darin liege die Hoffnung, dass der richtige Ansatz tatsächlich zu den richtigen Ergebnissen führen könne. In der Praxis lägen Daten außerhalb von Account oder Transfer jedoch oft in externen Systemen und separaten Datenbanken. Deshalb wird gefragt, wie Konsistenzprobleme oder Recovery zwischen solchen weniger vertrauenswürdigen externen Systemen und TigerBeetle in der Praxis gelöst würden.

    • Zoran von TigerBeetle erklärt Integrationsmuster und empfiehlt generell eine getrennte Architektur aus control plane (allgemeines OLGP, z. B. Postgres) und data plane (OLTP, z. B. TigerBeetle). Benutzerinformationen und Ähnliches lägen in OLGP als „Aktenschrank“, Transaktionsdaten (Bestand → Warenkorb → Zahlung usw.) in OLTP als „Tresor“. Pro Konto oder Transfer könnten bis zu drei Benutzer-Datenkennungen verknüpft und mit OLGP-Entitäten sowie Events verbunden werden. Diese Trennung biete Vorteile bei unabhängiger Skalierung, Betrieb und Verwaltung. Gerade bei Beispielen wie Banken sei die Trennung von Geld (Tresor) und Informationen (Aktenschrank) sinnvoll. Da die Häufigkeit realer Transaktionen und die Änderungsfrequenz von Informationen wie Name oder E-Mail unterschiedlich seien, sei diese Struktur plausibel. Für Datenkonsistenz werde auf dem Write-Pfad empfohlen, abhängige Daten zuerst in OLGP (und nötigenfalls externem Storage wie S3) zu schreiben und erst zuletzt in TigerBeetle zu committen. Auf dem Read-Pfad solle TigerBeetle stets als source of record abgefragt werden, um durch strict serializability Vertrauen sicherzustellen. Verlinkt wird die Architekturdokumentation.
  • Wer den Jepsen-Post über Fuzzer-Blindspots gelesen habe, finde den aktuellen TigerBeetle-Bericht noch interessanter. Der Fall eines Segfaults auf JNI-Seite würde zwar auch bei speichersicheren Sprachen wie Rust nicht unbedingt verhindert, aber der Zig-/TigerStyle-Ansatz von TigerBeetle liefere eine gute Demonstration in Sachen Speichersicherheit.

    • Es wird ein Beispiel für einen Bug genannt, gegen den man sich auch in Rust hätte absichern können; in der Praxis werde der Großteil jedoch bereits durch Assertions verhindert. Ohne TigerStyle hätte die Situation gefährlicher werden können.
  • Für den Einfallsreichtum des Abschnittstitels „Panic! At the Disk 0“ gibt es leichten, anerkennenden Golfapplaus.

  • Es wird tiefer Eindruck über den diesmal sehr detaillierten, Jepsen-zertifizierten Bericht geäußert. Obwohl v1.0 noch nicht veröffentlicht ist, seien die Erwartungen bereits hoch. Zusätzlich wird gelobt, dass die Gründer im Thread aktiv Einsichten teilen.

    • Auch Kyles Detailgenauigkeit und die fast künstlerische Sorgfalt des Berichts werden hervorgehoben; außerdem freue man sich auf neue Vorträge bei der SD25 Amsterdam.
  • Im Testen verteilter Systeme sei interessant, dass für eine präzise Verifikation im Grunde vorausgesetzt werde, dass das System selbst die interne Reihenfolge bzw. Zeitpunkte meldet, damit sie exakt mit einem externen Modell abgeglichen werden können; das wirke zugleich „offensichtlich selbstverständlich“.

    • In einer strict-serializability-Umgebung sei ein solcher Ansatz möglich, unter schwächeren Konsistenzgarantien dagegen nicht, weil dann keine einzelne globale Timeline existiere. Interessant sei das Meta-Muster, dass ein schwierigeres Problem paradoxerweise zu einem einfacheren System führen könne. Wenn man etwa ein Protokoll für Disk-Ausfall und Recovery grundlegend einführe, bekomme man auch den State-Sync langsamer Replikas gewissermaßen „gratis“ dazu.
  • Nach Durchsicht des Jepsen-Berichts, des zugehörigen Blogposts und des Antithesis-Integrationscodes wird mit Lernabsicht nach Umfang und Wirksamkeit der Tests gefragt. Es sei bekannt, dass TigerBeetle bereits umfassend mit Antithesis teste; daher sei unklar, warum ein von Jepsen gefundener Bug dort nicht entdeckt wurde. Konkret wird nach den Unterschieden zwischen Antithesis- und Jepsen-Tests sowie letztlich auch zur internen Testabdeckung gefragt.

    • aphyr ergänzt, dass generatives Testen verteilter Systeme drei Elemente erfordere: 1) die Ausführungsumgebung des Systems, 2) einen Load-Generator und 3) einen Auditor. Antithesis decke hauptsächlich Punkt 1 ab, also die deterministische Simulationsumgebung. Jepsen arbeite mit echten Maschinen und Fehler-Injektion auf OS-Ebene. TigerBeetles VOPR betreibe den gesamten Cluster innerhalb eines einzelnen Threads. Die verschiedenen Simulationsansätze ergänzten sich in ihren Vor- und Nachteilen. Beim aktuellen Bug seien letztlich vor allem 2) und 3) entscheidend gewesen, also Workload-Erzeugung und verifizierender Auditor. Aphyrs speziell auf TigerBeetle zugeschnittener Clojure-Code habe diesen Bug ausgelöst und erkannt; danach sei auch ein internes Äquivalent gepatcht worden. Dabei habe sich gezeigt, dass das kritischere Problem weniger in der Datenbank selbst als in VOPR lag. In verteilten Datenbanken seien Bugs immer möglich; grundlegend wichtig sei daher das Design mehrerer Generatoren und Teststrategien.
    • Auch im Blog von TigerBeetle werde das Problem im Detail beschrieben. Kurz gesagt habe der in Antithesis verwendete Test die für diesen Bug nötige Kombination aus Cross-Querys und out-of-order-Werten nicht abgedeckt und ihn deshalb übersehen, während Jepsen genau diese Kombination erzeugt und den Fehler dadurch erkannt habe. Zugleich wird betont, dass auch der Test-Generator von Jepsen gewisse Grenzen habe und daher verschiedene Generator-Designs nötig seien.
    • 90 % der internen Latenz-Simulationstests liefen in VOPR, dem eigenen Simulator, der mit 1.000 CPU-Kernen rund um die Uhr betrieben werde. Antithesis diene als zusätzliche Schicht. Warum der Query-Engine-Bug durchgerutscht sei, werde in diesem Beitrag erklärt.
  • Jemand sagt, er interessiere sich für TigerBeetle, wundere sich aber darüber, dass in der Client-Dokumentation kein C- oder Zig-Client auftauche. Da das Projekt selbst in Zig geschrieben sei, wird gefragt, ob ein solcher Client nicht existiere oder noch in Entwicklung sei.

  • Es wird gefragt, ob TigerBeetle bereits bei großen Banken oder Brokerhäusern im Einsatz sei.

    • Zoran von TigerBeetle antwortet, dass das System derzeit in Zusammenarbeit mit der Gates Foundation für den Aufbau des nationalen digitalen Zahlungssystems 2.0 und einer elektronischen Zentralbank in Luanda genutzt werden solle. Im Enterprise-Bereich laufe es bereits produktiv bei Kunden mit über 100 Millionen Transaktionen pro Monat. Kürzlich sei zudem ein Vertrag mit einem europäischen Fintech-Unicorn im Umfang von 2 Milliarden US-Dollar geschlossen worden, und in den USA liefen weitere Vertragsabschlüsse. Weltweit steige der Bedarf an TigerBeetle wegen der Nachfrage nach Echtzeit-Transaktionsverarbeitung. Auch die Gründer von Clear Street, einem bedeutenden mittelgroßen Brokerage an der Wall Street, hätten investiert. Als weiterführende Links werden mojaloop.io, der Blog von TigerBeetle und die Unternehmensseite genannt.
    • Zwar nicht bei einer großen Bank oder Börse, aber man selbst setze TigerBeetle in einem großen Fintech bereits für ein neues Produkt ein.
    • Da TigerBeetle nicht offensiv mit Referenzkunden werbe, werde vermutet, dass es keine bekannten großen Namen gebe; derzeit wirke die Empfehlung eines einflussreichen YouTubers als die größte öffentliche Bestätigung.