Θεωρία και πρακτική χρήσης HBase

Καλό απόγευμα Ονομάζομαι Danil Lipovoy, η ομάδα μας στη Sbertech άρχισε να χρησιμοποιεί το HBase ως χώρο αποθήκευσης για λειτουργικά δεδομένα. Στην πορεία της μελέτης του, έχει συσσωρευτεί εμπειρία που ήθελα να συστηματοποιήσω και να περιγράψω (ελπίζουμε ότι θα είναι χρήσιμο σε πολλούς). Όλα τα πειράματα παρακάτω πραγματοποιήθηκαν με τις εκδόσεις HBase 1.2.0-cdh5.14.2 και 2.0.0-cdh6.0.0-beta1.

  1. Γενική αρχιτεκτονική
  2. Εγγραφή δεδομένων στο HBASE
  3. Ανάγνωση δεδομένων από το HBASE
  4. Προσωρινή αποθήκευση δεδομένων
  5. Μαζική επεξεργασία δεδομένων MultiGet/MultiPut
  6. Στρατηγική για διαχωρισμό των πινάκων σε περιοχές (διαίρεση)
  7. Ανοχή σφαλμάτων, συμπύκνωση και εντοπιότητα δεδομένων
  8. Ρυθμίσεις και απόδοση
  9. Stress Testing
  10. Ευρήματα

1. Γενική αρχιτεκτονική

Θεωρία και πρακτική χρήσης HBase
Το backup Master ακούει τον καρδιακό παλμό του ενεργού στον κόμβο ZooKeeper και, σε περίπτωση εξαφάνισης, αναλαμβάνει τις λειτουργίες του master.

2. Γράψτε δεδομένα στο HBASE

Αρχικά, ας δούμε την απλούστερη περίπτωση - τη σύνταξη ενός αντικειμένου κλειδιού-τιμής σε έναν πίνακα χρησιμοποιώντας το put(rowkey). Ο πελάτης πρέπει πρώτα να βρει πού βρίσκεται ο διακομιστής περιοχής ρίζας (RRS), ο οποίος αποθηκεύει τον πίνακα hbase:meta. Λαμβάνει αυτές τις πληροφορίες από το ZooKeeper. Μετά από αυτό αποκτά πρόσβαση στο RRS και διαβάζει τον πίνακα hbase:meta, από τον οποίο εξάγει πληροφορίες σχετικά με το ποιος RegionServer (RS) είναι υπεύθυνος για την αποθήκευση δεδομένων για ένα δεδομένο κλειδί σειράς στον πίνακα ενδιαφέροντος. Για μελλοντική χρήση, ο πίνακας meta αποθηκεύεται προσωρινά από τον πελάτη και επομένως οι επόμενες κλήσεις πηγαίνουν πιο γρήγορα, απευθείας στο RS.

Στη συνέχεια, η RS, έχοντας λάβει ένα αίτημα, το γράφει πρώτα στο WriteAheadLog (WAL), το οποίο είναι απαραίτητο για την ανάκτηση σε περίπτωση συντριβής. Στη συνέχεια αποθηκεύει τα δεδομένα στο MemStore. Αυτό είναι ένα buffer στη μνήμη που περιέχει ένα ταξινομημένο σύνολο κλειδιών για μια δεδομένη περιοχή. Ένας πίνακας μπορεί να χωριστεί σε περιοχές (διαμερίσματα), καθεμία από τις οποίες περιέχει ένα διαχωρισμένο σύνολο κλειδιών. Αυτό σας επιτρέπει να τοποθετήσετε περιοχές σε διαφορετικούς διακομιστές για να επιτύχετε υψηλότερη απόδοση. Ωστόσο, παρά το προφανές αυτής της δήλωσης, θα δούμε αργότερα ότι αυτό δεν λειτουργεί σε όλες τις περιπτώσεις.

Μετά την τοποθέτηση μιας καταχώρισης στο MemStore, επιστρέφεται μια απάντηση στον πελάτη ότι η καταχώριση αποθηκεύτηκε με επιτυχία. Ωστόσο, στην πραγματικότητα αποθηκεύεται μόνο σε ένα buffer και φτάνει στο δίσκο μόνο αφού περάσει ένα ορισμένο χρονικό διάστημα ή όταν γεμίσει με νέα δεδομένα.

Θεωρία και πρακτική χρήσης HBase
Κατά την εκτέλεση της λειτουργίας «Διαγραφή», τα δεδομένα δεν διαγράφονται φυσικά. Απλώς επισημαίνονται ως διαγραμμένα και η ίδια η καταστροφή συμβαίνει τη στιγμή της κλήσης της κύριας συμπαγούς λειτουργίας, η οποία περιγράφεται λεπτομερέστερα στην παράγραφο 7.

