Κασσάνδρα. Πώς να μην πεθάνεις αν ξέρεις μόνο την Oracle

Γεια σου Χαμπρ.

Ονομάζομαι Misha Butrimov, θα ήθελα να σας πω λίγα λόγια για την Κασσάνδρα. Η ιστορία μου θα είναι χρήσιμη σε όσους δεν έχουν συναντήσει ποτέ βάσεις δεδομένων NoSQL - έχει πολλές δυνατότητες υλοποίησης και παγίδες που πρέπει να γνωρίζετε. Και αν δεν έχετε δει τίποτα άλλο εκτός από την Oracle ή οποιαδήποτε άλλη σχεσιακή βάση δεδομένων, αυτά τα πράγματα θα σας σώσουν τη ζωή.

Τι καλό έχει η Κασσάνδρα; Είναι μια βάση δεδομένων NoSQL που έχει σχεδιαστεί χωρίς ούτε ένα σημείο αποτυχίας που κλιμακώνεται καλά. Εάν χρειάζεται να προσθέσετε μερικά terabyte για κάποια βάση δεδομένων, μπορείτε απλώς να προσθέσετε κόμβους στο δαχτυλίδι. Επέκταση σε άλλο κέντρο δεδομένων; Προσθέστε κόμβους στο σύμπλεγμα. Αύξηση επεξεργασμένου RPS; Προσθέστε κόμβους στο σύμπλεγμα. Λειτουργεί και προς την αντίθετη κατεύθυνση.

Κασσάνδρα. Πώς να μην πεθάνεις αν ξέρεις μόνο την Oracle

Σε τι άλλο είναι καλή; Έχει να κάνει με το χειρισμό πολλών αιτημάτων. Αλλά πόσο είναι πολλά; 10, 20, 30, 40 χιλιάδες αιτήματα ανά δευτερόλεπτο δεν είναι πολλά. 100 χιλιάδες αιτήματα ανά δευτερόλεπτο για ηχογράφηση - επίσης. Υπάρχουν εταιρείες που είπαν ότι κρατούν 2 εκατομμύρια αιτήματα ανά δευτερόλεπτο. Μάλλον θα πρέπει να το πιστέψουν.

Και καταρχήν, η Κασσάνδρα έχει μια μεγάλη διαφορά από τα σχεσιακά δεδομένα - δεν είναι καθόλου παρόμοια με αυτά. Και αυτό είναι πολύ σημαντικό να το θυμάστε.

Δεν λειτουργούν το ίδιο ό,τι φαίνεται ίδιο

Κάποτε ένας συνάδελφος ήρθε σε μένα και με ρώτησε: «Εδώ είναι μια γλώσσα ερωτήματος CQL Cassandra, και έχει μια εντολή επιλογής, έχει πού, έχει και. Γράφω γράμματα και δεν δουλεύει. Γιατί?". Η αντιμετώπιση της Κασσάνδρας σαν μια σχεσιακή βάση δεδομένων είναι ο τέλειος τρόπος για να αυτοκτονήσετε με βία. Και δεν το προωθώ, απαγορεύεται στη Ρωσία. Απλώς κάτι θα σχεδιάσετε λάθος.

Για παράδειγμα, ένας πελάτης έρχεται σε εμάς και λέει: «Ας φτιάξουμε μια βάση δεδομένων για τηλεοπτικές σειρές ή μια βάση δεδομένων για έναν κατάλογο συνταγών. Θα έχουμε πιάτα φαγητού εκεί ή μια λίστα με τηλεοπτικές σειρές και ηθοποιούς σε αυτήν». Λέμε χαρούμενα: «Πάμε!» Απλώς στείλτε δύο byte, μερικά σημάδια και τελειώσατε, όλα θα λειτουργήσουν πολύ γρήγορα και αξιόπιστα. Και όλα είναι καλά μέχρι να έρθουν οι πελάτες και να πουν ότι οι νοικοκυρές λύνουν και το αντίθετο πρόβλημα: έχουν μια λίστα με προϊόντα και θέλουν να ξέρουν τι πιάτο θέλουν να μαγειρέψουν. Είστε νεκροί.

Αυτό συμβαίνει επειδή η Cassandra είναι μια υβριδική βάση δεδομένων: παρέχει ταυτόχρονα μια βασική τιμή και αποθηκεύει δεδομένα σε μεγάλες στήλες. Στην Java ή στο Kotlin, θα μπορούσε να περιγραφεί ως εξής:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Δηλαδή ένας χάρτης που περιέχει και ταξινομημένο χάρτη. Το πρώτο κλειδί σε αυτόν τον χάρτη είναι το κλειδί γραμμής ή το κλειδί διαμερίσματος - το κλειδί κατάτμησης. Το δεύτερο κλειδί, το οποίο είναι το κλειδί σε έναν ήδη ταξινομημένο χάρτη, είναι το κλειδί Clustering.

