Jepsen: TigerBeetle 0.16.11
(jepsen.io)- 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_transfersu. 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
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.
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.
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.
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.
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“.
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.
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.