Τα αρχεία σε μορφή HFile συγκεντρώνονται σε HDFS και από καιρό σε καιρό εκκινείται η δευτερεύουσα συμπαγής διαδικασία, η οποία απλώς συγχωνεύει μικρά αρχεία σε μεγαλύτερα χωρίς να διαγράφει τίποτα. Με τον καιρό, αυτό μετατρέπεται σε πρόβλημα που εμφανίζεται μόνο κατά την ανάγνωση δεδομένων (θα επανέλθουμε σε αυτό λίγο αργότερα).

Εκτός από τη διαδικασία φόρτωσης που περιγράφεται παραπάνω, υπάρχει μια πολύ πιο αποτελεσματική διαδικασία, η οποία είναι ίσως η ισχυρότερη πλευρά αυτής της βάσης δεδομένων - το BulkLoad. Βρίσκεται στο γεγονός ότι διαμορφώνουμε ανεξάρτητα HFiles και τα τοποθετούμε στο δίσκο, κάτι που μας επιτρέπει να κλιμακώνουμε τέλεια και να επιτυγχάνουμε πολύ αξιοπρεπείς ταχύτητες. Στην πραγματικότητα, ο περιορισμός εδώ δεν είναι το HBase, αλλά οι δυνατότητες του υλικού. Παρακάτω είναι τα αποτελέσματα εκκίνησης σε ένα σύμπλεγμα που αποτελείται από 16 RegionServers και 16 NodeManager YARN (CPU Xeon E5-2680 v4 @ 2.40GHz * 64 νήματα), έκδοση HBase 1.2.0-cdh5.14.2.

Θεωρία και πρακτική χρήσης HBase

Εδώ μπορείτε να δείτε ότι αυξάνοντας τον αριθμό των κατατμήσεων (περιοχών) στον πίνακα, καθώς και των εκτελεστών Spark, έχουμε αύξηση στην ταχύτητα λήψης. Επίσης, η ταχύτητα εξαρτάται από την ένταση της εγγραφής. Τα μεγάλα μπλοκ δίνουν μια αύξηση σε MB/sec, τα μικρά μπλοκ στον αριθμό των εισαγόμενων εγγραφών ανά μονάδα χρόνου, όλα τα άλλα είναι ίσα.

Μπορείτε επίσης να ξεκινήσετε τη φόρτωση σε δύο τραπέζια ταυτόχρονα και να έχετε διπλάσια ταχύτητα. Παρακάτω μπορείτε να δείτε ότι η εγγραφή μπλοκ 10 KB σε δύο πίνακες ταυτόχρονα γίνεται με ταχύτητα περίπου 600 MB/sec σε κάθε ένα (σύνολο 1275 MB/sec), που συμπίπτει με την ταχύτητα εγγραφής σε έναν πίνακα 623 MB/sec (βλ. Νο. 11 παραπάνω)

Θεωρία και πρακτική χρήσης HBase
Αλλά η δεύτερη εκτέλεση με εγγραφές 50 KB δείχνει ότι η ταχύτητα λήψης αυξάνεται ελαφρώς, πράγμα που δείχνει ότι πλησιάζει τις οριακές τιμές. Ταυτόχρονα, πρέπει να έχετε κατά νου ότι δεν δημιουργείται πρακτικά κανένα φορτίο στο ίδιο το HBASE, το μόνο που απαιτείται από αυτό είναι πρώτα να δώσετε δεδομένα από το hbase:meta και μετά την επένδυση των HFiles, να επαναφέρετε τα δεδομένα BlockCache και να αποθηκεύσετε το Το MemStore buffer στο δίσκο, εάν δεν είναι κενό.

3. Ανάγνωση δεδομένων από το HBASE

Αν υποθέσουμε ότι ο πελάτης έχει ήδη όλες τις πληροφορίες από το hbase:meta (βλ. σημείο 2), τότε το αίτημα πηγαίνει απευθείας στο RS όπου είναι αποθηκευμένο το απαιτούμενο κλειδί. Αρχικά, η αναζήτηση πραγματοποιείται στο MemCache. Ανεξάρτητα από το αν υπάρχουν δεδομένα εκεί ή όχι, η αναζήτηση πραγματοποιείται επίσης στο buffer BlockCache και, εάν χρειάζεται, στο HFiles. Εάν βρέθηκαν δεδομένα στο αρχείο, τοποθετούνται στο BlockCache και θα επιστραφούν πιο γρήγορα στο επόμενο αίτημα. Η αναζήτηση στο HFile είναι σχετικά γρήγορη χάρη στη χρήση του φίλτρου Bloom, δηλ. Έχοντας διαβάσει έναν μικρό όγκο δεδομένων, καθορίζει αμέσως αν αυτό το αρχείο περιέχει το απαιτούμενο κλειδί και αν όχι, μεταβαίνει στο επόμενο.

Θεωρία και πρακτική χρήσης HBase
Έχοντας λάβει δεδομένα από αυτές τις τρεις πηγές, η RS παράγει μια απάντηση. Συγκεκριμένα, μπορεί να μεταφέρει πολλές εκδόσεις ενός αντικειμένου που βρέθηκαν ταυτόχρονα, εάν ο πελάτης ζητήσει έκδοση εκδόσεων.

