Siirry sisältöön

Moottorit

Moottorin valinta

Kaikki kolme moottoria tallentavat saman asian: UUIDv7-tunnisteen ja data-olioiden taulukon, mutta järjestävät tiedot levylle eri tavoin. Tallennustapa määrittää kunkin moottorin vahvuudet:

DocStore SegmentedLog Queue
Levyrakenne yksi JSONC-tiedosto tietuetta kohti, UUID-häntämerkkien mukaan jaettuna lisäyskäyttöön tarkoitetut segmentit, joissa pituudella ja tarkistussummalla etuliitetyt JSON-rivit, sekä manifesti yksi lisäyskäyttöön tarkoitettu tapahtumaloki
Kirjoittaminen tietuekohtainen atominen tiedostokorvaus tarkistussummalliset lisäykset; ylikirjoitukset ja poistot lisäävät uusia merkintöjä, tila vapautuu compact()-toiminnolla jokaisen jonotapahtuman tarkistussummallinen lisäys
Lukeminen get() tunnisteen perusteella, indeksoidut haut kohdistin- ja aikaväliluvut, get() tilaindeksin avulla claim() lisäysjärjestyksessä
Sopii parhaiten yksittäislukuihin ja indeksoituihin hakuihin kaiken kokoisissa kokoelmissa lisäyspainotteisiin virtoihin noin 1M tietueeseen asti pysyvien töiden välittämiseen prosessien välillä
Heikkous indeksoimattomien kenttien läpikäynti yli noin 10k tietueen kokoelmissa usein toistuviin yksittäisten tietueiden uudelleenkirjoituksiin (vanhat versiot vievät tilaa tiivistykseen asti) ei ole yleiskäyttöinen tietuevarasto; hyötykuormat pudotetaan työn valmistuttua

DocStore ja SegmentedLog käyttävät samaa sujuvaa kyselyrajapintaa API: sama where()-ketju toimii kummassakin moottorissa, ja vain suoritus eroaa. DocStore voi hakea tuloksen toissijaisista indekseistään, kun taas SegmentedLog suodattaa segmenttejä lukiessaan. Queue perustuu varaamiseen eikä tue kyselyitä: työntekijät claim() seuraavan työn suodattamisen sijaan.

Nyrkkisäännöt:

  • Tietueet, joita noudat, päivität tai poistat yksitellen ja haet kentän perusteella: DocStore. Lisää indeksit kentille, joiden perusteella suodatat.
  • Tapahtumat tai versiot, joita pääasiassa lisäät ja luet järjestyksessä tai aikavälin mukaan: SegmentedLog.
  • Tuottajilta työntekijäprosesseille välitettävät työt: Queue. Varaus ja valmistuminen ovat turvallisia usean prosessin käytössä, ja claimMany()/completeMany() vähentävät lukituksen ja fsync-operaatioiden kustannusta.
  • Liitokset, haku tai raportointi missä tahansa kokoelmassa: lisää SQL-peili. Tiedostot pysyvät kanonisina; peili on uudelleenrakennettava projektio kohteessa SQLite tai MySQL.

Moottorit toimivat yhdessä: ne jakavat vain juurihakemiston, joten sovellus voi tallentaa sisällön kohteeseen DocStore, tarkastusketjun kohteeseen SegmentedLog ja taustatyöt kohteeseen Queue saman tallennusjuuren alle.

DocStore

DocStore sopii yksittäislukuihin ja yksinkertaisiin pysyvien tietueiden läpikäynteihin. Se kirjoittaa yhden JSONC-tiedoston tietuetta kohti:

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

Tietuetiedostot jaetaan UUID-häntämerkkien mukaan, jotta UUIDv7-kirjoituspiikit jakautuvat eri hakemistoihin:

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

SegmentedLog

SegmentedLog sopii lisäyspainotteisille tietueille, kohdistinluvuille ja aikaväliluvuille. Tietueet kirjoitetaan aktiiviseen segmenttiin, yksi rivi tietuetta kohti muodossa <byte-length>\t<xxh32>\t<json> (katso Atomisuus). Segmenttitiedostojen tunniste on .ndjson, mutta pituus- ja tarkistussummaetuliitteen vuoksi tavalliset NDJSON-työkalut eivät voi lukea niitä; lue tietueet takaisin kohteella stream() tai kyselyrakentajalla. Täydet segmentit siirtyvät suljetuiksi segmenteiksi, joilla on harvat indeksit.

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

Queue

Queue on tarkoitettu suuritehoisiin pysyviin työjonoihin. Enqueue, claim, complete, requeue ja purge kirjoittavat lisäyskäyttöön tarkoitettuja tapahtumia kohteeseen queue.log; jonon tila luetaan uudelleen muistiin, kun jono avataan. Erämenetelmät jakavat lukituksen ja tyhjennyksen kustannuksen useille töille. Lokia kasvattaa jokainen tapahtuma; stats() ilmoittaa sen nykyisen koon tavuina.

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

Pysyvyys ja samanaikaisuus

storh julkaisee tiedostokirjoitukset atomisella nimeämisellä kohdehakemiston sisällä. Uudelleenavaus ja repair() poistavat hylätyt väliaikaistiedostot, joiden omistajaprosessi on päättynyt, mutta jättävät aktiivisten kirjoittajien väliaikaistiedostot rauhaan. Kirjoittajamerkkien ansiosta tarkistus on vakioaikainen, joten tallennuksen avaaminen käy kokoelman läpi vain kaatumisen jälkeen.

SegmentedLog ja Queue kirjoittavat pituudella ja tarkistussummalla suojattuja lokirivejä. Uudelleenavaus tai korjaus katkaisee rikkoutuneet loput viimeiseen vahvistettuun tapahtumaan asti ja rakentaa muistissa olevan tilan uudelleen kestävän lokin sisällöstä. Lokin ja jonon kirjoitukset sarjallistetaan tiedostojärjestelmälukoilla.

DocStore-muutokset sarjallistetaan kokoelman tason kirjoituslukolla, joten tietuetiedostot ja toissijaiset indeksit päivittyvät yhtenä eheysrajana prosessien välillä. Samanaikaiset kirjoitukset eri tietuetunnuksiin ovat turvallisia samoilla tiedostojärjestelmän atomisen uudelleennimeämisen oletuksilla. Samanaikaisista saman tunnuksen kirjoituksista viimeinen uudelleennimeäminen voittaa.

storh tyhjentää tiedostokahvojen puskurit ja synkronoi ne ennen uudelleennimeämisen tai lisäyksen valmistumista sekä yrittää synkronoida ylätason hakemistot atomisten uudelleennimeämisten jälkeen. Sähkökatkon kestävyys riippuu silti siitä, noudattavatko alla oleva tiedostojärjestelmä ja liitosasetukset näitä synkronointeja.