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 ningclaimMany()/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:
$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:
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.
$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.
$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.