NEU: Helius übernimmt Light Protocol
Was ist RocksDB? Der eingebettete Schlüssel-Wert-Speicher
Blog/Engineering

Was ist RocksDB? Der eingebettete Schlüssel-Wert-Speicher

Developer Experience Engineer0xIchigo auf X0xIchigo auf LinkedIn0xIchigo auf GitHub
9 Min. Lesezeit

RocksDB gehört zu den meistgenutzten Speichersystemen, doch fast niemand konfiguriert es direkt. Es bildet die Grundlage für Kafka, MySQL über MyRocks, TiDB, YugabyteDB, Ceph und das Ledger der überwältigenden Mehrheit der Solana-Validatoren. 

Für eine derart tragende Technologie wird RocksDB überraschend selten ausführlich behandelt. 

Die offizielle Dokumentation eignet sich hervorragend als Referenz, aber kaum als Einstieg. Die meisten anderen Erklärungen setzen Vorwissen voraus, etwa darüber, was ein LSM-Baum ist.

Dies ist der erste Artikel einer Reihe über die interne Funktionsweise von RocksDB. Wir beginnen mit der naheliegenden Frage.

Was ist RocksDB?

RocksDB ist ein einbettbarer, persistenter Schlüssel-Wert-Speicher, der für schnelle Speicherung optimiert ist. Er akzeptiert Schlüssel und Werte als beliebige Byte-Arrays, hält sie sortiert und speichert sie dauerhaft auf der Festplatte. 

Das Wichtigste vorweg: RocksDB ist eine Bibliothek, kein Server. Es gibt keinen Prozess, zu dem du eine Verbindung aufbauen musst, keinen Port, den du öffnen musst, und keine Abfragesprache, die du lernen musst.

RocksDB wird in eine Anwendung integriert und läuft innerhalb ihres Prozesses. Dabei liest und schreibt es Dateien auf der lokalen Festplatte. Das macht RocksDB schnell: Zwischen Anwendungscode und den verarbeiteten Daten liegt kein Netzwerkzugriff. RocksDB bleibt minimalistisch, weil es Replikation, Sharding und Abfragen bewusst den darauf aufbauenden Systemen überlässt.

Einfach ausgedrückt ist RocksDB eine Speicher-Engine – die Komponente, um die Datenbanken wie TiDB und YugabyteDB herum aufgebaut sind.

Ist RocksDB dasselbe wie LevelDB?

Nein, aber beide stammen aus derselben Codebasis. RocksDB entstand 2012 als Fork von LevelDB, dem schlanken Schlüssel-Wert-Speicher, den Jeff Dean und Sanjay Ghemawat bei Google entwickelten. 

LevelDB wurde für überschaubare Umgebungen entwickelt, etwa als IndexedDB-Backend eines Browsers oder für ein einzelnes eingebettetes Gerät. Entsprechend fielen verschiedene Designentscheidungen aus: Single-Thread-Kompaktierung, sparsamer Speicherverbrauch und kaum Möglichkeiten zur Feinabstimmung.

Ingenieure bei Facebook, heute Meta, nahmen diese Grundlage und entwickelten sie für Server-Workloads weiter. Das Ziel war, moderne Hardware auszulasten und unter dauerhaftem Schreibdruck Datensätze zu verarbeiten, die den Arbeitsspeicher bei Weitem übersteigen. 

RocksDB wurde 2013 als Open Source veröffentlicht und hat sich seitdem stark von LevelDB entfernt. Hinzu kamen unter anderem Multi-Thread-Kompaktierung, Spaltenfamilien, Transaktionen, Backups, Merge-Operatoren, austauschbare Kompaktierungsverfahren und eine berüchtigt lange Liste von Tuning-Optionen.

LevelDB und RocksDB weisen noch eine gewisse Familienähnlichkeit auf. Sie als austauschbar zu betrachten, ist jedoch seit einem Jahrzehnt nicht mehr sinnvoll.

Wie funktioniert RocksDB?

RocksDB basiert auf einem logstrukturierten Merge-Baum (LSM-Baum). Diese Datenstruktur tauscht einfache Lesevorgänge gegen höheren Schreibdurchsatz ein. 

Im Wesentlichen landen eingehende Schreibvorgänge in einem In-Memory-Puffer namens memtable. Gleichzeitig werden sie zur dauerhaften Speicherung an ein Write-ahead-Log auf der Festplatte angehängt. 

Sobald die memtable voll ist, wird sie eingefroren und als unveränderliche, sortierte Datei auf die Festplatte geschrieben. Diese Datei heißt Sorted String Table (SST). SST-Dateien sammeln sich in einer mehrstufigen Hierarchie an. Ein Hintergrundprozess namens Kompaktierung führt sie kontinuierlich zusammen und entfernt dabei überschriebene Werte sowie gelöschte Schlüssel. So bleibt die Struktur aufgeräumt, sortiert und dauerhaft gespeichert.

Lesevorgänge prüfen zuerst die memtable und durchsuchen anschließend die verschiedenen Ebenen der SST-Dateien. Bloomfilter ermöglichen es RocksDB, Dateien zu überspringen, die den Schlüssel unmöglich enthalten können. Ein Block-Cache hält häufig verwendete Daten im Arbeitsspeicher. Daher greifen die meisten Lesevorgänge auf höchstens ein oder zwei Dateien zu.

Was ist der Unterschied zwischen LSM-Bäumen und B-Bäumen?

B-Bäume, die von den meisten traditionellen Datenbanken verwendet werden, aktualisieren Daten direkt an ihrer Position. Zufällige Schreibvorgänge verteilen sich dadurch über die Festplatte. LSM-Bäume hängen Daten an und verarbeiten sie in Batches. So entstehen große sequenzielle Schreibvorgänge, die sich ideal für SSDs und Workloads mit hoher Datenaufnahme eignen. Der Nachteil: Der aktuelle Wert eines Schlüssels kann sich über mehrere Dateien verteilen. Kompaktierung, Bloomfilter und Caching sind nötig, um diesen Nachteil zu begrenzen. 

Jede Designentscheidung in einem LSM-Baum wägt letztlich drei Belastungen gegeneinander ab:

  • Schreibverstärkung
  • Leseverstärkung
  • Speicherplatzverstärkung

Wer zwei davon verbessert, verschlechtert meist die dritte. 

Dieses Dreieck ist das wichtigste Denkmodell, um das Tuning von RocksDB zu verstehen. 

Wofür wird RocksDB verwendet?

RocksDB kommt überall dort zum Einsatz, wo eine Anwendung schnellen, dauerhaften und geordneten Schlüssel-Wert-Speicher auf einer lokalen Festplatte benötigt – ohne den Aufwand eines separaten Datenbankservers. Konkrete Beispiele verdeutlichen dieses Muster besser als Kategorien.

Kafka Streams speichert den Zustand jeder Verarbeitungsaufgabe – laufende Aggregationen, Joins und Fensterberechnungen – in einem lokalen RocksDB-Speicher. Dadurch kann der Zustand über den Arbeitsspeicher hinauswachsen und Neustarts überstehen, ohne dass jede Abfrage einen zusätzlichen Netzwerk-Roundtrip erfordert.

Metas ZippyDB ergänzt RocksDB um eine Replikationsschicht, Shard-Verwaltung und Konfigurationsdienste und bietet so einen vollständig verwalteten, verteilten Schlüssel-Wert-Speicher. Die Aufgaben sind klar getrennt: RocksDB stellt den Speicher bereit, während alle servertypischen Funktionen darum herum gebaut werden.

