Motorer
Välj en motor
Alla tre motorer lagrar samma sak: ett id av typen UUIDv7 plus en dataarray, men organiserar det olika på disk. Den organisationen avgör vad varje motor passar bäst för:
| DocStore | SegmentedLog | Queue | |
|---|---|---|---|
| På disk | en JSONC-fil per post, uppdelad i kataloger efter UUID-suffix | endast tillägg i segment med längd- och kontrollsummeförsedda JSON-rader samt ett manifest | en händelselogg med endast tillägg |
| Skrivning | atomiskt filbyte per post | kontrollsummeverifierade tillägg; överskrivningar och raderingar lägger till nya poster som återtas genom compact() |
kontrollsummeverifierat tillägg per köhändelse |
| Läsning | get() efter id, indexerade frågor |
markör- och tidsintervallssökningar, get() via tillståndsindexet |
claim() i inskickningsordning |
| Passar bäst | punktläsningar och indexerade sökningar vid alla samlingsstorlekar | strömmar med många tillägg och upp till cirka 1M poster | beständig arbetsdistribution mellan processer |
| Svaghet | fältsökningar utan index vid fler än cirka 10k poster | frekventa omskrivningar av enskilda poster (äldre versioner tar plats tills de kompakteras) | ingen generell postlagring; nyttolaster tas bort när ett jobb slutförs |
DocStore och SegmentedLog har samma flytande
fråge-API: samma kedja av where()-anrop körs på båda
motorerna, och endast exekveringen skiljer sig. DocStore kan svara från sina
sekundära index, medan SegmentedLog filtrerar vid genomsökning av segmenten.
Queue bygger på anspråk och kan inte frågas mot: arbetare claim() nästa jobb i stället
för att filtrera jobb.
Tumregler:
- Poster som du hämtar, uppdaterar eller raderar enskilt och söker på fält:
DocStore. Lägg till index för fälten du filtrerar på. - Händelser eller versioner som du främst lägger till och läser i ordning eller inom ett
tidsintervall:
SegmentedLog. - Jobb som skickas från producenter till arbetarprocesser:
Queue. Anspråk och slutföranden är säkra mellan flera processer, ochclaimMany()/completeMany()fördelar kostnaden för lås och fsync över flera jobb. - Kopplingar, sökning eller rapportering över en samling: lägg till en SQL-spegel. Filerna är fortsatt kanoniska; spegeln är en återskapningsbar projektion i SQLite eller MySQL.
Motorer kan kombineras: de delar bara rotkatalog, så en applikation kan
lagra innehåll i en DocStore, en granskningslogg i en SegmentedLog och
bakgrundsjobb i en Queue under samma lagringsrot.
DocStore
DocStore är avsedd för punktläsningar och enkla genomsökningar av beständiga poster. Den skriver
en JSONC-fil per post:
$store = new Storh\DocStore($root, 'articles');
$record = $store->put(['slug' => 'hello', 'published' => true]);
$same = $store->get($record->id());
Postfiler delas upp efter UUID avslutande tecken så att UUIDv7 skrivtoppar sprids över katalogerna:
articles/data/2d/018bcfe5-6800-7000-8000-2d5dba6274da.jsonc
SegmentedLog
SegmentedLog är avsedd för poster med många tillägg, markörläsningar och tidsintervallsläsningar.
Poster skrivs till det aktiva segmentet, en rad per post i formatet
<byte-length>\t<xxh32>\t<json> (se Atomicitet). Segmentfilerna har tillägget .ndjson,
men prefixet med längd och kontrollsumma innebär att vanliga NDJSON-verktyg inte kan läsa dem; läs tillbaka poster med stream() eller
frågebyggaren. Fulla segment rullas över till förseglade segment med glesa index.
$events = new Storh\SegmentedLog($root, 'events');
$events->put(['type' => 'user.created']);
$events->compact();
Queue
Queue är avsedd för beständiga arbetsköer med högt genomflöde. Enqueue, claim, complete,
requeue och purge skriver händelser med endast tillägg till queue.log; köstatus
spelas upp i minnet när kön öppnas. Batchmetoder fördelar kostnaden för lås och
flush över många jobb. Loggen växer med varje händelse; stats()
rapporterar dess aktuella storlek i byte.
$queue = new Storh\Queue($root, 'mail');
$queue->enqueue(['to' => 'person@example.test']);
$job = $queue->claim();
Beständighet och samtidighet
storh publicerar filskrivningar med atomärt namnbyte i målkatalogen.
Vid återöppning och repair() tas övergivna temporära filer bort när ägarprocessen har avslutats,
medan temporära filer från aktiva skrivare lämnas ifred. Skrivarmarkörer gör kontrollen
konstant i tid, så en samling genomsöks när ett lager öppnas endast efter en krasch.
SegmentedLog och Queue skriver loggrader som skyddas av längd och kontrollsumma. Vid återöppning
eller reparation kapas trasiga slutrader till den senaste bekräftade händelsen, och tillståndet i minnet
byggs om från loggens beständiga innehåll. Logg- och köskrivningar serialiseras med
filsystemslås.
DocStore-ändringar serialiseras med ett skrivlås på samlingsnivå, så
postfiler och sekundära index uppdateras som en enda konsekvent enhet mellan
processer. Samtidiga skrivningar till olika post-id:n är säkra med samma
antaganden om atomärt namnbyte i filsystemet. Vid samtidiga skrivningar till samma id vinner
sista namnbytet.
storh tömmer buffertar och synkroniserar filhandtag före avslutat namnbyte eller tillägg och försöker synkronisera överordnade kataloger efter atomära namnbyten. Beständighet vid strömavbrott beror fortfarande på att det underliggande filsystemet och monteringsalternativen respekterar dessa synkroniseringar.