4. Προσωρινή αποθήκευση δεδομένων

Τα buffer MemStore και BlockCache καταλαμβάνουν έως και το 80% της εκχωρημένης μνήμης RS on-heap (το υπόλοιπο προορίζεται για εργασίες υπηρεσίας RS). Εάν η τυπική λειτουργία χρήσης είναι τέτοια που οι διαδικασίες γράφουν και διαβάζουν αμέσως τα ίδια δεδομένα, τότε είναι λογικό να μειωθεί το BlockCache και να αυξηθεί το MemStore, επειδή Όταν τα δεδομένα εγγραφής δεν εισέρχονται στην κρυφή μνήμη για ανάγνωση, το BlockCache θα χρησιμοποιείται λιγότερο συχνά. Το buffer BlockCache αποτελείται από δύο μέρη: LruBlockCache (πάντα on-heap) και BucketCache (συνήθως off-heap ή σε SSD). Το BucketCache θα πρέπει να χρησιμοποιείται όταν υπάρχουν πολλά αιτήματα ανάγνωσης και δεν ταιριάζουν στο LruBlockCache, κάτι που οδηγεί σε ενεργή εργασία του Garbage Collector. Ταυτόχρονα, δεν θα πρέπει να περιμένετε ριζική αύξηση της απόδοσης από τη χρήση της προσωρινής μνήμης ανάγνωσης, αλλά θα επανέλθουμε σε αυτό στην παράγραφο 8

Θεωρία και πρακτική χρήσης HBase
Υπάρχει ένα BlockCache για ολόκληρο το RS και υπάρχει ένα MemStore για κάθε τραπέζι (ένα για κάθε οικογένεια στηλών).

πως περιγράφεται Θεωρητικά, κατά την εγγραφή, τα δεδομένα δεν μπαίνουν στη μνήμη cache και πράγματι, τέτοιες παράμετροι CACHE_DATA_ON_WRITE για τον πίνακα και "Cache DATA on Write" για RS ορίζονται σε ψευδείς. Ωστόσο, στην πράξη, εάν γράψουμε δεδομένα στο MemStore, μετά τα ξεπλύνουμε στο δίσκο (άρα τον καθαρίζουμε), μετά διαγράψουμε το αρχείο που προκύπτει και κατόπιν εκτελώντας ένα αίτημα λήψης θα λάβουμε με επιτυχία τα δεδομένα. Επιπλέον, ακόμα κι αν απενεργοποιήσετε εντελώς το BlockCache και γεμίσετε τον πίνακα με νέα δεδομένα, στη συνέχεια επαναφέρετε το MemStore στο δίσκο, τα διαγράψετε και τα ζητήσετε από μια άλλη περίοδο λειτουργίας, θα συνεχίσουν να ανακτώνται από κάπου. Έτσι το HBase αποθηκεύει όχι μόνο δεδομένα, αλλά και μυστηριώδη μυστήρια.