Για να δείξουμε την κατανομή της βάσης δεδομένων, ας σχεδιάσουμε τρεις κόμβους. Τώρα πρέπει να καταλάβετε πώς να αποσυνθέσετε τα δεδομένα σε κόμβους. Γιατί αν τα στριμώξουμε όλα σε ένα (παρεμπιπτόντως, μπορεί να είναι χίλια, δύο χιλιάδες, πέντε - όσοι θέλετε), δεν πρόκειται πραγματικά για διανομή. Επομένως, χρειαζόμαστε μια μαθηματική συνάρτηση που θα επιστρέψει έναν αριθμό. Απλώς ένας αριθμός, μια μακρά int που θα εμπίπτει σε κάποιο εύρος. Και θα έχουμε έναν κόμβο υπεύθυνο για ένα εύρος, τον δεύτερο για το δεύτερο, τον nth για το ντο.

Κασσάνδρα. Πώς να μην πεθάνεις αν ξέρεις μόνο την Oracle

Αυτός ο αριθμός λαμβάνεται χρησιμοποιώντας μια συνάρτηση κατακερματισμού, η οποία εφαρμόζεται σε αυτό που ονομάζουμε κλειδί διαμερίσματος. Αυτή είναι η στήλη που καθορίζεται στην οδηγία για το πρωτεύον κλειδί και αυτή είναι η στήλη που θα είναι το πρώτο και πιο βασικό κλειδί του χάρτη. Καθορίζει ποιος κόμβος θα λάβει ποια δεδομένα. Δημιουργείται ένας πίνακας στην Κασσάνδρα με σχεδόν την ίδια σύνταξη όπως στην SQL:

CREATE TABLE users (
	user_id uu id,
	name text,
	year int,
	salary float,
	PRIMARY KEY(user_id)

)

Το πρωτεύον κλειδί σε αυτήν την περίπτωση αποτελείται από μία στήλη και είναι επίσης το κλειδί διαμερίσματος.

Πώς θα αποδώσουν οι χρήστες μας; Μερικοί θα πάνε σε έναν κόμβο, άλλοι σε έναν άλλον και άλλοι σε έναν τρίτο. Το αποτέλεσμα είναι ένας συνηθισμένος πίνακας κατακερματισμού, γνωστός και ως χάρτης, γνωστός και ως λεξικό στην Python, ή μια απλή δομή βασικών τιμών από την οποία μπορούμε να διαβάσουμε όλες τις τιμές, να διαβάσουμε και να γράψουμε με κλειδί.

Κασσάνδρα. Πώς να μην πεθάνεις αν ξέρεις μόνο την Oracle

Επιλέξτε: όταν επιτρέπεται το φιλτράρισμα μετατρέπεται σε πλήρη σάρωση ή τι να μην κάνετε

Ας γράψουμε μια πρόταση επιλογής: select * from users where, userid = . Αποδεικνύεται όπως στην Oracle: γράφουμε Select, καθορίζουμε τις συνθήκες και όλα λειτουργούν, οι χρήστες το λαμβάνουν. Αλλά αν επιλέξετε, για παράδειγμα, έναν χρήστη με συγκεκριμένο έτος γέννησης, η Κασσάνδρα παραπονιέται ότι δεν μπορεί να εκπληρώσει το αίτημα. Επειδή δεν γνωρίζει απολύτως τίποτα για το πώς διανέμουμε δεδομένα σχετικά με το έτος γέννησης - έχει μόνο μία στήλη που υποδεικνύεται ως κλειδί. Μετά λέει, «Εντάξει, μπορώ ακόμα να εκπληρώσω αυτό το αίτημα. Προσθήκη επιτρεπόμενου φιλτραρίσματος." Προσθέτουμε την οδηγία, όλα λειτουργούν. Και αυτή τη στιγμή συμβαίνει κάτι τρομερό.

