Preskočiť na obsah

Nástroje

Výber nástroja

Všetky tri nástroje ukladajú to isté: ID UUIDv7 a pole údajov, ale na disku ich usporadúvajú odlišne. Toto usporiadanie určuje, na čo sa každý nástroj hodí:

DocStore SegmentedLog Queue
Na disku jeden súbor JSONC na záznam, rozdelený podľa koncových znakov UUID segmenty iba na pridávanie, pričom každý riadok JSON má predponu s dĺžkou a kontrolným súčtom, plus manifest jeden protokol udalostí, do ktorého sa iba pridáva
Zápis atomická náhrada súboru pri každom zázname pridania s kontrolným súčtom; prepísania a odstránenia pridávajú nové položky, uvoľnené miesto získava compact() pridanie s kontrolným súčtom pri každej udalosti frontu
Čítanie get() podľa ID, indexované dopyty prechádzanie kurzorom a podľa časového rozsahu, get() cez stavový index claim() v poradí zaradenia do frontu
Vhodné najmä na priame čítanie a indexované vyhľadávanie v kolekcii ľubovoľnej veľkosti prúdy s častým pridávaním, približne do 1M záznamov spoľahlivé odovzdávanie práce medzi procesmi
Slabá stránka prechádzanie polí bez indexu pri viac než približne 10k záznamoch časté prepisovanie jednotlivých záznamov (staré verzie zaberajú miesto až do kompakcie) nejde o všeobecné úložisko záznamov; po dokončení úlohy sa jej dátový obsah zahodí

DocStore a SegmentedLog používajú rovnaký plynulý dopyt API: rovnaký reťazec where() funguje v oboch nástrojoch a líši sa iba vykonanie. DocStore dokáže odpovedať pomocou sekundárnych indexov, zatiaľ čo SegmentedLog filtruje pri prechádzaní segmentov. Queue používa nárokovanie, nie dopytovanie: pracovníci claim() ďalšiu úlohu namiesto filtrovania úloh.

Praktické pravidlá:

  • Záznamy, ktoré načítavate, aktualizujete alebo odstraňujete jednotlivo a vyhľadávate podľa poľa: DocStore. Pridajte indexy pre polia, podľa ktorých filtrujete.
  • Udalosti alebo verzie, ktoré väčšinou pridávate a čítate späť v poradí alebo podľa časového okna: SegmentedLog.
  • Úlohy odovzdávané producentmi pracovným procesom: Queue. Nárokovanie a dokončovanie sú bezpečné pri viacerých procesoch a claimMany()/completeMany() rozkladajú náklady na zámky a fsync.
  • Spájanie, vyhľadávanie alebo vykazovanie nad ľubovoľnou kolekciou: pridajte zrkadlo SQL. Súbory zostávajú autoritatívne; zrkadlo je projekcia, ktorú možno znova zostaviť v SQLite alebo MySQL.

Nástroje možno kombinovať: zdieľajú iba koreňový adresár, takže jedna aplikácia môže uchovávať obsah v DocStore, auditnú stopu v SegmentedLog a prácu na pozadí v Queue pod rovnakým koreňom úložiska.

DocStore

DocStore je určený na priame čítanie a jednoduché prechádzanie trvalých záznamov. Pre každý záznam zapisuje jeden súbor JSONC:

PHP
$store = new Storh\DocStore($root, 'articles');
$record = $store->put(['slug' => 'hello', 'published' => true]);
$same = $store->get($record->id());

Súbory záznamov sa rozdeľujú podľa posledných znakov UUID, aby sa nápor zápisov UUIDv7 rozložil medzi adresáre:

Text
articles/data/2d/018bcfe5-6800-7000-8000-2d5dba6274da.jsonc

SegmentedLog

SegmentedLog je určený na záznamy s častým pridávaním, čítanie kurzorom a čítanie podľa časového rozsahu. Záznamy sa zapisujú do aktívneho segmentu, jeden na riadok vo formáte <byte-length>\t<xxh32>\t<json> (pozri Atomicity). Súbory segmentov používajú príponu .ndjson, ale predpona s dĺžkou a kontrolným súčtom znamená, že bežné nástroje NDJSON ich nedokážu čítať; záznamy načítajte pomocou stream() alebo nástroja na tvorbu dopytov. Úplné segmenty sa uzatvoria a zmenia na segmenty s riedkymi indexmi.

PHP
$events = new Storh\SegmentedLog($root, 'events');
$events->put(['type' => 'user.created']);
$events->compact();

Queue

Queue je určený pre trvalé pracovné fronty s vysokou priepustnosťou. Operácie zaradenia do frontu, nárokovania, dokončenia, opätovného zaradenia a vyčistenia zapisujú udalosti iba na koniec súboru queue.log; stav frontu sa pri otvorení frontu znovu prehrá do pamäte. Hromadné metódy rozkladajú náklady na zámky a vyprázdnenie vyrovnávacej pamäte medzi mnohé úlohy. Log rastie s každou udalosťou; stats() uvádza jeho aktuálnu veľkosť v bajtoch.

PHP
$queue = new Storh\Queue($root, 'mail');
$queue->enqueue(['to' => 'person@example.test']);
$job = $queue->claim();

Trvácnosť a súbežnosť

storh zverejňuje zápisy súborov pomocou atomického premenovania v cieľovom adresári. Opätovné otvorenie a repair() odstránia opustené dočasné súbory, ktorých vlastniaci proces už nebeží, a živé dočasné súbory zapisovateľov ponechajú. Značky zapisovateľov umožňujú túto kontrolu vykonať v konštantnom čase, takže ku skenovaniu kolekcie pri otvorení úložiska dôjde iba po páde.

SegmentedLog a Queue zapisujú riadky logu chránené dĺžkou a kontrolným súčtom. Opätovné otvorenie alebo oprava skrátia poškodený koniec po poslednú potvrdenú udalosť a obnovia stav v pamäti z trvalého obsahu logu. Zápisy do logu a frontu sa serializujú pomocou zámkov súborového systému.

Zmeny v DocStore sa serializujú pomocou zámku zápisu na úrovni kolekcie, takže súbory záznamov a sekundárne indexy sa medzi procesmi aktualizujú ako jeden konzistentný celok. Súbežné zápisy do rôznych ID záznamov sú bezpečné pri rovnakých predpokladoch o atomickom premenovaní súborov. Pri súbežných zápisoch s rovnakým ID vyhráva posledné premenovanie.

storh pred dokončením premenovania alebo pridania vyprázdni obslužné objekty súborov a zavolá fsync; po atomickom premenovaní sa pokúsi zavolať fsync aj na nadradených adresároch. Odolnosť voči výpadku napájania stále závisí od toho, či podkladový súborový systém a možnosti pripojenia rešpektujú tieto synchronizácie.