hbase(main):001:0> create 'ns:magic', 'cf'
Created table ns:magic
Took 1.1533 seconds
hbase(main):002:0> put 'ns:magic', 'key1', 'cf:c', 'try_to_delete_me'
Took 0.2610 seconds
hbase(main):003:0> flush 'ns:magic'
Took 0.6161 seconds
hdfs dfs -mv /data/hbase/data/ns/magic/* /tmp/trash
hbase(main):002:0> get 'ns:magic', 'key1'
 cf:c      timestamp=1534440690218, value=try_to_delete_me

Η παράμετρος "Cache DATA on Read" έχει οριστεί σε false. Εάν έχετε οποιεσδήποτε ιδέες, ευπρόσδεκτοι να τις συζητήσετε στα σχόλια.

5. Μαζική επεξεργασία δεδομένων MultiGet/MultiPut

Η επεξεργασία μεμονωμένων αιτημάτων (Get/Put/Delete) είναι μια αρκετά δαπανηρή λειτουργία, επομένως, εάν είναι δυνατόν, θα πρέπει να τα συνδυάσετε σε μια λίστα ή λίστα, η οποία σας επιτρέπει να λάβετε σημαντική ώθηση απόδοσης. Αυτό ισχύει ιδιαίτερα για τη λειτουργία εγγραφής, αλλά κατά την ανάγνωση υπάρχει η ακόλουθη παγίδα. Το παρακάτω γράφημα δείχνει τον χρόνο ανάγνωσης 50 εγγραφών από το MemStore. Η ανάγνωση πραγματοποιήθηκε σε ένα νήμα και ο οριζόντιος άξονας δείχνει τον αριθμό των πλήκτρων στο αίτημα. Εδώ μπορείτε να δείτε ότι όταν αυξάνεται σε χίλια κλειδιά σε ένα αίτημα, ο χρόνος εκτέλεσης πέφτει, δηλ. η ταχύτητα αυξάνεται. Ωστόσο, με τη λειτουργία MSLAB ενεργοποιημένη από προεπιλογή, μετά από αυτό το όριο αρχίζει μια ριζική πτώση στην απόδοση και όσο μεγαλύτερη είναι η ποσότητα δεδομένων στην εγγραφή, τόσο μεγαλύτερος είναι ο χρόνος λειτουργίας.

Θεωρία και πρακτική χρήσης HBase

Οι δοκιμές πραγματοποιήθηκαν σε εικονική μηχανή, 8 πυρήνων, έκδοση HBase 2.0.0-cdh6.0.0-beta1.

Η λειτουργία MSLAB έχει σχεδιαστεί για να μειώνει τον κατακερματισμό του σωρού, που συμβαίνει λόγω της μίξης δεδομένων νέας και παλιάς γενιάς. Ως λύση, όταν το MSLAB είναι ενεργοποιημένο, τα δεδομένα τοποθετούνται σε σχετικά μικρά κελιά (κομμάτια) και υποβάλλονται σε επεξεργασία σε κομμάτια. Ως αποτέλεσμα, όταν ο όγκος στο ζητούμενο πακέτο δεδομένων υπερβαίνει το εκχωρημένο μέγεθος, η απόδοση μειώνεται απότομα. Από την άλλη πλευρά, η απενεργοποίηση αυτής της λειτουργίας δεν συνιστάται επίσης, καθώς θα οδηγήσει σε διακοπή λόγω GC σε στιγμές εντατικής επεξεργασίας δεδομένων. Μια καλή λύση είναι να αυξήσετε τον όγκο του κελιού στην περίπτωση ενεργού γραφής μέσω put ταυτόχρονα με την ανάγνωση. Αξίζει να σημειωθεί ότι το πρόβλημα δεν παρουσιάζεται εάν, μετά την εγγραφή, εκτελέσετε την εντολή flush, η οποία επαναφέρει το MemStore στο δίσκο ή εάν φορτώσετε χρησιμοποιώντας BulkLoad. Ο παρακάτω πίνακας δείχνει ότι τα ερωτήματα από το MemStore για μεγαλύτερα (και ίδια ποσότητα) δεδομένα οδηγούν σε επιβράδυνση. Ωστόσο, αυξάνοντας το chunksize επαναφέρουμε τον χρόνο επεξεργασίας στο κανονικό.

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

6. Στρατηγική για τη διαίρεση των πινάκων σε περιοχές (διαίρεση)

Δεδομένου ότι το HBase είναι μια αποθήκευση κλειδιού-τιμής και η κατάτμηση πραγματοποιείται με κλειδί, είναι εξαιρετικά σημαντικό να διαιρούνται ομοιόμορφα τα δεδομένα σε όλες τις περιοχές. Για παράδειγμα, η κατάτμηση ενός τέτοιου πίνακα σε τρία μέρη θα έχει ως αποτέλεσμα τα δεδομένα να χωριστούν σε τρεις περιοχές:

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

1000001
1000002
...
1100003

Δεδομένου ότι τα κλειδιά αποθηκεύονται ως πίνακας byte, όλα θα ξεκινούν το ίδιο και θα ανήκουν στην ίδια περιοχή #1 που αποθηκεύει αυτό το εύρος κλειδιών. Υπάρχουν διάφορες στρατηγικές κατάτμησης:

HexStringSplit – Μετατρέπει το κλειδί σε δεκαεξαδική κωδικοποιημένη συμβολοσειρά στην περιοχή "00000000" => "FFFFFFFF" και συμπληρώνει στα αριστερά με μηδενικά.

UniformSplit – Μετατρέπει το κλειδί σε πίνακα byte με δεκαεξαδική κωδικοποίηση στην περιοχή "00" => "FF" και πλήρωση στα δεξιά με μηδενικά.

Επιπλέον, μπορείτε να καθορίσετε οποιοδήποτε εύρος ή σύνολο πλήκτρων για διαχωρισμό και να διαμορφώσετε τον αυτόματο διαχωρισμό. Ωστόσο, μία από τις απλούστερες και πιο αποτελεσματικές προσεγγίσεις είναι το UniformSplit και η χρήση της συνένωσης κατακερματισμού, για παράδειγμα το πιο σημαντικό ζεύγος byte από την εκτέλεση του κλειδιού μέσω της συνάρτησης CRC32(rowkey) και του ίδιου του κλειδιού σειράς:

hash + rowkey

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

7. Ανοχή σφαλμάτων και τοποθεσία δεδομένων

Δεδομένου ότι μόνο μία περιοχή είναι υπεύθυνη για κάθε σύνολο κλειδιών, η λύση σε προβλήματα που σχετίζονται με σφάλματα ή παροπλισμό RS είναι η αποθήκευση όλων των απαραίτητων δεδομένων στο HDFS. Όταν το RS πέφτει, ο κύριος το εντοπίζει αυτό μέσω της απουσίας καρδιακού παλμού στον κόμβο ZooKeeper. Στη συνέχεια εκχωρεί την περιοχή που εξυπηρετείται σε άλλο RS και αφού τα HFiles αποθηκεύονται σε ένα κατανεμημένο σύστημα αρχείων, ο νέος κάτοχος τα διαβάζει και συνεχίζει να προβάλλει τα δεδομένα. Ωστόσο, δεδομένου ότι ορισμένα από τα δεδομένα ενδέχεται να βρίσκονται στο MemStore και δεν είχαν χρόνο να μπουν στο HFiles, το WAL, το οποίο είναι επίσης αποθηκευμένο σε HDFS, χρησιμοποιείται για την επαναφορά του ιστορικού λειτουργιών. Αφού εφαρμοστούν οι αλλαγές, η RS είναι σε θέση να ανταποκριθεί σε αιτήματα, αλλά η κίνηση οδηγεί στο γεγονός ότι ορισμένα από τα δεδομένα και οι διεργασίες που τα εξυπηρετούν καταλήγουν σε διαφορετικούς κόμβους, π.χ. η εντοπιότητα μειώνεται.

Η λύση στο πρόβλημα είναι η μεγάλη συμπύκνωση - αυτή η διαδικασία μετακινεί αρχεία σε εκείνους τους κόμβους που είναι υπεύθυνοι για αυτά (όπου βρίσκονται οι περιοχές τους), με αποτέλεσμα κατά τη διάρκεια αυτής της διαδικασίας το φορτίο στο δίκτυο και στους δίσκους να αυξάνεται απότομα. Ωστόσο, στο μέλλον, η πρόσβαση στα δεδομένα επιταχύνεται αισθητά. Επιπλέον, το major_compaction εκτελεί τη συγχώνευση όλων των HFiles σε ένα αρχείο σε μια περιοχή και επίσης καθαρίζει τα δεδομένα ανάλογα με τις ρυθμίσεις του πίνακα. Για παράδειγμα, μπορείτε να καθορίσετε τον αριθμό των εκδόσεων ενός αντικειμένου που πρέπει να διατηρηθούν ή τη διάρκεια ζωής μετά την οποία το αντικείμενο διαγράφεται φυσικά.

Αυτή η διαδικασία μπορεί να έχει πολύ θετική επίδραση στη λειτουργία του HBase. Η παρακάτω εικόνα δείχνει πώς υποβαθμίστηκε η απόδοση ως αποτέλεσμα της ενεργής εγγραφής δεδομένων. Εδώ μπορείτε να δείτε πώς 40 νήματα έγραψαν σε έναν πίνακα και 40 νήματα διαβάζουν ταυτόχρονα δεδομένα. Τα νήματα γραφής δημιουργούν όλο και περισσότερα HFiles, τα οποία διαβάζονται από άλλα νήματα. Ως αποτέλεσμα, όλο και περισσότερα δεδομένα πρέπει να αφαιρούνται από τη μνήμη και τελικά το GC αρχίζει να λειτουργεί, κάτι που ουσιαστικά παραλύει όλες τις εργασίες. Η εκτόξευση της μεγάλης συμπύκνωσης οδήγησε στον καθαρισμό των συντριμμιών που προέκυψαν και στην αποκατάσταση της παραγωγικότητας.

Θεωρία και πρακτική χρήσης HBase
Η δοκιμή πραγματοποιήθηκε σε 3 DataNodes και 4 RS (CPU Xeon E5-2680 v4 @ 2.40 GHz * 64 threads). Έκδοση HBase 1.2.0-cdh5.14.2

Αξίζει να σημειωθεί ότι η μεγάλη συμπίεση ξεκίνησε σε έναν «ζωντανό» πίνακα, στον οποίο τα δεδομένα εγγράφηκαν και διαβάζονταν ενεργά. Υπήρχε μια δήλωση στο διαδίκτυο ότι αυτό θα μπορούσε να οδηγήσει σε λανθασμένη απάντηση κατά την ανάγνωση δεδομένων. Για έλεγχο, ξεκίνησε μια διαδικασία που δημιούργησε νέα δεδομένα και τα έγραψε σε έναν πίνακα. Μετά από αυτό διάβασα αμέσως και έλεγξα αν η τιμή που προέκυψε συνέπεσε με αυτό που γράφτηκε. Κατά τη διάρκεια αυτής της διαδικασίας, η μεγάλη συμπίεση εκτελέστηκε περίπου 200 φορές και δεν καταγράφηκε ούτε μία αποτυχία. Ίσως το πρόβλημα εμφανίζεται σπάνια και μόνο κατά τη διάρκεια υψηλού φορτίου, επομένως είναι ασφαλέστερο να σταματήσετε τις διαδικασίες γραφής και ανάγνωσης όπως έχει προγραμματιστεί και να εκτελέσετε καθαρισμό για να αποτρέψετε τέτοιες αναστολές GC.

Επίσης, η μεγάλη συμπύκνωση δεν επηρεάζει την κατάσταση του MemStore· για να το ξεπλύνετε στο δίσκο και να το συμπυκνώσετε, πρέπει να χρησιμοποιήσετε το flush (connection.getAdmin().flush(TableName.valueOf(tblName))).

8. Ρυθμίσεις και απόδοση

Όπως ήδη αναφέρθηκε, το HBase δείχνει τη μεγαλύτερη επιτυχία του εκεί που δεν χρειάζεται να κάνει τίποτα, κατά την εκτέλεση του BulkLoad. Ωστόσο, αυτό ισχύει για τα περισσότερα συστήματα και άτομα. Ωστόσο, αυτό το εργαλείο είναι πιο κατάλληλο για την αποθήκευση δεδομένων μαζικά σε μεγάλα μπλοκ, ενώ εάν η διαδικασία απαιτεί πολλαπλά ανταγωνιστικά αιτήματα ανάγνωσης και εγγραφής, χρησιμοποιούνται οι εντολές Get και Put που περιγράφονται παραπάνω. Για τον προσδιορισμό των βέλτιστων παραμέτρων, πραγματοποιήθηκαν εκκινήσεις με διάφορους συνδυασμούς παραμέτρων και ρυθμίσεων πίνακα:

  • 10 νήματα εκτοξεύτηκαν ταυτόχρονα 3 φορές στη σειρά (ας το ονομάσουμε μπλοκ νημάτων).
  • Ο χρόνος λειτουργίας όλων των νημάτων σε ένα μπλοκ υπολογίστηκε κατά μέσο όρο και ήταν το τελικό αποτέλεσμα της λειτουργίας του μπλοκ.
  • Όλα τα νήματα λειτουργούσαν με τον ίδιο πίνακα.
  • Πριν από κάθε έναρξη του μπλοκ νήματος, πραγματοποιήθηκε μια σημαντική συμπίεση.
  • Κάθε μπλοκ εκτελούσε μόνο μία από τις ακόλουθες λειτουργίες:

-Βάζω
-Παίρνω
—Get+Put

  • Κάθε μπλοκ εκτέλεσε 50 επαναλήψεις της λειτουργίας του.
  • Το μέγεθος μπλοκ μιας εγγραφής είναι 100 byte, 1000 byte ή 10000 byte (τυχαία).
  • Τα μπλοκ κυκλοφόρησαν με διαφορετικούς αριθμούς κλειδιών που ζητήθηκαν (είτε ένα κλειδί είτε 10).
  • Τα μπλοκ εκτελέστηκαν κάτω από διαφορετικές ρυθμίσεις πίνακα. Οι παράμετροι άλλαξαν:

— BlockCache = ενεργοποιημένο ή απενεργοποιημένο
— BlockSize = 65 KB ή 16 KB
— Χωρίσματα = 1, 5 ή 30
— MSLAB = ενεργοποιημένο ή απενεργοποιημένο

Το μπλοκ λοιπόν μοιάζει με αυτό:

ένα. Η λειτουργία MSLAB ενεργοποιήθηκε/απενεργοποιήθηκε.
σι. Δημιουργήθηκε ένας πίνακας για τον οποίο ορίστηκαν οι ακόλουθες παράμετροι: BlockCache = true/none, BlockSize = 65/16 Kb, Partition = 1/5/30.
ντο. Η συμπίεση ορίστηκε σε GZ.
ρε. Ξεκίνησαν 10 νήματα ταυτόχρονα κάνοντας 1/10 πράξεις put/get/get+put σε αυτόν τον πίνακα με εγγραφές 100/1000/10000 byte, εκτελώντας 50 ερωτήματα στη σειρά (τυχαία πλήκτρα).
μι. Το σημείο δ επαναλήφθηκε τρεις φορές.
φά. Ο χρόνος λειτουργίας όλων των νημάτων υπολογίστηκε κατά μέσο όρο.

Όλοι οι πιθανοί συνδυασμοί δοκιμάστηκαν. Είναι προβλέψιμο ότι η ταχύτητα θα μειωθεί καθώς αυξάνεται το μέγεθος της εγγραφής ή ότι η απενεργοποίηση της προσωρινής αποθήκευσης θα προκαλέσει επιβράδυνση. Ωστόσο, ο στόχος ήταν να κατανοηθεί ο βαθμός και η σημασία της επιρροής κάθε παραμέτρου, έτσι τα δεδομένα που συλλέχθηκαν τροφοδοτήθηκαν στην είσοδο μιας συνάρτησης γραμμικής παλινδρόμησης, η οποία καθιστά δυνατή την αξιολόγηση της σημασίας χρησιμοποιώντας στατιστικές t. Παρακάτω είναι τα αποτελέσματα των μπλοκ που εκτελούν λειτουργίες Put. Πλήρες σετ συνδυασμών 2*2*3*2*3 = 144 επιλογές + 72 tk. μερικά έγιναν δύο φορές. Επομένως, υπάρχουν 216 σειρές συνολικά:

Θεωρία και πρακτική χρήσης HBase
Η δοκιμή πραγματοποιήθηκε σε ένα mini-cluster που αποτελείται από 3 DataNodes και 4 RS (CPU Xeon E5-2680 v4 @ 2.40 GHz * 64 νήματα). Έκδοση HBase 1.2.0-cdh5.14.2.

Η υψηλότερη ταχύτητα εισαγωγής 3.7 δευτερολέπτων επιτεύχθηκε με απενεργοποιημένη τη λειτουργία MSLAB, σε τραπέζι με ένα διαμέρισμα, με ενεργοποιημένο το BlockCache, BlockSize = 16, εγγραφές 100 byte, 10 τεμάχια ανά πακέτο.
Η χαμηλότερη ταχύτητα εισαγωγής των 82.8 sec επιτεύχθηκε με ενεργοποιημένη τη λειτουργία MSLAB, σε έναν πίνακα με ένα διαμέρισμα, με ενεργοποιημένο το BlockCache, BlockSize = 16, εγγραφές 10000 byte, 1 το καθένα.

Τώρα ας δούμε το μοντέλο. Βλέπουμε την καλή ποιότητα του μοντέλου που βασίζεται στο R2, αλλά είναι απολύτως σαφές ότι η παρέκταση αντενδείκνυται εδώ. Η πραγματική συμπεριφορά του συστήματος όταν αλλάζουν οι παράμετροι δεν θα είναι γραμμική· αυτό το μοντέλο δεν χρειάζεται για προβλέψεις, αλλά για την κατανόηση του τι συνέβη μέσα στις δεδομένες παραμέτρους. Για παράδειγμα, εδώ βλέπουμε από το κριτήριο του Student ότι οι παράμετροι BlockSize και BlockCache δεν έχουν σημασία για τη λειτουργία Put (η οποία είναι γενικά αρκετά προβλέψιμη):

Θεωρία και πρακτική χρήσης HBase
Αλλά το γεγονός ότι η αύξηση του αριθμού των κατατμήσεων οδηγεί σε μείωση της απόδοσης είναι κάπως απροσδόκητο (έχουμε ήδη δει τη θετική επίδραση της αύξησης του αριθμού των κατατμήσεων με BulkLoad), αν και κατανοητό. Πρώτον, για την επεξεργασία, πρέπει να δημιουργήσετε αιτήματα σε 30 περιοχές αντί για μία, και ο όγκος των δεδομένων δεν είναι τέτοιος ώστε αυτό να αποφέρει κέρδος. Δεύτερον, ο συνολικός χρόνος λειτουργίας καθορίζεται από το πιο αργό RS και δεδομένου ότι ο αριθμός των DataNodes είναι μικρότερος από τον αριθμό των RS, ορισμένες περιοχές έχουν μηδενική εντοπιότητα. Λοιπόν, ας δούμε τις πέντε πρώτες:

Θεωρία και πρακτική χρήσης HBase
Τώρα ας αξιολογήσουμε τα αποτελέσματα της εκτέλεσης των μπλοκ Get:

Θεωρία και πρακτική χρήσης HBase
Ο αριθμός των κατατμήσεων έχει χάσει τη σημασία του, κάτι που πιθανώς εξηγείται από το γεγονός ότι τα δεδομένα αποθηκεύονται καλά και η μνήμη cache ανάγνωσης είναι η πιο σημαντική (στατιστικά) παράμετρος. Φυσικά, η αύξηση του αριθμού των μηνυμάτων σε ένα αίτημα είναι επίσης πολύ χρήσιμη για την απόδοση. Κορυφαίες βαθμολογίες:

Θεωρία και πρακτική χρήσης HBase
Λοιπόν, τέλος, ας δούμε το μοντέλο του μπλοκ που εκτελέστηκε πρώτα get και μετά βάλαμε:

Θεωρία και πρακτική χρήσης HBase
Όλες οι παράμετροι είναι σημαντικές εδώ. Και τα αποτελέσματα των αρχηγών:

Θεωρία και πρακτική χρήσης HBase

9. Δοκιμή φορτίου

Λοιπόν, επιτέλους θα κυκλοφορήσουμε ένα περισσότερο ή λιγότερο αξιοπρεπές φορτίο, αλλά είναι πάντα πιο ενδιαφέρον όταν έχετε κάτι να συγκρίνετε. Στην ιστοσελίδα της DataStax, του βασικού προγραμματιστή της Cassandra, υπάρχει ευρήματα NT ενός αριθμού αποθηκευτικών χώρων NoSQL, συμπεριλαμβανομένης της έκδοσης HBase 0.98.6-1. Η φόρτωση πραγματοποιήθηκε από 40 νήματα, μέγεθος δεδομένων 100 byte, δίσκους SSD. Το αποτέλεσμα της δοκιμής των πράξεων Read-Modify-Write έδειξε τα ακόλουθα αποτελέσματα.

Θεωρία και πρακτική χρήσης HBase
Από όσο καταλαβαίνω, η ανάγνωση πραγματοποιήθηκε σε μπλοκ των 100 εγγραφών και για 16 κόμβους HBase, η δοκιμή DataStax έδειξε απόδοση 10 χιλιάδων πράξεων ανά δευτερόλεπτο.

Ευτυχώς που το σύμπλεγμα μας έχει επίσης 16 κόμβους, αλλά δεν είναι πολύ «τυχερό» που ο καθένας έχει 64 πυρήνες (threads), ενώ στο τεστ DataStax είναι μόνο 4. Από την άλλη, αυτοί έχουν μονάδες SSD, ενώ εμείς έχουμε HDD ή περισσότερο, η νέα έκδοση του HBase και η χρήση της CPU κατά τη φόρτωση πρακτικά δεν αυξήθηκε σημαντικά (οπτικά κατά 5-10 τοις εκατό). Ωστόσο, ας προσπαθήσουμε να αρχίσουμε να χρησιμοποιούμε αυτήν τη διαμόρφωση. Προεπιλεγμένες ρυθμίσεις πίνακα, η ανάγνωση πραγματοποιείται στο εύρος κλειδιών από 0 έως 50 εκατομμύρια τυχαία (δηλαδή, ουσιαστικά νέα κάθε φορά). Ο πίνακας περιέχει 50 εκατομμύρια εγγραφές, χωρισμένες σε 64 διαμερίσματα. Τα κλειδιά κατακερματίζονται χρησιμοποιώντας το crc32. Οι ρυθμίσεις πίνακα είναι προεπιλεγμένες, το MSLAB είναι ενεργοποιημένο. Εκκινώντας 40 νήματα, κάθε νήμα διαβάζει ένα σύνολο 100 τυχαίων κλειδιών και αμέσως γράφει τα 100 byte που δημιουργούνται πίσω σε αυτά τα κλειδιά.

Θεωρία και πρακτική χρήσης HBase
Stand: 16 DataNode και 16 RS (CPU Xeon E5-2680 v4 @ 2.40 GHz * 64 νήματα). Έκδοση HBase 1.2.0-cdh5.14.2.

Το μέσο αποτέλεσμα είναι πιο κοντά στις 40 χιλιάδες λειτουργίες ανά δευτερόλεπτο, κάτι που είναι σημαντικά καλύτερο από το τεστ DataStax. Ωστόσο, για πειραματικούς σκοπούς, μπορείτε να αλλάξετε ελαφρώς τις συνθήκες. Είναι πολύ απίθανο όλες οι εργασίες να εκτελούνται αποκλειστικά σε ένα τραπέζι και επίσης μόνο σε μοναδικά κλειδιά. Ας υποθέσουμε ότι υπάρχει ένα συγκεκριμένο "ζεστό" σύνολο πλήκτρων που δημιουργεί το κύριο φορτίο. Επομένως, ας προσπαθήσουμε να δημιουργήσουμε ένα φορτίο με μεγαλύτερες εγγραφές (10 KB), επίσης σε παρτίδες των 100, σε 4 διαφορετικούς πίνακες και περιορίζοντας το εύρος των ζητούμενων κλειδιών σε 50 χιλιάδες. Το παρακάτω γράφημα δείχνει την εκκίνηση 40 νημάτων, κάθε νήμα διαβάζει ένα σύνολο 100 πλήκτρων και αμέσως γράφει τυχαία 10 KB σε αυτά τα πλήκτρα πίσω.

Θεωρία και πρακτική χρήσης HBase
Stand: 16 DataNode και 16 RS (CPU Xeon E5-2680 v4 @ 2.40 GHz * 64 νήματα). Έκδοση HBase 1.2.0-cdh5.14.2.

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

Η ανάγνωση και η άμεση γραφή είναι ένα από τα πιο δύσκολα σενάρια εργασίας για το HBase. Εάν κάνετε μόνο μικρά αιτήματα τοποθέτησης, για παράδειγμα 100 byte, συνδυάζοντάς τα σε πακέτα των 10-50 χιλιάδων τεμαχίων, μπορείτε να λάβετε εκατοντάδες χιλιάδες λειτουργίες ανά δευτερόλεπτο και η κατάσταση είναι παρόμοια με τα αιτήματα μόνο για ανάγνωση. Αξίζει να σημειωθεί ότι τα αποτελέσματα είναι ριζικά καλύτερα από αυτά της DataStax, κυρίως λόγω αιτημάτων σε μπλοκ των 50 χιλιάδων.

Θεωρία και πρακτική χρήσης HBase
Stand: 16 DataNode και 16 RS (CPU Xeon E5-2680 v4 @ 2.40 GHz * 64 νήματα). Έκδοση HBase 1.2.0-cdh5.14.2.

10. Συμπεράσματα

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

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

Πηγή: www.habr.com

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