İçeriğe geç

Motorlar

Motor seçimi

Üç motor da aynı şeyi, bir UUIDv7 kimliğiyle birlikte veri dizisini depolar; ancak diskte farklı biçimlerde düzenler. Her motorun güçlü olduğu alanı bu düzen belirler:

DocStore SegmentedLog Queue
Diskte her kayıt için bir JSONC dosya, UUID-kuyruk parçalı uzunluk ve sağlama toplamı önekleriyle bölümlere ayrılmış, yalnızca eklemeli JSON satırları ve bir manifest yalnızca eklemeli tek bir olay günlüğü
Yazma her kayıt için atomik dosya değiştirme sağlama toplamlı eklemeler; üzerine yazmalar ve silmeler yeni girdiler ekler, compact() ile geri kazanılır her kuyruk olayı için sağlama toplamlı ekleme
Okuma kimliğe göre get(), dizinlenmiş sorgular imleç ve zaman aralığı taramaları, durum dizini üzerinden get() kuyruğa eklenme sırasına göre claim()
İdeal kullanım her koleksiyon boyutunda tekil okumalar ve dizinlenmiş aramalar yaklaşık 1M kayda kadar yoğun eklemeli akışlar süreçler arasında kalıcı iş dağıtımı
Zayıf yön yaklaşık 10k kaydın ötesinde dizinlenmemiş alan taramaları sık tek kayıt yeniden yazımları (eski sürümler sıkıştırmaya kadar yer kaplar) genel amaçlı bir kayıt deposu değildir; bir iş tamamlandığında yük verileri silinir

DocStore ve SegmentedLog aynı akıcı sorguyu API paylaşır: aynı where() zinciri her iki motor üzerinde çalışır; yalnızca yürütme biçimi değişir. DocStore ikincil dizinlerinden yanıt verebilirken SegmentedLog segmentleri tararken filtre uygular. Queue sorgulanabilir değildir, talep temellidir: çalışanlar işleri filtrelemek yerine sıradaki işi claim().

Genel kurallar:

  • Tek tek alıp güncellediğiniz veya sildiğiniz, alanlarına göre sorguladığınız kayıtlar: DocStore. Filtrelediğiniz alanlara dizinler ekleyin.
  • Çoğunlukla eklediğiniz ve sırayla ya da zaman aralığına göre okuduğunuz olaylar veya sürümler: SegmentedLog.
  • Üreticilerden çalışan süreçlere aktarılan işler: Queue. Talepler ve tamamlamalar birden fazla süreçte güvenlidir; claimMany()/completeMany() kilit ve fsync maliyetini dağıtır.
  • Herhangi bir koleksiyonda birleştirmeler, arama veya raporlama: bir SQL yansıması ekleyin. Dosyalar asıl veri kaynağı olarak kalır; yansıma, SQLite veya MySQL içinde yeniden oluşturulabilir bir projeksiyondur.

Motorlar birlikte kullanılabilir: yalnızca kök dizini paylaşırlar. Böylece bir uygulama aynı depolama kökü altında içeriği DocStore'te, denetim izini SegmentedLog'te ve arka plan işlerini Queue'te tutabilir.

DocStore

DocStore kalıcı kayıtlarda tekil okumalar ve basit taramalar içindir. Her kayıt için bir JSONC dosyası yazar:

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

Kayıt dosyaları, UUID kuyruk karakterine göre parçalı dizinlere yerleştirilir; böylece UUIDv7 yazma patlamaları dizinlere yayılır:

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

SegmentedLog

SegmentedLog yoğun eklemeli kayıtlar, imleç okumaları ve zaman aralığı okumaları içindir. Kayıtlar etkin segmente, kayıt başına bir satır olacak şekilde <byte-length>\t<xxh32>\t<json> biçiminde yazılır (bkz. Atomicity). Segment dosyaları .ndjson uzantısını kullanır; ancak uzunluk ve sağlama toplamı önekleri nedeniyle düz NDJSON araçları bu dosyaları okuyamaz. Kayıtları stream() veya sorgu oluşturucuyla okuyun. Dolu segmentler seyrek dizinli mühürlü segmentlere dönüştürülür.

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

Kuyruk

Queue yüksek verimli, kalıcı iş kuyrukları içindir. Kuyruğa ekleme, talep etme, tamamlama, yeniden kuyruğa alma ve temizleme işlemleri queue.log içine yalnızca eklemeli olaylar yazar; kuyruk açıldığında durumu belleğe yeniden oynatılır. Toplu yöntemler, kilit ve boşaltma maliyetini birçok işe dağıtır. Günlük her olayla büyür; stats() geçerli bayt boyutunu bildirir.

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

Kalıcılık ve Eşzamanlılık

storh dosya yazmalarını hedef dizin içinde atomik yeniden adlandırmayla yayımlar. Yeniden açma ve repair(), sahibi olan süreç kapanmış terk edilmiş geçici dosyaları silerken etkin yazarların geçici dosyalarını olduğu gibi bırakır. Yazar işaretçileri bu kontrolü sabit zamanda yapar; bu nedenle depo açılırken koleksiyon yalnızca bir çökme sonrasında taranır.

SegmentedLog ve Queue uzunluk ve sağlama toplamıyla korunan günlük satırları yazar. Yeniden açma veya onarma, yarım kalmış son satırları son işlenen olaya kadar keser ve bellekteki durumu kalıcı günlük içeriğinden yeniden oluşturur. Günlük ve kuyruk yazmaları dosya sistemi kilitleriyle sıraya alınır.

DocStore değişiklikleri koleksiyon düzeyinde bir yazma kilidiyle sıraya alınır; böylece kayıt dosyaları ve ikincil dizinler süreçler arasında tek bir tutarlılık sınırı içinde güncellenir. Farklı kayıt kimliklerine eşzamanlı yazmalar, aynı dosya sistemi atomik yeniden adlandırma varsayımları altında güvenlidir. Aynı kimliğe eşzamanlı yazmalarda son yeniden adlandırma kazanır.

storh dosya tanıtıcılarını yeniden adlandırma veya ekleme tamamlanmadan önce boşaltır ve fsync işlemi uygular; atomik yeniden adlandırmalardan sonra üst dizinlere de fsync uygulamayı dener. Elektrik kesintisine karşı kalıcılık yine de temel dosya sisteminin ve bağlama seçeneklerinin bu eşitleme işlemlerini yerine getirmesine bağlıdır.