Storh
Záznamy ukladané najprv do súborov pre PHP: dokumenty JSONC, segmentované protokoly iba na pridávanie a fronty založené na protokoloch s ID UUIDv7.
composer require storh/storhNajnovšie vydanie v0.5.2 MIT PHP 8.2+
$pages = $docs
->query()
->where('kind')->eq('page')
->orderBy('title')
->limit(20)
->get();V praxi
Rýchly úvod v dvoch častiach: dokument v koreňovom adresári úložiska, potom záznam v protokole a úloha vo fronte vedľa neho.
Jeden koreň, tri moduly
StorageRoot::resolve() normalizuje základný adresár a menný priestor na koreňový adresár a každý modul pri prvom použití vytvorí vlastný podadresár.
Každý modul vracia objekty StorageRecord s id() a data(). Front pridáva každé prevzatie a dokončenie do svojho protokolu udalostí.
use Storh\DocStore;
use Storh\Queue;
use Storh\RecordQuery;
use Storh\SegmentedLog;
use Storh\StorageRoot;
$root = StorageRoot::resolve(__DIR__ . '/var/storh', 'demo');
$docs = new DocStore($root, 'pages');
$home = $docs->put([
'kind' => 'page',
'title' => 'Home',
]);
$loaded = $docs->get($home->id());$log = new SegmentedLog($root, 'events');
$log->put([
'type' => 'page.saved',
'pageId' => $home->id(),
]);
foreach ($log->stream(RecordQuery::all()->after($home->id())->limit(50)) as $record) {
// Process records lazily.
}
$queue = new Queue($root, 'jobs');
$jobId = $queue->enqueue(['task' => 'render', 'pageId' => $home->id()]);
$job = $queue->claim();
if (null !== $job) {
$queue->complete($job->id());
}Úložisko dokumentov JSONC
Jeden súbor JSONC na záznam, ID UUIDv7, rozdelenie do shardov podľa dvoch znakov z poslednej skupiny UUID, atómová náhrada a filtrovanie polí počas prúdenia.
Segmentovaný protokol
Segmenty iba na pridávanie s riadkami JSON, pred ktorými je uvedená dĺžka a kontrolný súčet, riedke indexy, čítanie pomocou kurzora a v časovom rozsahu, obnova po páde a kompakcia.
Front protokolu
Úlohy prechádzajú stavmi čakajúca, spracúva sa a dokončená pomocou kompaktných udalostí frontu, ktoré sa iba pridávajú.
Záznamy UUIDv7
ID, ktoré možno triediť a adresovať podľa času, pre stabilné kurzory, ohraničené skenovania a cesty úložiska vhodné pre shardy.
Atómové zápisy
Zápisy do dočasných súborov a atómové premenovania zachovávajú úplnosť záznamov. Po páde zapisujúceho procesu nasledujúce otvorenie odstráni osirelé dočasné súbory.
Obnova po čiastočnom zápise
Pri čítaní segmentov sa overujú polia dĺžky a kontrolného súčtu; obnova skráti čiastočné riadky na konci.
Najprv súbory
Bez databázového servera, bez adaptéra frameworku, bez behového prostredia Composer; volajúci odovzdá adresár.
Čítanie JSONC
Súbory záznamov môžu obsahovať komentáre a koncové čiarky. Zápisy storh vytvárajú kompaktný jednoradový JSON, takže komentáre zostanú zachované až do ďalšieho zápisu.
Zostavovač dotazov
Reťazenie dotazov, napríklad where('status')->in([...]), v DocStore a SegmentedLog; DocStore používa sekundárne indexy, ak sú k dispozícii.
Sekundárne indexy
Indexy rovnosti, jedinečnosti a rozsahu sa ukladajú ako súbory vedľa kolekcie, odvodzujú sa zo záznamov a možno ich kedykoľvek znova vytvoriť.
Schémy
Voliteľné schémy kolekcií overujú každý zápis a určujú, ktoré polia sa indexujú.
Zrkadlo SQL
Odosielajte kolekcie do SQLite alebo MySQL na spájanie, vyhľadávanie a vytváranie reportov, pričom súbory zostávajú kanonické. Potrebuje ext-pdo alebo ext-mysqli, iba ak sa používa.
Prečo Storh
Adresár namiesto servera
Odovzdáte základný adresár a storh doň zapisuje. Vyžaduje PHP 8.2 a ext-json, bez behových balíkov Composer a adaptéra frameworku.
Jeden tvar záznamu, tri rozloženia
Dokumenty, protokoly a fronty ukladajú ID UUIDv7 spolu s poľom údajov. Vyberte rozloženie na disku podľa pracovnej záťaže a uchovávajte všetky tri pod jedným koreňovým adresárom.
Kontroly, ktoré môžete spustiť
verify() porovnáva indexy a stav protokolov s úplným skenovaním súborov. repair() umiestňuje poškodené záznamy do karantény a skracuje poškodené konce protokolov; CLI vypisuje JSON pre úlohy cron a kontroly stavu.
Porovnávacie testy s uvedeným nastavením
README zverejňuje mediány pre 50,000 záznamov na modul na počítači Apple M1 Pro s PHP 8.5, napríklad 5.6 µs na jedno načítanie konkrétneho bodu. Všetky zápisy pri týchto behoch sa synchronizujú pomocou fsync, takže rýchlosť zápisu závisí od súborového systému.
V porovnaní s
storh ukladá dáta najprv do súborov namiesto toho, aby fungovalo ako relačný dotazovací mechanizmus, preto tieto nástroje vykonávajú niektoré úlohy, ktoré nepokrýva.
| Nástroj | V čom vyniká | Rozdiel oproti Storh |
|---|---|---|
| SQLite | V čom vynikáSamostatný modul SQL v jedinom súbore so serializovateľnými transakciami ACID, ktoré pretrvajú pád programu alebo výpadok napájania. Dokumentácia ho predstavuje ako náhradu za účelové dátové súbory. | Rozdiel oproti Storhstorh uchováva každý záznam v samostatnom súbore JSON a jeho jadro nevyžaduje ovládač PDO. Nepodporuje transakcie viacerých záznamov a dokumentácia odporúča na túto úlohu skutočnú databázu. Kolekcie môže odosielať do SQLite na spájanie a vytváranie reportov, pričom súbory zostávajú kanonické. |
| MySQL | V čom vynikáRelačná databáza obsluhovaná viacvláknovým serverom SQL, s klientskymi programami a knižnicami, nástrojmi na správu a širokou škálou API. | Rozdiel oproti Storhstorh beží v procese PHP a pracuje s adresárom, takže netreba prevádzkovať server. Na spájanie, vyhľadávanie a vytváranie reportov zrkadlí kolekcie do MySQL, aj cez existujúce pripojenie mysqli; súbory pritom zostávajú zdrojom pravdy. |
| SleekDB | V čom vynikáDokumentová databáza založená na obyčajných súboroch v PHP bez závislostí od tretích strán, ktorá ukladá údaje bez schémy do obyčajných súborov JSON. Jej dotazovací API zahŕňa spájanie, textové vyhľadávanie, group by a having, ako aj filtre vnorených vlastností. | Rozdiel oproti Storhstorh spája úložisko dokumentov so segmentovaným protokolom iba na pridávanie a frontom založeným na protokole pod jedným koreňovým adresárom a pred potvrdením uloženia synchronizuje každý zápis pomocou fsync. Spájanie nie je súčasťou storh; na tento účel odosiela kolekcie do SQLite alebo MySQL. |
Otázky a odpovede
Stručné odpovede z dokumentácie Storh.
Áno. DocStore serializuje zmeny pomocou zámku na úrovni kolekcie a pri súbežných zápisoch toho istého ID vyhráva posledné premenovanie. Prevzatie úlohy vo fronte drží zámok frontu, takže dvaja pracovníci nemôžu prevziať tú istú čakajúcu úlohu.
Áno. Pri čítaní akceptuje komentáre a koncové čiarky, no ďalší put() pre dané ID prepíše súbor v kompaktnom formáte JSON a odstráni ich. V režime vyrovnávacej pamäte TRUST sa zmeny súborov mimo storh nezistia.
Načítanie záznamu podľa ID zostáva rýchle, pokiaľ súborový systém zvláda počet súborov. Skenovanie polí DocStore bez indexov sa pri viac než približne 10k záznamoch spomaľuje, preto vytvorte indexy pre polia, podľa ktorých filtrujete. Skenovanie segmentovaného protokolu a čítanie rozsahov fungujú dobre približne do 1M záznamov.
Zápisy sa synchronizujú pomocou fsync a zverejňujú atómovým premenovaním; pri opätovnom otvorení protokolu alebo frontu sa poškodené konce skracujú na poslednú potvrdenú udalosť. Odolnosť voči výpadku napájania stále závisí od toho, či súborový systém a možnosti pripojenia rešpektujú tieto synchronizácie.
Nie. Kolekcie môžete odoslať do SQLite alebo MySQL pomocou SqlMirror na spájanie, vyhľadávanie a vytváranie reportov. Atómové zápisy viacerých záznamov zostávajú úlohou pre skutočnú databázu, ktorá slúži ako zdroj pravdy.
Nie. Front nie je všeobecné úložisko záznamov a obsah úlohy sa po jej dokončení zahodí.
Začnite rýchlym úvodom a potom podľa pokynov v časti Výber modulu prispôsobte DocStore, SegmentedLog alebo Queue svojej pracovnej záťaži.