Μετάβαση στο περιεχόμενο

Κατακερματισμός

Το DocStore γράφει ένα αρχείο ανά εγγραφή. Χωρίς κατακερματισμό, μια μεγάλη συλλογή θα συγκέντρωνε όλα τα αρχεία σε έναν κατάλογο, και οι λειτουργίες καταλόγου επιβραδύνονται όσο αυξάνονται οι καταχωρίσεις. Γι’ αυτό το storh ομαδοποιεί τα αρχεία εγγραφών βάσει δύο χαρακτήρων του αναγνωριστικού εγγραφής:

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

Ο κάδος καθορίζεται από την αρχή της τελικής ομάδας του UUID (χαρακτήρες 24 και 25), η οποία περιέχει τυχαία εντροπία. Δύο δεκαεξαδικοί χαρακτήρες δίνουν 256 κάδους, οπότε μια συλλογή 100k εγγραφών έχει κατά μέσο όρο λιγότερα από 400 αρχεία ανά κατάλογο.

Γιατί οι τελευταίοι χαρακτήρες και όχι οι πρώτοι

Τα αναγνωριστικά UUIDv7 αρχίζουν με χρονική σήμανση 48 bit σε χιλιοστά του δευτερολέπτου, επομένως τα αναγνωριστικά που δημιουργούνται κοντά χρονικά έχουν κοινούς αρχικούς χαρακτήρες. Ο κατακερματισμός με βάση το πρόθεμα θα έστελνε κάθε ριπή εγγραφών στον ίδιο υπερφορτωμένο κατάλογο και θα άλλαζε κάδους μόνο καθώς περνά ο χρόνος. Τα τελευταία byte είναι τυχαία για κάθε εγγραφή, επομένως οι εγγραφές κατανέμονται ομοιόμορφα από την πρώτη κιόλας εγγραφή.

Ο κατακερματισμός δεν είναι ορατός στις αναγνώσεις και στα ερωτήματα: το get() υπολογίζει τον κάδο από το αναγνωριστικό και το stream() επιστρέφει εγγραφές ταξινομημένες κατά αναγνωριστικό σε όλους τους κάδους, επομένως η σελιδοποίηση με δρομέα λειτουργεί σαν να ήταν η συλλογή μία ενιαία ταξινομημένη λίστα.

Σε μεγάλη κλίμακα

Ο αριθμός των κάδων δεν αυξάνεται ποτέ: δύο δεκαεξαδικοί χαρακτήρες αντιστοιχούν σε 256 καταλόγους, ανεξάρτητα από το μέγεθος της συλλογής. Αυτό που αυξάνεται είναι τα αρχεία ανά κάδο:

Εγγραφές Αρχεία ανά κάδο
10k ~40
100k ~390
1M ~3,900
10M ~39,000

Τα σύγχρονα συστήματα αρχείων ευρετηριάζουν τις εγγραφές καταλόγων, επομένως μερικές χιλιάδες αρχεία ανά κάδο διατηρούν γρήγορες τις αναζητήσεις συγκεκριμένων εγγραφών· 1M εγγραφές είναι διαχειρίσιμες για τα get() και τα ευρετηριασμένα ερωτήματα. Το άνοιγμα ενός αποθηκευτικού χώρου απαιτεί σταθερό χρόνο ανεξάρτητα από το μέγεθος της συλλογής: η σάρωση ορφανών προσωρινών αρχείων εκτελείται μόνο όταν ένας δείκτης ανενεργού εγγραφέα δείχνει ότι μια προηγούμενη διεργασία κατέρρευσε στη μέση της εγγραφής. Αυτό που αυξάνεται γραμμικά σε μεγάλη κλίμακα είναι οι λειτουργίες σε ολόκληρη τη συλλογή: οι σαρώσεις χωρίς ευρετήριο, τα reindex() και τα verify() διατρέχουν κάθε αρχείο εγγραφής, επομένως αντιμετωπίστε τα ως εργασίες δέσμης. Πέρα από περίπου 10M εγγραφές ανά συλλογή, αρχίζουν να έχουν σημασία οι μετρήσεις ανά κάδο και η συνολική χρήση inode: χωρίστε τις συλλογές ή χρησιμοποιήστε το τμηματοποιημένο αρχείο καταγραφής για δεδομένα που απαιτούν σάρωση, το οποίο διατηρεί χαμηλό τον αριθμό αρχείων από τον σχεδιασμό.

Οι υπόλοιπες μηχανές

Τα SegmentedLog και Queue δεν διαμοιράζουν δεδομένα, επειδή δεν δημιουργούν ένα αρχείο ανά εγγραφή. Το αρχείο καταγραφής προσθέτει εγγραφές σε αρχεία τμημάτων στο segments/, με όριο το max_segment_bytes (1 MiB από προεπιλογή), ενώ η ουρά προσθέτει συμβάντα σε ένα μόνο queue.log. Ο αριθμός αρχείων παραμένει χαμηλός από τον σχεδιασμό.