Liigu sisu juurde

Mootorid

Mootori valimine

Kõik kolm mootorit salvestavad sama tüüpi sisu: UUIDv7 ID ja andmemassiivi, kuid paigutavad selle kettale erinevalt. Paigutus määrab, milleks iga mootor sobib:

DocStore SegmentedLog Queue
Kettal üks JSONC fail kirje kohta, UUID lõpu järgi jaotatud ainult lisatavad pikkuse ja kontrollsummaga prefiksiga JSON read segmentides ning manifest üks ainult lisatav sündmuste logi
Kirjutamine iga kirje puhul faili atomaarne asendamine kontrollsummaga lisamised; ülekirjutused ja kustutamised lisavad uusi kirjeid, ruum vabastatakse compact() abil iga järjekorrasündmuse lisamine kontrollsummaga
Lugemine get() ID järgi, indekseeritud päringud kursori- ja ajavahemiku skannimised, get() olekuindeksi kaudu claim() lisamise järjekorras
Sobib kõige paremini üksikkirje lugemiseks ja indekseeritud otsinguteks mis tahes kogu suuruse korral lisamismahukate voogude jaoks, kuni umbes 1M kirjet püsivaks tööde suunamiseks protsesside vahel
Nõrk koht indekseerimata väljade skannimine, kui kirjeid on üle ligikaudu 10k sagedased üksikkirje ümberkirjutused (vanad versioonid võtavad ruumi kuni tihendamiseni) pole üldotstarbeline kirjehoidla; koormad eemaldatakse töö lõpetamisel

DocStore ja SegmentedLog kasutavad sama sujuvat päringu API liidest: sama where() ahel töötab mõlema mootoriga ja erineb ainult täitmine. DocStore saab vastata sekundaarsete indeksite põhjal, SegmentedLog aga filtreerib segmentide skannimisel. Queue põhineb hõivamisel ega toeta päringuid: töötajad claim() järgmise töö, mitte ei filtreeri töid.

Rusikareeglid:

  • Kirjed, mida hangite, uuendate või kustutate ükshaaval ning mille kohta esitate väljade järgi päringuid: DocStore. Lisage indeksid väljadele, mille järgi filtreerite.
  • Sündmused või versioonid, mida peamiselt lisate ning loete tagasi järjekorras või ajavahemiku järgi: SegmentedLog.
  • Tootjatelt tööprotsessidele edasi antavad tööd: Queue. Hõivamised ja lõpetamised on turvalised mitme protsessi korral ning claimMany()/completeMany() vähendavad luku ja fsync-i kulu.
  • Ühendamised, otsing või aruandlus mis tahes kogu kohta: lisage SQL peegel. Failid jäävad kanooniliseks; peegel on uuesti koostatav projektsioon asukohas SQLite või MySQL.

Mootoreid saab kombineerida: neil on ühine ainult juurkataloog, nii et rakendus saab hoida sisu mootoris DocStore, auditijälge mootoris SegmentedLog ja taustatöid mootoris Queue sama salvestusjuure all.

DocStore

DocStore sobib püsikirjete üksiklugemiseks ja lihtsateks skannimisteks. See kirjutab iga kirje kohta ühe JSONC faili:

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

Kirjefailid jaotatakse UUID viimase märgi järgi, et UUIDv7 kirjutusimpulsid jaguneksid kataloogide vahel:

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

SegmentedLog

SegmentedLog sobib paljude lisamiste, kursori abil lugemise ja ajavahemiku järgi lugemise jaoks. Kirjed kirjutatakse aktiivsesse segmenti, üks rida kirje kohta kujul <byte-length>\t<xxh32>\t<json> (vt Atomaarusus). Segmendifailidel on laiend .ndjson, kuid pikkuse ja kontrollsumma prefiksi tõttu ei saa neid tavaliste NDJSON-tööriistadega lugeda; lugege kirjeid tagasi tööriistaga stream() või päringukoostajaga. Täielikud segmendid suletakse ja neile lisatakse hõredad indeksid.

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

Queue

Queue on mõeldud suure läbilaskevõimega püsivate tööjärjekordade jaoks. Tööde lisamine, hõivamine, lõpetamine, uuesti järjekorda panemine ja tühjendamine kirjutavad lisamisrežiimis sündmusi faili queue.log; järjekorra olek laaditakse järjekorra avamisel mällu sündmusi taasesitades. Paketmeetodid jaotavad lukustamise ja kettale kirjutamise kulu paljude tööde vahel. Logi kasvab iga sündmusega; stats() näitab selle praegust suurust baitides.

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

Püsivus ja samaaegne kasutus

storh avaldab failikirjutused sihtkataloogis aatomilise ümbernimetamise teel. Uuesti avamine ja repair() eemaldavad hüljatud ajutised failid, mille omanikprotsess on lõppenud, jättes aktiivsete kirjutajate ajutised failid alles. Kirjutajamarkerite abil on kontroll konstantse ajakuluga, nii et salvesti avamisel vaadatakse kogumik läbi ainult pärast krahhi.

SegmentedLog ja Queue kirjutavad logiridu, mille pikkus ja kontrollsumma on kaitstud. Uuesti avamine või parandamine kärbib poolikud lõpuosad viimase kinnitatud sündmuseni ning taastab mälus oleva oleku püsiva logi sisu põhjal. Logi- ja järjekorrakirjutused järjestatakse failisüsteemi lukkudega.

DocStore muudatused järjestatakse kogumitaseme kirjutuslukuga, nii et kirjefailid ja sekundaarsed indeksid uuenevad protsessideüleselt ühe terviklikkuse piirina. Eri kirje ID-de samaaegne kirjutamine on ohutu samadel failisüsteemi aatomilise ümbernimetamise eeldustel. Sama ID puhul võidab viimasena ümbernimetatud fail.

storh tühjendab failikäepidemed puhvrisse ja sünkroonib need enne ümbernimetamise või lisamise lõpetamist ning püüab pärast aatomilisi ümbernimetamisi sünkroonida ka ülemkataloogid. Elektrikatkestuse korral sõltub andmete säilimine siiski sellest, kas aluseks olev failisüsteem ja ühendamisvalikud neid sünkroonimisi järgivad.