Storh
Rekaman yang mengutamakan file untuk PHP: dokumen JSONC, log tersegmentasi append-only, dan antrean berbasis log dengan id UUIDv7.
composer require storh/storhRilis terbaru v0.5.2 MIT PHP 8.2+
$pages = $docs
->query()
->where('kind')->eq('page')
->orderBy('title')
->limit(20)
->get();Dalam praktik
Mulai cepat dalam dua bagian: dokumen di akar penyimpanan, lalu entri log dan pekerjaan antrean di sampingnya.
Satu akar, tiga mesin
StorageRoot::resolve() menormalkan direktori dasar dan namespace menjadi satu akar, lalu setiap mesin membuat direktorinya sendiri di dalamnya saat pertama kali digunakan.
Setiap mesin mengembalikan objek StorageRecord dengan id() dan data(). Antrean menambahkan setiap klaim dan penyelesaian ke log peristiwanya.
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());
}Penyimpanan Dokumen JSONC
Satu file JSONC per rekaman, id UUIDv7, sharding berdasarkan dua karakter dari grup terakhir UUID, penggantian atomik, dan filter field streaming.
Log Tersegmentasi
Segmen append-only berisi baris JSON dengan prefiks panjang dan checksum, indeks jarang, pembacaan kursor dan rentang waktu, pemulihan setelah crash, serta pemadatan.
Antrean Log
Pekerjaan berpindah melalui status tertunda, diproses, dan selesai menggunakan peristiwa antrean append-only yang ringkas.
Rekaman UUIDv7
Id yang dapat diurutkan dan dialamatkan berdasarkan waktu untuk kursor stabil, pemindaian berbatas, dan jalur penyimpanan yang ramah terhadap sharding.
Penulisan Atomik
Penulisan ke file sementara dan penggantian nama secara atomik menjaga keutuhan rekaman. Setelah penulis mengalami crash, pembukaan berikutnya membersihkan file sementaranya yang yatim.
Pemulihan Penulisan Terpotong
Pembacaan segmen memvalidasi field panjang dan checksum; pemulihan memotong baris terakhir yang tidak lengkap.
Berbasis File
Tanpa server basis data, tanpa adaptor framework, tanpa paket runtime Composer; pemanggil memberikan direktori.
Pembacaan JSONC
File rekaman boleh memuat komentar dan koma di akhir. storh menulis JSON ringkas dalam satu baris, sehingga komentar tetap ada hingga penulisan berikutnya.
Query Builder
Kueri berantai seperti where('status')->in([...]) pada DocStore dan SegmentedLog; DocStore menggunakan indeks sekunder jika tersedia.
Indeks Sekunder
Indeks kesetaraan, unik, dan rentang disimpan sebagai file di samping koleksi, diturunkan dari rekaman dan dapat dibangun ulang kapan saja.
Skema
Skema koleksi opsional memvalidasi setiap penulisan dan menentukan field yang diberi indeks.
Mirror SQL
Kirim koleksi ke SQLite atau MySQL untuk join, pencarian, dan pelaporan, sementara file tetap menjadi sumber kanonis. Membutuhkan ext-pdo atau ext-mysqli hanya saat digunakan.
Mengapa Storh
Direktori, bukan server
Anda memberikan direktori dasar dan storh menulis di sana. Dibutuhkan PHP 8.2 dan ext-json, tanpa paket runtime Composer dan tanpa adaptor framework.
Satu bentuk rekaman, tiga tata letak
Dokumen, log, dan antrean semuanya menyimpan id UUIDv7 serta array data. Pilih tata letak disk sesuai beban kerja dan simpan ketiganya di bawah satu akar.
Pemeriksaan yang dapat Anda jalankan
verify() memeriksa indeks dan status log dengan membandingkannya terhadap pemindaian penuh file. repair() mengarantina rekaman yang rusak dan memotong bagian akhir log yang terpotong, sedangkan CLI mencetak JSON untuk pekerjaan cron dan pemeriksaan kesehatan.
Tolok ukur beserta konfigurasinya
README menerbitkan median untuk 50,000 rekaman per mesin pada Apple M1 Pro dengan PHP 8.5, misalnya 5.6 µs per pembacaan langsung. Setiap penulisan dalam pengujian tersebut di-fsync, jadi laju penulisan bergantung pada sistem file.
Dibandingkan dengan
storh adalah penyimpanan berbasis file, bukan mesin kueri relasional, sehingga alat-alat ini menangani beberapa tugas yang tidak dicakupnya.
| Alat | Keunggulan | Perbedaan dengan Storh |
|---|---|---|
| SQLite | KeunggulanMesin SQL mandiri dalam satu file, dengan transaksi ACID yang dapat diserialisasi dan tetap bertahan saat program crash atau listrik padam. Dokumentasinya menyajikannya sebagai pengganti file data ad hoc. | Perbedaan dengan Storhstorh menyimpan satu file JSON per rekaman dan intinya tidak memerlukan driver PDO. Produk ini tidak memiliki transaksi beberapa rekaman, dan dokumentasinya menyarankan penggunaan basis data sungguhan untuk tugas tersebut. Koleksi dapat dikirim ke SQLite untuk join dan pelaporan sementara file tetap menjadi sumber kanonis. |
| MySQL | KeunggulanBasis data relasional yang dilayani oleh server SQL multithread, dengan program dan pustaka klien, alat administrasi, serta beragam API. | Perbedaan dengan Storhstorh berjalan di dalam proses PHP dan menggunakan direktori, sehingga tidak ada server yang perlu dioperasikan. Untuk join, pencarian, dan pelaporan, koleksi di-mirror ke MySQL, termasuk melalui handle mysqli yang sudah ada, dan file tetap menjadi sumber kebenaran. |
| SleekDB | KeunggulanBasis data dokumen flat-file dalam PHP tanpa dependensi pihak ketiga, yang menyimpan data tanpa skema sebagai file JSON biasa. API kuerinya mencakup join, pencarian teks, group by dan having, serta filter pada properti bertingkat. | Perbedaan dengan Storhstorh memadukan penyimpanan dokumen dengan log tersegmentasi append-only dan antrean berbasis log di bawah satu akar, serta melakukan fsync pada setiap penulisan sebelum melaporkannya tersimpan. Join bukan bagian dari storh; untuk itu, koleksi dikirim ke SQLite atau MySQL. |
Tanya jawab
Jawaban singkat dari dokumentasi Storh.
Ya. DocStore menserialisasi mutasi dengan kunci tulis tingkat koleksi, dan penulisan bersamaan pada id yang sama mengikuti aturan rename terakhir menang. Klaim antrean memegang kunci antrean, sehingga dua worker tidak akan mengklaim pekerjaan tertunda yang sama.
Ya. Pembacaan menerima komentar dan koma di akhir, tetapi put() berikutnya untuk ID tersebut menulis ulang file sebagai JSON ringkas dan menghapusnya. Dengan mode cache TRUST, perubahan file dari luar storh tidak terdeteksi.
Pembacaan langsung berdasarkan id tetap cepat selama sistem file mampu menangani jumlah file. Pemindaian field DocStore tanpa indeks melambat setelah sekitar 10k rekaman, jadi deklarasikan indeks untuk field yang Anda gunakan sebagai filter. Pemindaian log tersegmentasi dan pembacaan rentang tetap nyaman hingga sekitar 1M rekaman.
Penulisan di-fsync dan diterbitkan dengan penggantian nama atomik, sedangkan pembukaan kembali log atau antrean akan memotong bagian akhir yang rusak hingga peristiwa terakhir yang telah dikomit. Ketahanan terhadap listrik padam tetap bergantung pada apakah sistem file dan opsi mount mematuhi operasi sinkronisasi tersebut.
Tidak. Kirim koleksi ke SQLite atau MySQL dengan SqlMirror untuk join, pencarian, dan pelaporan. Penulisan atomik untuk beberapa rekaman tetap perlu ditangani oleh basis data sungguhan sebagai sistem pencatatan utama.
Tidak. Queue bukan penyimpanan rekaman umum, dan payload pekerjaan akan dihapus setelah pekerjaan selesai.
Mulailah dengan panduan mulai cepat, lalu gunakan Memilih mesin untuk menyesuaikan DocStore, SegmentedLog, atau Queue dengan beban kerja Anda.