Όταν τρέχουμε με δεδομένα δοκιμής, όλα είναι καλά. Και όταν εκτελείτε ένα ερώτημα στην παραγωγή, όπου έχουμε, για παράδειγμα, 4 εκατομμύρια δίσκους, τότε δεν είναι όλα πολύ καλά για εμάς. Επειδή το allow filtering είναι μια οδηγία που επιτρέπει στην Cassandra να συλλέγει όλα τα δεδομένα από αυτόν τον πίνακα από όλους τους κόμβους, όλα τα κέντρα δεδομένων (αν υπάρχουν πολλά από αυτά σε αυτό το σύμπλεγμα) και μόνο τότε να τα φιλτράρει. Αυτό είναι ένα ανάλογο του Full Scan και σχεδόν κανείς δεν είναι ευχαριστημένος με αυτό.

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

Και έχει επίσης ένα κλειδί, το οποίο ονομάζουμε Clustering Key. Αυτό το κλειδί, το οποίο, με τη σειρά του, αποτελείται από τις στήλες που επιλέγουμε, με τη βοήθεια του οποίου η Cassandra κατανοεί πώς τα δεδομένα της ταξινομούνται φυσικά και θα βρίσκονται σε κάθε κόμβο. Δηλαδή, για κάποιο κλειδί Partition, το κλειδί Clustering θα σας πει ακριβώς πώς να ωθήσετε τα δεδομένα σε αυτό το δέντρο, ποια θέση θα πάρει εκεί.

Αυτό είναι πραγματικά ένα δέντρο, ένας συγκριτής ονομάζεται απλώς εκεί, στον οποίο περνάμε ένα συγκεκριμένο σύνολο στηλών με τη μορφή ενός αντικειμένου και καθορίζεται επίσης ως λίστα στηλών.