Die Speicherschicht von TiDB führt RocksDB auf jedem Node als Engine unterhalb einer verteilten SQL-Datenbank aus. Sie codiert die Tabellenstruktur in Schlüsselpräfixen, sodass das Scannen einer Tabelle zu einem einzigen zusammenhängenden Lesevorgang über sortierte Schlüssel wird.

Jeder auf Agave basierende Solana-Validator schreibt das Ledger in RocksDB. Die Daten werden nach Slot verschlüsselt, damit aufeinanderfolgende Ledger-Daten auf der Festplatte nebeneinanderliegen.

Die letzten beiden Beispiele sind interessant, weil Schlüssel sortiert gespeichert werden – standardmäßig byteweise oder anhand eines benutzerdefinierten Vergleichsoperators. Dadurch sind Bereichsscans und Präfixsuchen effizient.

Ein überraschend großer Teil des Schemadesigns realer Systeme auf Basis von RocksDB läuft darauf hinaus, diese Sortierung auszunutzen.

Wer verwendet RocksDB?

Neben den oben genannten Systemen ist RocksDB die Grundlage für alle Systeme, die eine eingebettete, praxiserprobte und für Schreibvorgänge optimierte Speicher-Engine benötigen. Teams entscheiden sich dafür, weil sie von einem Jahrzehnt Produktionshärtung bei Meta profitieren, statt eine solche Engine von Grund auf selbst zu entwickeln.

Besonders erwähnenswert:

RocksDB wird hauptsächlich für schreibintensive Workloads eingesetzt, die größer als der Arbeitsspeicher sind und auf SSDs laufen. Darauf kommen wir später in diesem Artikel zurück.

Wie verwendet Solana RocksDB?

Solana ist eine leistungsstarke Proof-of-Stake-Blockchain mit niedriger Latenz, die für ihren Fokus auf Geschwindigkeit, Effizienz und Endnutzeranwendungen bekannt ist. Das Ledger von Solana befindet sich in RocksDB. Der Agave-Validator-Client speichert das Ledger im Blockstore. Diese Komponente enthält eine RocksDB-Datenbank, die in unabhängige, konfigurierbare Schlüsselräume unterteilt ist. 

Separate Spaltenfamilien enthalten Shred-Daten und Shred-Erasure-Coding – also die rohen Einheiten der Ledger-Daten, wie sie über das Netzwerk eintreffen –, Transaktionsstatus, Adress-zu-Signatur-Indizes und verschiedene Metadaten.

Das Schreibmuster eines Validators ist im Vergleich zu den meisten Datenbank-Workloads extrem. Ein Validator muss Shreds kontinuierlich und mit voller Netzwerkgeschwindigkeit aufnehmen, und zwar für immer. Als Schlüssel dienen Slot-Nummern, die fast monoton ansteigen. Ein unbeschnittenes Archiv des Ledgers ist deutlich größer als einige Hundert Terabyte und wächst jedes Jahr um mindestens mehrere Dutzend Terabyte.

Bei gestufter Kompaktierung erzeugten die Shred-Spaltenfamilien so viel Hintergrundarbeit, dass Validatoren zunehmend auf Schreibpausen stießen. Mit diesem integrierten Mechanismus verlangsamt RocksDB die Datenaufnahme, wenn die Kompaktierung nicht mehr nachkommt. 

Um 2021 wurden die Shred-Spaltenfamilien auf FIFO-Kompaktierung umgestellt. Dieses minimalistische Verfahren löscht einfach die älteste Datei, sobald die Größenobergrenze erreicht ist. Für allgemeine Workloads ist FIFO normalerweise unsicher. Da Shred-Schlüssel jedoch in nahezu monotoner Slot-Reihenfolge eintreffen, konnten Validatoren die älteste Datei löschen, weil sie die ältesten Slots enthielt. Damit passte das Kompaktierungsverfahren fast perfekt zur Form des Workloads.

