Dělení do oddílů
DocStore zapisuje jeden soubor pro každý záznam. Bez dělení by se všechny soubory velké kolekce hromadily v jediném adresáři a operace s adresářem by se s rostoucím počtem položek zpomalovaly. storh proto rozděluje soubory záznamů do skupin podle dvou znaků ID záznamu:
pages/data/2d/018bcfe5-6800-7000-8000-2d5dba6274da.jsonc
Skupina se určuje podle začátku UUID poslední části (znaky 24 a 25), která obsahuje náhodnou entropii. Dva hexadecimální znaky dávají 256 skupin, takže kolekce se 100 tisíci záznamy má v průměru méně než 400 souborů v adresáři.
Proč konec, a ne začátek
ID UUIDv7 začínají 48bitovým časovým razítkem v milisekundách, takže ID vytvořená krátce po sobě sdílejí počáteční znaky. Dělení podle předpony by každou dávku zápisů směrovalo do stejného vytíženého adresáře a skupiny by se měnily pouze s postupem času. Koncové bajty jsou pro každý záznam náhodné, takže zápisy se rovnoměrně rozloží hned od prvního záznamu.
Dělení do oddílů je při čtení i dotazování neviditelné: get() vypočítá skupinu z ID a stream() vrací záznamy seřazené podle ID napříč všemi skupinami, takže stránkování pomocí kurzoru funguje, jako by kolekce byla jediným seřazeným seznamem.
Ve velkém měřítku
Počet skupin nikdy neroste: dva hexadecimální znaky znamenají 256 adresářů bez ohledu na velikost kolekce. Roste počet souborů v každé skupině:
| Záznamy | Souborů ve skupině |
|---|---|
| 10k | ~40 |
| 100k | ~390 |
| 1M | ~3,900 |
| 10M | ~39,000 |
Moderní souborové systémy indexují položky adresářů, takže několik tisíc souborů ve skupině umožňuje rychlé vyhledávání jednotlivých záznamů; milion záznamů zvládají get() a dotazy využívající indexy bez problémů. Otevření úložiště má konstantní čas bez ohledu na velikost kolekce: osiřelé dočasné soubory se prohledávají jen tehdy, když značka po mrtvém zapisovači ukazuje, že předchozí proces havaroval uprostřed zápisu. Lineárně se s rozsahem zvětšují operace nad celou kolekcí: neindexovaná prohledávání, reindex() a verify() procházejí každý soubor záznamu, proto je berte jako dávkové úlohy. Přibližně nad 10 miliony záznamů v kolekci začíná záležet na počtu záznamů ve skupině i na celkovém využití inodů: rozdělte kolekce nebo pro data určená k prohledávání použijte segmentovaný protokol, který už svou konstrukcí udržuje počet souborů nízký.
Ostatní moduly
SegmentedLog a Queue nedělí data do oddílů, protože nevytvářejí jeden soubor pro každý záznam. Protokol přidává data do segmentových souborů v segments/, jejichž velikost je omezena hodnotou max_segment_bytes (výchozí hodnota je 1 MiB), a fronta přidává události do jediného queue.log. Počet souborů tak zůstává nízký už svou konstrukcí.