Μηχανές
Επιλογή μηχανής
Και οι τρεις μηχανές αποθηκεύουν τα ίδια δεδομένα, ένα αναγνωριστικό UUIDv7 και έναν πίνακα δεδομένων, αλλά τα διατάσσουν διαφορετικά στον δίσκο. Αυτή η διάταξη καθορίζει σε τι είναι κατάλληλη κάθε μηχανή:
| DocStore | SegmentedLog | Queue | |
|---|---|---|---|
| Στον δίσκο | ένα αρχείο JSONC ανά εγγραφή, διαχωρισμένο σε υποκαταλόγους βάσει των χαρακτήρων τέλους UUID | τμήματα προσθήκης μόνο στο τέλος με γραμμές JSON στις οποίες προηγούνται το μήκος και το άθροισμα ελέγχου, καθώς και ένα manifest | ένα αρχείο καταγραφής συμβάντων προσθήκης μόνο στο τέλος |
| Εγγραφή | ατομική αντικατάσταση αρχείου ανά εγγραφή | προσθήκες με άθροισμα ελέγχου· οι αντικαταστάσεις και οι διαγραφές προσθέτουν νέες καταχωρίσεις, ενώ ο χώρος ανακτάται με compact() |
προσθήκη με άθροισμα ελέγχου για κάθε συμβάν ουράς |
| Ανάγνωση | get() βάσει αναγνωριστικού, ερωτήματα με ευρετήριο |
σαρώσεις δρομέα και εύρους χρόνου, get() μέσω του ευρετηρίου κατάστασης |
claim() με τη σειρά προσθήκης στην ουρά |
| Ιδανικό για | σημειακές αναγνώσεις και αναζητήσεις με ευρετήριο σε συλλογές κάθε μεγέθους | ροές με πολλές προσθήκες έως περίπου 1M εγγραφές | ανθεκτική διανομή εργασιών μεταξύ διεργασιών |
| Αδύνατο σημείο | σαρώσεις πεδίων χωρίς ευρετήριο σε πάνω από περίπου 10k εγγραφές | συχνές αντικαταστάσεις μεμονωμένων εγγραφών (οι παλιές εκδόσεις καταλαμβάνουν χώρο μέχρι τη συμπύκνωση) | δεν είναι γενικό σύστημα αποθήκευσης εγγραφών· τα περιεχόμενα διαγράφονται όταν ολοκληρωθεί μια εργασία |
Τα DocStore και SegmentedLog μοιράζονται το ίδιο ευέλικτο
ερώτημα API: η ίδια αλυσίδα where() εκτελείται και στις δύο
μηχανές, ενώ αλλάζει μόνο η εκτέλεση. Το DocStore μπορεί να απαντήσει από τα
δευτερεύοντα ευρετήριά του, ενώ το SegmentedLog φιλτράρει κατά τη σάρωση των τμημάτων.
Το Queue βασίζεται σε αναλήψεις και δεν υποστηρίζει ερωτήματα: οι εργάτες claim() την επόμενη εργασία αντί
να φιλτράρουν εργασίες.
Ενδεικτικοί κανόνες:
- Εγγραφές που ανακτάτε, ενημερώνετε ή διαγράφετε μεμονωμένα και αναζητάτε βάσει πεδίων:
DocStore. Προσθέστε ευρετήρια για τα πεδία που χρησιμοποιείτε στα φίλτρα. - Συμβάντα ή εκδόσεις που κυρίως προσθέτετε και διαβάζετε ξανά με τη σειρά ή με χρονικό
εύρος:
SegmentedLog. - Εργασίες που περνούν από παραγωγούς σε διεργασίες εργατών:
Queue. Οι αναλήψεις και οι ολοκληρώσεις είναι ασφαλείς σε πολλές διεργασίες και ταclaimMany()/completeMany()επιμερίζουν το κόστος κλειδώματος και fsync. - Συνδέσεις, αναζήτηση ή αναφορές για οποιαδήποτε συλλογή: προσθέστε ένα mirror SQL. Τα αρχεία παραμένουν κανονικά· το mirror είναι μια προβολή που μπορεί να αναδημιουργηθεί σε SQLite ή MySQL.
Οι μηχανές συνδυάζονται: μοιράζονται μόνο τον ριζικό κατάλογο, ώστε μια εφαρμογή να μπορεί
να διατηρεί περιεχόμενο σε ένα DocStore, ένα αρχείο ελέγχου σε ένα SegmentedLog και
εργασίες παρασκηνίου σε ένα Queue κάτω από την ίδια ρίζα αποθήκευσης.
DocStore
Το DocStore προορίζεται για σημειακές αναγνώσεις και απλές σαρώσεις ανθεκτικών εγγραφών. Γράφει
ένα αρχείο JSONC ανά εγγραφή:
$store = new Storh\DocStore($root, 'articles');
$record = $store->put(['slug' => 'hello', 'published' => true]);
$same = $store->get($record->id());
Τα αρχεία εγγραφών κατανέμονται σε υποκαταλόγους βάσει των τελευταίων χαρακτήρων UUID, ώστε οι ριπές εγγραφών UUIDv7 να κατανέμονται σε διαφορετικούς καταλόγους:
articles/data/2d/018bcfe5-6800-7000-8000-2d5dba6274da.jsonc
SegmentedLog
Το SegmentedLog προορίζεται για εγγραφές με πολλές προσθήκες, αναγνώσεις με δρομέα και αναγνώσεις εύρους χρόνου.
Οι εγγραφές γράφονται στο ενεργό τμήμα, μία γραμμή ανά εγγραφή με τη μορφή
<byte-length>\t<xxh32>\t<json> (βλ. Ατομικότητα). Τα
αρχεία τμημάτων έχουν επέκταση .ndjson, αλλά το πρόθεμα μήκους και αθροίσματος ελέγχου
σημαίνει ότι τα απλά εργαλεία NDJSON δεν μπορούν να τα διαβάσουν· χρησιμοποιήστε το stream() ή τον
κατασκευαστή ερωτημάτων για να διαβάσετε τις εγγραφές. Τα πλήρη τμήματα κλείνουν και αντικαθίστανται από νέα ενεργά τμήματα με αραιά ευρετήρια.
$events = new Storh\SegmentedLog($root, 'events');
$events->put(['type' => 'user.created']);
$events->compact();
Ουρά
Το Queue προορίζεται για ανθεκτικές ουρές εργασιών υψηλής διεκπεραιωτικής ικανότητας. Η προσθήκη, η ανάληψη, η ολοκλήρωση, η επανατοποθέτηση και η εκκαθάριση εργασιών καταγράφονται ως συμβάντα μόνο για προσθήκη στο queue.log· η κατάσταση της ουράς αναπαράγεται στη μνήμη όταν ανοίγει η ουρά. Οι ομαδικές μέθοδοι επιμερίζουν το κόστος κλειδώματος και εγγραφής σε πολλές εργασίες. Το αρχείο καταγραφής μεγαλώνει με κάθε συμβάν· το stats() αναφέρει το τρέχον μέγεθός του σε byte.
$queue = new Storh\Queue($root, 'mail');
$queue->enqueue(['to' => 'person@example.test']);
$job = $queue->claim();
Ανθεκτικότητα και ταυτόχρονη πρόσβαση
Το storh δημοσιεύει τις εγγραφές αρχείων με ατομική μετονομασία μέσα στον κατάλογο προορισμού. Κατά το εκ νέου άνοιγμα και το repair() διαγράφονται εγκαταλελειμμένα προσωρινά αρχεία των οποίων η διεργασία ιδιοκτήτη έχει τερματιστεί, ενώ τα προσωρινά αρχεία ενεργών εγγραφέων παραμένουν ανέπαφα. Τα σήματα εγγραφέων καθιστούν αυτόν τον έλεγχο σταθερού χρόνου, επομένως η συλλογή σαρώνονται κατά το άνοιγμα του χώρου αποθήκευσης μόνο μετά από κατάρρευση.
Τα SegmentedLog και Queue γράφουν γραμμές αρχείου καταγραφής με προστασία μήκους και αθροίσματος ελέγχου. Κατά το εκ νέου άνοιγμα ή την επιδιόρθωση, οι ημιτελείς ουρές αποκόπτονται στο τελευταίο δεσμευμένο συμβάν και η κατάσταση στη μνήμη αναδημιουργείται από τα περιεχόμενα του μόνιμου αρχείου καταγραφής. Οι εγγραφές στο αρχείο καταγραφής και στην ουρά σειριοποιούνται με κλειδώματα συστήματος αρχείων.
Οι μεταβολές του DocStore σειριοποιούνται με κλείδωμα εγγραφής σε επίπεδο συλλογής, ώστε τα αρχεία εγγραφών και τα δευτερεύοντα ευρετήρια να ενημερώνονται ως ενιαίο όριο συνέπειας μεταξύ διεργασιών. Οι ταυτόχρονες εγγραφές σε διαφορετικά αναγνωριστικά εγγραφών είναι ασφαλείς υπό τις ίδιες παραδοχές ατομικής μετονομασίας του συστήματος αρχείων. Σε ταυτόχρονες εγγραφές στο ίδιο αναγνωριστικό, υπερισχύει η τελευταία μετονομασία.
Το storh εκκαθαρίζει και συγχρονίζει με fsync τους χειριστές αρχείων πριν από την ολοκλήρωση μετονομασίας ή προσθήκης, και επιχειρεί να συγχρονίσει με fsync τους γονικούς καταλόγους μετά από ατομικές μετονομασίες. Η ανθεκτικότητα σε απώλεια ισχύος εξακολουθεί να εξαρτάται από το αν το υποκείμενο σύστημα αρχείων και οι επιλογές προσάρτησης τηρούν αυτούς τους συγχρονισμούς.