CREATE TABLE users_by_year_salary_id (
	user_id uuid,
	name text,
	year int,
	salary float,
	PRIMARY KEY((year), salary, user_id)

Δώστε προσοχή στην οδηγία για το πρωτεύον κλειδί· το πρώτο της επιχείρημα (στην περίπτωσή μας, το έτος) είναι πάντα Κλειδί διαμερίσματος. Μπορεί να αποτελείται από μία ή περισσότερες στήλες, δεν πειράζει. Εάν υπάρχουν πολλές στήλες, πρέπει να αφαιρεθεί ξανά σε αγκύλες, έτσι ώστε ο προεπεξεργαστής γλώσσας να καταλάβει ότι αυτό είναι το Κύριο κλειδί και πίσω από αυτό όλες οι άλλες στήλες είναι το κλειδί Ομαδοποίησης. Σε αυτήν την περίπτωση, θα μεταδοθούν στον συγκριτικό με τη σειρά που εμφανίζονται. Δηλαδή, η πρώτη στήλη είναι πιο σημαντική, η δεύτερη είναι λιγότερο σημαντική κ.ο.κ. Το πώς γράφουμε, για παράδειγμα, ισούται με πεδία για κλάσεις δεδομένων: παραθέτουμε τα πεδία και για αυτά γράφουμε ποια είναι μεγαλύτερα και ποια είναι μικρότερα. Στην Κασσάνδρα, αυτά είναι, μιλώντας σχετικά, τα πεδία της κλάσης δεδομένων, στα οποία θα εφαρμοστούν τα ίσα που γράφτηκαν για αυτήν.

Θέτουμε ταξινόμηση και επιβάλλουμε περιορισμούς

Πρέπει να θυμάστε ότι η σειρά ταξινόμησης (φθίνουσα, αύξουσα, ό,τιδήποτε) ορίζεται την ίδια στιγμή που δημιουργείται το κλειδί και δεν μπορεί να αλλάξει αργότερα. Καθορίζει φυσικά πώς θα ταξινομηθούν τα δεδομένα και πώς θα αποθηκευτούν. Εάν πρέπει να αλλάξετε το κλειδί Ομαδοποίησης ή τη σειρά ταξινόμησης, θα πρέπει να δημιουργήσετε έναν νέο πίνακα και να μεταφέρετε δεδομένα σε αυτόν. Αυτό δεν θα λειτουργήσει με ένα υπάρχον.

Κασσάνδρα. Πώς να μην πεθάνεις αν ξέρεις μόνο την Oracle

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

Εμφανίζεται ξανά το εργατικό μας where, and, και έχουμε χρήστες, και όλα είναι πάλι καλά. Αλλά αν προσπαθήσουμε να χρησιμοποιήσουμε μόνο ένα μέρος του κλειδιού Clustering και ένα λιγότερο σημαντικό, τότε η Cassandra θα παραπονεθεί αμέσως ότι δεν μπορεί να βρει τη θέση στον χάρτη μας όπου αυτό το αντικείμενο, το οποίο έχει αυτά τα πεδία για τον μηδενικό συγκριτή και αυτό που μόλις είχε οριστεί , - όπου βρίσκεται. Θα πρέπει να ανασύρω ξανά όλα τα δεδομένα από αυτόν τον κόμβο και να τον φιλτράρω. Και αυτό είναι ένα ανάλογο του Full Scan σε έναν κόμβο, αυτό είναι κακό.

Σε οποιαδήποτε ασαφή κατάσταση, δημιουργήστε έναν νέο πίνακα

Αν θέλουμε να μπορούμε να στοχεύουμε χρήστες με ταυτότητα, ηλικία ή μισθό, τι πρέπει να κάνουμε; Τίποτα. Απλά χρησιμοποιήστε δύο τραπέζια. Εάν πρέπει να προσεγγίσετε χρήστες με τρεις διαφορετικούς τρόπους, θα υπάρχουν τρεις πίνακες. Πέρασαν οι εποχές που εξοικονομούσαμε χώρο στη βίδα. Αυτός είναι ο φθηνότερος πόρος. Κοστίζει πολύ λιγότερο από τον χρόνο απόκρισης, κάτι που μπορεί να είναι επιζήμιο για τον χρήστη. Είναι πολύ πιο ευχάριστο για τον χρήστη να λάβει κάτι σε ένα δευτερόλεπτο παρά σε 10 λεπτά.

Ανταλλάσσουμε τον περιττό χώρο και τα αποκανονικά δεδομένα για την ικανότητα να κλιμακώνουμε καλά και να λειτουργούμε αξιόπιστα. Άλλωστε, στην πραγματικότητα, ένα σύμπλεγμα που αποτελείται από τρία κέντρα δεδομένων, καθένα από τα οποία έχει πέντε κόμβους, με αποδεκτό επίπεδο διατήρησης δεδομένων (όταν δεν χάνεται τίποτα), μπορεί να επιβιώσει πλήρως από το θάνατο ενός κέντρου δεδομένων. Και δύο ακόμη κόμβοι σε καθέναν από τους υπόλοιπους δύο. Και μόνο μετά αρχίζουν τα προβλήματα. Αυτή είναι μια αρκετά καλή πλεονασμός, αξίζει μερικές επιπλέον μονάδες SSD και επεξεργαστές. Επομένως, για να χρησιμοποιήσετε την Cassandra, η οποία δεν είναι ποτέ SQL, στην οποία δεν υπάρχουν σχέσεις, ξένα κλειδιά, πρέπει να γνωρίζετε απλούς κανόνες.

Σχεδιάζουμε τα πάντα σύμφωνα με το αίτημά σας. Το κύριο πράγμα δεν είναι τα δεδομένα, αλλά το πώς θα λειτουργήσει η εφαρμογή με αυτά. Εάν χρειάζεται να λάβει διαφορετικά δεδομένα με διαφορετικούς τρόπους ή τα ίδια δεδομένα με διαφορετικούς τρόπους, πρέπει να τα βάλουμε με τρόπο που να είναι βολικός για την εφαρμογή. Διαφορετικά, θα αποτύχουμε στο Full Scan και η Κασσάνδρα δεν θα μας δώσει κανένα πλεονέκτημα.

Η αποκανονικοποίηση των δεδομένων είναι ο κανόνας. Ξεχνάμε τις κανονικές φόρμες, δεν έχουμε πλέον σχεσιακές βάσεις δεδομένων. Αν βάλουμε κάτι κάτω 100 φορές, θα ξαπλώσει 100 φορές. Είναι ακόμα φθηνότερο από το να σταματήσεις.

Επιλέγουμε τα πλήκτρα για την κατάτμηση ώστε να κατανέμονται κανονικά. Δεν θέλουμε ο κατακερματισμός των κλειδιών μας να πέσει σε ένα στενό εύρος. Δηλαδή, το έτος γέννησης στο παραπάνω παράδειγμα είναι ένα κακό παράδειγμα. Πιο συγκεκριμένα, είναι καλό αν οι χρήστες μας κατανέμονται κανονικά ανά έτος γέννησης και κακό αν μιλάμε για μαθητές της 5ης τάξης - η κατάτμηση εκεί δεν θα είναι πολύ καλή.

Η ταξινόμηση επιλέγεται μία φορά στο στάδιο δημιουργίας κλειδιού συμπλέγματος. Εάν πρέπει να αλλάξει, θα πρέπει να ενημερώσουμε τον πίνακά μας με διαφορετικό κλειδί.

Και το πιο σημαντικό: αν χρειαστεί να ανακτήσουμε τα ίδια δεδομένα με 100 διαφορετικούς τρόπους, τότε θα έχουμε 100 διαφορετικούς πίνακες.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο