Hoppa till innehåll

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, och claimMany()/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:

PHP
$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:

Text
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.

PHP
$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.

PHP
$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.