cobalt

Wbudowany magazyn klucz–wartość typu LSM w Zig. Świeże zapisy trafiają do skiplisty na WAL, są zrzucane do niezmiennych SSTable, a miejsce odzyskuje leveled-compaction.

cobalt
TL;DR

Wbudowany magazyn klucz-wartość typu LSM w Zig. Świeże zapisy trafiają do skiplisty na dzienniku WAL, potem są zrzucane do niezmiennych SSTable, a miejsce odzyskuje leveled-compaction. To fundament, na którym stoją nowoczesne bazy danych.

Wprowadzenie

Nowoczesne bazy danych, których używasz na co dzień, prawie zawsze mają pod spodem ten sam kształt silnika. cobalt jest po to, żeby ten kształt przestał być czarną skrzynką: implementuje całą drogę zapisu typu LSM od dziennika po compaction, w Zig, języku, który nie ukrywa przed tobą ani jednego bajta ani alokacji.

To nie jest kolejna baza do produkcji, tylko rozebrany na części silnik, w którym widać każdą decyzję. Kiedy sam napiszesz WAL, memtable, SSTable i compaction, RocksDB i Cassandra przestają być magią, a stają się znajomymi wariantami tej samej idei.

Dlaczego LSM, a nie B-drzewo

Klasyczne bazy zapisują w miejscu, aktualizując strony B-drzewa, co oznacza losowe zapisy po dysku. LSM idzie inaczej: każdy zapis jest dopisaniem. Nowe dane lecą do struktury w pamięci, a starsze warstwy leżą niezmienne na dysku. Dzięki temu zapisy są szybkie i sekwencyjne, bo dysk najbardziej lubi właśnie zapis ciągły.

Cena jest jasna i świadoma: te same dane mogą istnieć w kilku miejscach naraz i trzeba je później scalać. Cała sztuka LSM polega na tym, żeby ten dług zapłacić w tle, nie spowalniając zapisów, które go tworzą.

Droga zapisu, krok po kroku

1
WAL

zapis najpierw ląduje w dzienniku, więc przeżyje nagłe wyłączenie, zanim trafi gdziekolwiek indziej.

2
Skiplista

świeże dane siedzą w posortowanej strukturze w pamięci, gotowe do szybkiego odczytu.

3
SSTable

gdy pamięć się zapełnia, skiplista jest zrzucana do niezmiennego, posortowanego pliku na dysku.

4
Compaction

leveled-compaction scala pliki między poziomami, usuwa nadpisane wersje i odzyskuje miejsce.

Kolejność tych kroków nie jest przypadkowa. WAL idzie pierwszy właśnie dlatego, że gwarantuje trwałość, zanim dane dotrą do ulotnej pamięci. Gdyby kolejność była odwrotna, awaria zasilania między zapisem do pamięci a dziennikiem oznaczałaby ciche zgubienie danych.

Compaction to serce, które odróżnia działający LSM od takiego, który z czasem się dławi. Bez niej pliki SSTable narastają w nieskończoność, a odczyt musi przejrzeć coraz więcej warstw. Leveled-compaction scala je między poziomami, wyrzucając po drodze wersje, które zostały nadpisane, i odzyskując miejsce zajęte przez martwe dane.

i
Informacja

Ten sam kształt silnika, WAL plus memtable plus SSTable plus compaction, znajdziesz w RocksDB, LevelDB i Cassandrze. Różnica między nimi to głównie strojenie tych samych klocków, a nie inna architektura.

Koniec czarnej skrzynki

Największym efektem cobalt nie jest sam magazyn, tylko to, że duże bazy przestają być tajemnicą. Kiedy przeszedłeś całą drogę od dopisania do dziennika po odzysk miejsca w compaction, wiesz dokładnie, dlaczego LSM jest szybki w zapisie i gdzie płaci za to cenę w odczycie.

Warstwy silnika i gdzie jeszcze żyją

WarstwaRolaGdzie jeszcze
WALtrwałość zapisukażda poważna baza
Memtable (skiplista)świeże dane w pamięciRocksDB, LevelDB
SSTableniezmienne pliki na dyskuCassandra, LevelDB
Compactionodzysk miejsca, scalanieRocksDB, Cassandra

Więcej projektów

Inne realizacje z tej samej kategorii - zobacz, jak podchodzimy do podobnych wyzwań.

Masz podobny projekt?

Napisz do nas - wycena jest bezpłatna i wraca w godzinę.