Pereiti prie turinio

Varikliai

Variklio pasirinkimas

Visi trys varikliai saugo tą patį – UUIDv7 ID ir duomenų masyvą, – tačiau skirtingai išdėsto juos diske. Nuo šio išdėstymo priklauso, kam kiekvienas variklis tinka:

DocStore SegmentedLog Queue
Diske po vieną JSONC failą įrašui, suskaidyta į aplankus pagal UUID paskutinius simbolius tik papildymui skirti JSON eilučių segmentai su ilgiu ir kontroline suma bei manifestu vienas tik papildymui skirtas įvykių žurnalas
Įrašymas kiekvieno įrašo failas atomiškai pakeičiamas kontrolinėmis sumomis apsaugoti papildymai; perrašymai ir trynimai sukuria naujus įrašus, o vieta atlaisvinama compact() kontrolinėmis sumomis apsaugomas kiekvienas eilės įvykio įrašymas
Skaitymas get() pagal ID, indeksuotos užklausos žymeklio ir laiko intervalo peržiūra, get() pagal būsenos indeksą claim() įtraukimo į eilę tvarka
Tinkamiausia tiesioginis skaitymas ir indeksuota paieška bet kokio dydžio kolekcijose intensyviai papildomi srautai iki maždaug 1M įrašų patvarus užduočių paskirstymas tarp procesų
Silpnoji vieta neindeksuoto lauko peržiūra kolekcijose, didesnėse nei maždaug 10k įrašų dažni atskirų įrašų perrašymai (senos versijos užima vietą iki sutankinimo) tai nėra bendros paskirties įrašų saugykla; užduotį užbaigus duomenys pašalinami

DocStore ir SegmentedLog naudoja tą pačią nuoseklią užklausų API sąsają: ta pati where() grandinė veikia abiejuose varikliuose, skiriasi tik vykdymas. DocStore gali atsakyti naudodamas antrinius indeksus, o SegmentedLog filtruoja įrašus peržiūrėdamas segmentus. Queue veikia pagal užduoties paėmimo principą, o ne pagal užklausas: darbuotojai claim() kitą užduotį, užuot jas filtravę.

Taisyklės, kaip pasirinkti:

  • Įrašams, kuriuos atskirai gaunate, atnaujinate ar ištrinate ir ieškote pagal lauką, rinkitės DocStore. Filtruojamiems laukams pridėkite indeksus.
  • Įvykiams ar versijoms, kuriuos daugiausia pridedate ir skaitote atgal eilės tvarka arba pagal laiko intervalą, rinkitės SegmentedLog.
  • Užduotims, kurias gamintojai perduoda darbuotojų procesams, rinkitės Queue. Užduočių paėmimas ir užbaigimas yra saugūs keliems procesams, o claimMany() / completeMany() sumažina vienai užduočiai tenkančią užraktų ir fsync kainą.
  • Sujungimams, paieškai ar ataskaitoms visoje kolekcijoje pridėkite SQL veidrodį. Failai lieka pagrindiniu duomenų šaltiniu; veidrodis yra atkuriama projekcija, saugoma SQLite arba MySQL.

Variklius galima derinti: jie dalijasi tik šakniniu katalogu, todėl viena programa gali saugoti turinį DocStore, audito seką SegmentedLog, o fonines užduotis Queue, naudodama tą pačią saugyklos šaknį.

DocStore

DocStore skirtas tiesiogiai skaityti ir paprastai peržiūrėti patvarius įrašus. Kiekvienam įrašui įrašo po vieną JSONC failą:

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

Įrašų failai suskaidomi į aplankus pagal UUID paskutinius simbolius, kad UUIDv7 rašymo pliūpsniai pasiskirstytų po skirtingus aplankus:

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

SegmentedLog

SegmentedLog skirtas daugiausia pridedamiems įrašams, žymeklių skaitymui ir laiko intervalų peržiūrai. Įrašai rašomi į aktyvų segmentą po vieną eilutėje formatu <byte-length>\t<xxh32>\t<json> (žr. Atomiškumas). Segmentų failams naudojamas .ndjson plėtinys, tačiau ilgio ir kontrolinės sumos priešdėlis reiškia, kad įprasti NDJSON įrankiai jų perskaityti negali; įrašams skaityti naudokite stream() arba užklausų kūrimo priemonę. Užpildyti segmentai paverčiami uždarytais segmentais su retais indeksais.

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

Queue

Queue skirtas didelio našumo patvarioms užduočių eilėms. Įtraukimas į eilę, paėmimas, užbaigimas, grąžinimas į eilę ir išvalymas įrašo tik papildomus įvykius į queue.log; atidarius eilę, jos būsena atkuriama atmintyje. Paketinio apdorojimo metodai paskirsto užrakinimo ir išsiuntimo kainą daugeliui užduočių. Žurnalas auga su kiekvienu įvykiu; stats() pateikia dabartinį jo dydį baitais.

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

Patvarumas ir lygiagretumas

storh publikuoja failų įrašymus atomiškai pervadindamas failus tiksliniame aplanke. Pakartotinai atidarant ir vykdant repair() pašalinami apleisti laikini failai, kurių savininko procesas jau baigė darbą, o aktyvių rašytojų laikini failai paliekami. Rašytojų žymos leidžia tai patikrinti pastoviu laiku, todėl kolekcija peržiūrima tik po gedimo.

SegmentedLog ir Queue įrašo žurnalo eilutes su ilgio ir kontrolinės sumos patikra. Atidarius iš naujo arba taisant, nutrūkusios pabaigos nukerpamos iki paskutinio patvirtinto įvykio, o atminties būsena atkuriama iš patvaraus žurnalo turinio. Žurnalo ir eilės įrašymai serializuojami naudojant failų sistemos užraktus.

DocStore pakeitimai serializuojami naudojant kolekcijos lygmens įrašymo užraktą, todėl įrašų failai ir antriniai indeksai atnaujinami kaip viena vientisumo riba visuose procesuose. Lygiagretus įrašymas į skirtingus įrašų ID yra saugus, jei failų sistema palaiko atominį pervadinimą. Kartu įrašant tą patį ID laimi paskutinis pervadinimas.

storh prieš pervadinant failus arba baigiant papildymą išsiunčia duomenis iš failų deskriptorių buferių ir iškviečia fsync, o po atominių pervadinimų bando iškviesti fsync ir tėviniams aplankams. Patvarumas nutrūkus maitinimui vis tiek priklauso nuo to, ar pagrindinė failų sistema ir prijungimo parinktys laikosi šių sinchronizavimo nurodymų.