Storh
Failus pirmiausia naudojantys įrašai, žurnalai ir eilės, skirti PHP: JSONC dokumentai, tik pridedami segmentuoti žurnalai ir žurnalais paremtos eilės su UUIDv7 ID.
composer require storh/storhNaujausia versija v0.5.2 MIT PHP 8.2+
$pages = $docs
->query()
->where('kind')->eq('page')
->orderBy('title')
->limit(20)
->get();Praktinis pritaikymas
Greitoji pradžia iš dviejų dalių: dokumentas saugyklos šakniniame kataloge, o šalia jo – žurnalo įrašas ir eilės užduotis.
Viena šaknis, trys varikliai
StorageRoot::resolve() normalizuoja pagrindinį katalogą ir vardų sritį į šakninį katalogą, o pirmą kartą naudojant kiekvieną variklį jame sukuriamas atskiras katalogas.
Kiekvienas variklis grąžina StorageRecord objektus su id() ir data(). Eilė kiekvieną užduoties paėmimą ir užbaigimą prideda prie savo įvykių žurnalo.
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());
}JSONC dokumentų saugykla
Po vieną JSONC failą kiekvienam įrašui, UUIDv7 ID, skaidymas į dalis pagal du simbolius iš paskutinės UUID grupės, atominis pakeitimas ir srautinis laukų filtravimas.
Segmentuotas žurnalas
Tik pridedami ilgį ir kontrolinę sumą nurodančių priešdėlių JSON įrašų segmentai, reti indeksai, skaitymas pagal žymeklį ir laiko intervalą, atkūrimas po gedimo ir glaudinimas.
Žurnalo eilė
Užduotys pereina laukimo, apdorojimo ir užbaigimo būsenas, naudojant kompaktiškus, tik pridedamus eilės įvykius.
UUIDv7 įrašai
Rūšiuojami ID, leidžiantys nurodyti laiką, kad žymekliai būtų stabilūs, nuskaitymai riboti, o saugojimo keliai tinkami skaidymui į dalis.
Atominiai įrašymai
Įrašymas į laikinąjį failą ir atominis pervadinimas užtikrina įrašų vientisumą. Jei rašymo procesas nutrūksta, kitą kartą atidarius sistemą išvalomi našlaičiais likę laikinieji failai.
Nutrūkusio įrašymo atkūrimas
Skaitant segmentus tikrinami ilgio ir kontrolinės sumos laukai; atkuriant pašalinamos neužbaigtos paskutinės eilutės dalys.
Failai pirmiausia
Nereikia duomenų bazės serverio, karkaso adapterio ar Composer vykdymo paketo; iškvietėjai perduoda katalogą.
Skaitymas JSONC
Įrašų failuose gali būti komentarų ir kablelių po paskutinio elemento. storh įrašo kompaktišką vienos eilutės JSON, todėl komentarai išlieka iki kito įrašymo.
Užklausų kūrimo priemonė
Sklandžios užklausos, pvz., where('status')->in([...]) objektuose DocStore ir SegmentedLog; DocStore naudoja antrinius indeksus, jei jie yra.
Antriniai indeksai
Lygybės, unikalumo ir intervalo indeksai saugomi failuose šalia rinkinio, išvedami iš įrašų ir bet kada atkuriami.
Schemos
Pasirinktinės rinkinio schemos tikrina kiekvieną įrašymą ir nurodo, kuriems laukams kuriami indeksai.
SQL veidrodis
Siųskite rinkinius į SQLite arba MySQL, kad galėtumėte jungti, ieškoti ir rengti ataskaitas, o failai liktų kanoniniu šaltiniu. Reikia tik ext-pdo arba ext-mysqli, kai ši funkcija naudojama.
Kodėl Storh
Katalogas, o ne serveris
Nurodote pagrindinį katalogą, o storh į jį įrašo duomenis. Reikalinga PHP 8.2 ir ext-json; nereikia Composer vykdymo paketų ar karkaso adapterio.
Viena įrašo struktūra, trys išdėstymai
Dokumentuose, žurnaluose ir eilėse saugomas UUIDv7 ID ir duomenų masyvas. Pasirinkite disko išdėstymą pagal darbo pobūdį ir laikykite visas tris sistemas viename šakniniame kataloge.
Patikros, kurias galite atlikti
verify() tikrina indeksus ir žurnalų būseną, nuskaitydama visus failus. repair() izoliuoja sugadintus įrašus ir pašalina nutrūkusias žurnalų pabaigas, o CLI pateikia JSON, skirtą cron užduotims ir būklės patikroms.
Etaloniniai testai su aprašyta sąranka
README pateikia kiekvieno variklio medianas, apskaičiuotas iš 50,000 įrašų, naudojant Apple M1 Pro su PHP 8.5, pavyzdžiui, 5.6 µs vienam taškiniam skaitymui. Kiekvienas šių bandymų įrašymas sinchronizuojamas su disku, todėl įrašymo sparta priklauso nuo failų sistemos.
Palyginimas su
storh yra failais paremta saugykla, o ne reliacinių užklausų variklis, todėl šie įrankiai atlieka kai kurias jo neteikiamas užduotis.
| Įrankis | Stipriosios pusės | Skirtumas nuo Storh |
|---|---|---|
| SQLite | Stipriosios pusėsSavarankiškas SQL variklis viename faile su serializuojamomis ACID transakcijomis, kurios išlieka po programos strigties ar maitinimo nutrūkimo. Dokumentuose jis pristatomas kaip pakaitalas ad hoc duomenų failams. | Skirtumas nuo Storhstorh kiekvienam įrašui saugo atskirą JSON failą, o pagrindinei veiklai nereikia PDO tvarkyklės. Jis nepalaiko kelių įrašų transakcijų; dokumentuose nurodoma šias užduotis patikėti tikrai duomenų bazei. Rinkinius galima siųsti į SQLite jungimams ir ataskaitoms rengti, o failai lieka kanoniniu šaltiniu. |
| MySQL | Stipriosios pusėsReliacinė duomenų bazė, veikianti kelių gijų SQL serveryje, su kliento programomis ir bibliotekomis, administravimo įrankiais bei įvairiomis API. | Skirtumas nuo Storhstorh veikia PHP procese ir naudoja katalogą, todėl nereikia administruoti serverio. Jungimams, paieškai ir ataskaitoms rengti rinkiniai atvaizduojami į MySQL, taip pat naudojant esamą mysqli rankeną; failai lieka tiesos šaltiniu. |
| SleekDB | Stipriosios pusėsPlokščiųjų failų dokumentų duomenų bazė PHP be trečiųjų šalių priklausomybių, kurioje duomenys be schemos saugomi paprastuose JSON failuose. Užklausų API apima jungimus, tekstinę paiešką, grupavimą ir sąlygų taikymą grupėms, taip pat įdėtinių savybių filtravimą. | Skirtumas nuo Storhstorh viename šakniniame kataloge sujungia dokumentų saugyklą, tik pridedamą segmentuotą žurnalą ir žurnalais paremtą eilę; kiekvienas įrašymas sinchronizuojamas su disku prieš patvirtinant, kad duomenys išsaugoti. Jungimai nėra storh funkcija; rinkinius jiems atlikti galima siųsti į SQLite arba MySQL. |
Klausimai ir atsakymai
Trumpi atsakymai iš Storh dokumentacijos.
Taip. DocStore serializuoja pakeitimus naudodamas rinkinio lygmens rašymo užraktą, o vienu metu į tą patį ID įrašantys procesai taikomi pagal principą „laimi paskutinis pervadinimas“. Eilės užduoties paėmimas atliekamas laikant eilės užraktą, todėl du darbuotojai nepaima tos pačios laukiančios užduoties.
Taip. Skaitant priimami komentarai ir kableliai po paskutinio elemento, tačiau kitas to ID put() perrašo failą kaip kompaktišką JSON ir pašalina juos. Įjungus TRUST talpyklos režimą, už storh ribų pakeisti failai neaptinkami.
Įrašų paieška pagal ID išlieka greita, kol failų sistema susidoroja su failų skaičiumi. Neindeksuotų DocStore laukų nuskaitymas sulėtėja, kai įrašų skaičius viršija maždaug 10k, todėl deklaruokite indeksus laukams, pagal kuriuos filtruojate. Segmentuoto žurnalo nuskaitymas ir intervalų skaitymas patogiai veikia su maždaug 1M įrašų.
Įrašymai sinchronizuojami su disku ir paskelbiami atominiu pervadinimu; iš naujo atidarius žurnalą arba eilę, nutrūkusios pabaigos pašalinamos iki paskutinio patvirtinto įvykio. Atsparumas duomenų praradimui dingus elektrai vis tiek priklauso nuo to, ar failų sistema ir prijungimo parinktys tinkamai vykdo sinchronizavimą.
Ne. Jungimams, paieškai ir ataskaitoms rengti siųskite rinkinius į SQLite arba MySQL, naudodami SqlMirror. Kelių įrašų atominis įrašymas tebėra tikros duomenų bazės, kaip sistemos įrašų šaltinio, užduotis.
Ne. Eilė nėra bendros paskirties įrašų saugykla, o užduoties turinys pašalinamas ją užbaigus.
Pradėkite nuo greitosios pradžios, tada vadovaudamiesi skiltimi „Variklio pasirinkimas“ pritaikykite DocStore, SegmentedLog arba Queue savo darbo pobūdžiui.