Spätere Optimierungen an der gestuften Kompaktierung reduzierten ihre I/O-Verstärkung so weit, dass FIFO keine Vorteile mehr bot. Deshalb wurde der FIFO-Pfad im Juni 2024 als veraltet markiert und im November desselben Jahres entfernt.

Firedancer, der in C geschriebene Solana-Validator-Client von Jump Crypto, verzichtet vollständig auf RocksDB und verwendet stattdessen eine eigens entwickelte interne Speicherschicht.

Ob eine von Grund auf neu entwickelte Speicher-Engine ein Jahrzehnt an Härtung und Optimierung von RocksDB übertreffen kann, bleibt eine interessante offene Frage im Validator-Engineering.

Wann ist RocksDB das falsche Werkzeug?

RocksDB ist häufiger das falsche Werkzeug, als seine weite Verbreitung vermuten lässt. Die Tuning-Möglichkeiten sind enorm: Hunderte Optionen beeinflussen sich auf schwer erkennbare Weise. Eine falsche Konfiguration ist daher eher die Regel als die Ausnahme. 

Erschwerend kommt hinzu, dass die Standardeinstellungen von RocksDB zwar vernünftig, aber nicht optimal sind. Entwickler müssen die oben beschriebenen Zielkonflikte bei der Verstärkung verstehen, um echte Leistungsgewinne zu erzielen. Eine dauerhaft hohe Datenaufnahme kann die Hintergrundkompaktierung überholen und Schreibpausen auslösen, die meist dann auftreten, wenn das System am stärksten ausgelastet ist.

Außerdem ist RocksDB eine Bibliothek und kein Server. Alles, was ein typischer Datenbankserver bereitstellt – etwa Replikation, Sharding, Backups, Zugriffskontrolle, eine Abfrageschicht und Betriebswerkzeuge –, muss selbst entwickelt werden.

Auch die Form des Workloads spielt eine entscheidende Rolle. 

RocksDB ist eine zeilenorientierte Engine für Punktabfragen und Bereichsscans. Für analytische Workloads, die große Datenbereiche scannen und spaltenübergreifend aggregieren, eignet sich ein spaltenorientierter Speicher wie ClickHouse besser.

All das ist kein Grund, RocksDB zu meiden. Es ist vielmehr ein Grund, sich bewusst dafür zu entscheiden. Wir bei Helius haben diese Risiken direkt bewertet, als wir unsere Archivierungsschicht neu konzipierten und uns dennoch für RocksDB entschieden. Der Workload entsprach genau dem Muster, für das RocksDB entwickelt wurde: Punktabfragen und eng begrenzte Bereichsscans über einen großen Datensatz, an den überwiegend Daten angehängt werden. 

Fazit

RocksDB ist ein einbettbarer, persistenter und sortierter Schlüssel-Wert-Speicher, der betriebliche Annehmlichkeiten gegen maximale Leistung auf lokalen Festplatten eintauscht. RocksDB entstand aus LevelDB, wurde bei Meta für SSDs und Mehrkernsysteme gehärtet und steckt heute weltweit in zahlreichen Systemen – von Stream-Prozessoren und verteilten SQL-Datenbanken bis zu Speicherclustern und dem Ledger von Solana.

Wenn dich die Arbeit an leistungsstarken RocksDB-Setups im großen Maßstab reizt, entwickle sie mit uns.

Solana ist auf dem Weg, zur Abwicklungsschicht für das globale Finanzwesen zu werden. Die zugrunde liegende Infrastruktur basiert genau auf der Technologie, die diese Artikelreihe beschreibt. Löse anspruchsvolle Systemprobleme auf einigen der besten Hardwareplattformen, die man kaufen kann – in planetarem Maßstab.

Wir stellen in unserem gesamten Engineering-Team ein. Alle offenen Stellen findest du unter helius.dev/careers.

Helius abonnieren

Bleib bei der Solana-Entwicklung auf dem Laufenden und erhalte Updates, wenn wir neue Beiträge veröffentlichen