Ανάλυση TSDB στο Prometheus 2

Ανάλυση TSDB στο Prometheus 2

Η βάση δεδομένων χρονοσειρών (TSDB) στο Prometheus 2 είναι ένα εξαιρετικό παράδειγμα λύσης μηχανικής που προσφέρει σημαντικές βελτιώσεις σε σχέση με το Prometheus 2 storage v1 όσον αφορά τη συλλογή δεδομένων και την ταχύτητα εκτέλεσης ερωτημάτων και την αποδοτικότητα των πόρων. Εφαρμόζαμε το Prometheus 2 στο Percona Monitoring and Management (PMM) και είχα την ευκαιρία να κατανοήσω την απόδοση του Prometheus 2 TSDB. Σε αυτό το άρθρο θα μιλήσω για τα αποτελέσματα αυτών των παρατηρήσεων.

Προμηθέας Μέσος Φόρτος Εργασίας

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

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

Κατά τη διάρκεια της δοκιμής, εστίασα στην ικανότητα συγκέντρωσης δεδομένων. Ανέπτυξα το Prometheus 2.3.2 μεταγλωττισμένο με το Go 1.10.1 (ως μέρος του PMM 1.14) σε μια υπηρεσία Linode χρησιμοποιώντας αυτό το σενάριο: StackScript. Για την πιο ρεαλιστική παραγωγή φορτίου, με αυτό StackScript Έτρεξα αρκετούς κόμβους MySQL με πραγματικό φορτίο (Sysbench TPC-C Test), καθένας από τους οποίους εξομοίωσε 10 κόμβους Linux/MySQL.
Όλες οι ακόλουθες δοκιμές πραγματοποιήθηκαν σε διακομιστή Linode με οκτώ vCore και 32 GB μνήμης, με 20 προσομοιώσεις φόρτωσης που παρακολουθούν 800 παρουσίες MySQL. Ή, όσον αφορά τον Προμηθέα, 440 στόχοι (στόχοι), 380 αμοιβές (scrapes) ανά δευτερόλεπτο, 1,7 χιλιάδες εγγραφές (δείγματα) ανά δευτερόλεπτο και XNUMX εκατομμύρια ενεργές χρονοσειρές.

Σχέδιο

Η συνήθης παραδοσιακή προσέγγιση βάσης δεδομένων, συμπεριλαμβανομένης αυτής που χρησιμοποιεί ο Prometheus 1.x, είναι να όριο μνήμης. Εάν δεν είναι αρκετό για να χειριστείτε το φορτίο, θα αντιμετωπίσετε υψηλό λανθάνοντα χρόνο και ορισμένα αιτήματα δεν θα εκπληρωθούν. Η χρήση της μνήμης στο Prometheus 2 μπορεί να διαμορφωθεί μέσω ενός κλειδιού storage.tsdb.min-block-duration, το οποίο καθορίζει πόσο χρόνο θα διατηρηθούν οι εγγραφές στη μνήμη πριν από την έκπλυση στο δίσκο (η προεπιλογή είναι 2 ώρες). Η ποσότητα της απαιτούμενης μνήμης θα εξαρτηθεί από τον αριθμό των χρονοσειρών, των ετικετών και των scrapes, συν την καθαρή είσοδο. Όσον αφορά τον χώρο στο δίσκο, ο Prometheus στοχεύει στη χρήση 3 byte ανά εγγραφή (δείγμα). Από την άλλη πλευρά, οι απαιτήσεις μνήμης είναι πολύ μεγαλύτερες.

Αν και είναι δυνατό να διαμορφώσετε το μέγεθος του μπλοκ, δεν συνιστάται να το ρυθμίσετε με μη αυτόματο τρόπο, επομένως σας απομένει να δώσετε στον Prometheus όση μνήμη χρειάζεται για τον φόρτο εργασίας σας.
Εάν δεν υπάρχει αρκετή μνήμη για να υποστηρίξει την εισερχόμενη ροή μετρήσεων, ο Προμηθέας θα χάσει τη μνήμη ή θα πιαστεί από έναν δολοφόνο OOM.
Η προσθήκη ανταλλαγής για να καθυστερήσει τη συντριβή όταν ο Prometheus εξαντληθεί η μνήμη δεν βοηθά πραγματικά, επειδή η χρήση αυτής της δυνατότητας προκαλεί εκρήξεις στη μνήμη. Νομίζω ότι έχει να κάνει με το Go, τον σκουπιδοσυλλέκτη του και το πώς λειτουργεί με την ανταλλαγή.
Μια άλλη ενδιαφέρουσα προσέγγιση είναι να ρυθμίσετε το μπλοκ κεφαλής να ξεπλένεται στο δίσκο σε μια συγκεκριμένη ώρα, αντί να το μετράτε από τη στιγμή που ξεκίνησε η διαδικασία.

Ανάλυση TSDB στο Prometheus 2

Όπως μπορείτε να δείτε από το γράφημα, οι εκροές στο δίσκο γίνονται κάθε δύο ώρες. Εάν αλλάξετε την παράμετρο min-block-duration σε μία ώρα, τότε αυτές οι επαναφορές θα γίνονται κάθε ώρα, ξεκινώντας σε μισή ώρα.
Εάν θέλετε να χρησιμοποιήσετε αυτό και άλλα γραφήματα στην εγκατάσταση του Prometheus, μπορείτε να το χρησιμοποιήσετε ταμπλό. Σχεδιάστηκε για PMM, αλλά με μερικές τροποποιήσεις ταιριάζει σε οποιαδήποτε εγκατάσταση του Prometheus.
Έχουμε ένα ενεργό μπλοκ, που ονομάζεται μπλοκ κεφαλής, το οποίο είναι αποθηκευμένο στη μνήμη. μπλοκ με παλαιότερα δεδομένα είναι διαθέσιμα μέσω mmap(). Αυτό καταργεί την ανάγκη να ρυθμίσετε τις παραμέτρους της κρυφής μνήμης ξεχωριστά, αλλά σημαίνει επίσης ότι πρέπει να αφήσετε αρκετό χώρο για την προσωρινή μνήμη του λειτουργικού συστήματος, εάν θέλετε να υποβάλετε ερώτημα σε δεδομένα παλαιότερα από το μπλοκ κεφαλής.
Σημαίνει επίσης ότι η κατανάλωση εικονικής μνήμης του Prometheus θα φαίνεται αρκετά υψηλή, κάτι που δεν προκαλεί ανησυχία.

Ανάλυση TSDB στο Prometheus 2

Ένα άλλο ενδιαφέρον σημείο σχεδίασης είναι η χρήση του WAL (εγγραφή καταγραφής εκ των προτέρων). Όπως μπορείτε να δείτε από την τεκμηρίωση του αποθετηρίου, ο Prometheus χρησιμοποιεί το WAL για την αποφυγή σφαλμάτων. Συγκεκριμένοι μηχανισμοί για τη διασφάλιση της επιβίωσης των δεδομένων, δυστυχώς, δεν είναι καλά τεκμηριωμένοι. Το Prometheus 2.3.2 ξεπλένει το WAL στο δίσκο κάθε 10 δευτερόλεπτα και αυτή η ρύθμιση δεν μπορεί να διαμορφωθεί από το χρήστη.

Σφραγίδες

Το Prometheus TSDB έχει σχεδιαστεί με τον ίδιο τρόπο όπως η αποθήκευση LSM (Log Structured merge): το μπλοκ κεφαλής ξεπλένεται περιοδικά στο δίσκο, ενώ ο μηχανισμός συμπίεσης συγχωνεύει πολλά μπλοκ μεταξύ τους για να αποφύγει τη σάρωση πάρα πολλών μπλοκ σε ερωτήματα. Εδώ μπορείτε να δείτε τον αριθμό των μπλοκ που παρατήρησα στο σύστημα δοκιμής μετά από μια ημέρα φόρτωσης.

Ανάλυση TSDB στο Prometheus 2

Εάν θέλετε να μάθετε περισσότερα σχετικά με τον χώρο αποθήκευσης, μπορείτε να δείτε το αρχείο meta.json, το οποίο περιέχει πληροφορίες σχετικά με τα διαθέσιμα μπλοκ και πώς προέκυψαν.

{
       "ulid": "01CPZDPD1D9R019JS87TPV5MPE",
       "minTime": 1536472800000,
       "maxTime": 1536494400000,
       "stats": {
               "numSamples": 8292128378,
               "numSeries": 1673622,
               "numChunks": 69528220
       },
       "compaction": {
               "level": 2,
               "sources": [
                       "01CPYRY9MS465Y5ETM3SXFBV7X",
                       "01CPYZT0WRJ1JB1P0DP80VY5KJ",
                       "01CPZ6NR4Q3PDP3E57HEH760XS"
               ],
               "parents": [
                       {
                               "ulid": "01CPYRY9MS465Y5ETM3SXFBV7X",
                               "minTime": 1536472800000,
                               "maxTime": 1536480000000
                       },
                       {
                               "ulid": "01CPYZT0WRJ1JB1P0DP80VY5KJ",
                               "minTime": 1536480000000,
                               "maxTime": 1536487200000
                       },
                       {
                               "ulid": "01CPZ6NR4Q3PDP3E57HEH760XS",
                               "minTime": 1536487200000,
                               "maxTime": 1536494400000
                       }
               ]
       },
       "version": 1
}

Οι σφραγίδες στον Προμηθέα συνδέονται με τη στιγμή που το μπλοκ κεφαλής ξεπλένεται στο δίσκο. Σε αυτό το σημείο, μπορούν να πραγματοποιηθούν πολλές τέτοιες λειτουργίες.

Ανάλυση TSDB στο Prometheus 2

Φαίνεται ότι οι συμπιέσεις δεν περιορίζονται με κανέναν τρόπο και μπορούν να προκαλέσουν μεγάλες αιχμές εισόδου/εξόδου του δίσκου κατά την εκτέλεση.

Ανάλυση TSDB στο Prometheus 2

Αιχμές φορτίου CPU

Ανάλυση TSDB στο Prometheus 2

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

Ανάλυση TSDB στο Prometheus 2

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

Αποκατάσταση ανακαίνισης

Η αποκατάσταση από καταστροφή απαιτεί χρόνο και για καλό λόγο. Για μια εισερχόμενη ροή ενός εκατομμυρίου εγγραφών ανά δευτερόλεπτο, έπρεπε να περιμένω περίπου 25 λεπτά ενώ η ανάκτηση λάμβανε υπόψη τη μονάδα SSD.

level=info ts=2018-09-13T13:38:14.09650965Z caller=main.go:222 msg="Starting Prometheus" version="(version=2.3.2, branch=v2.3.2, revision=71af5e29e815795e9dd14742ee7725682fa14b7b)"
level=info ts=2018-09-13T13:38:14.096599879Z caller=main.go:223 build_context="(go=go1.10.1, user=Jenkins, date=20180725-08:58:13OURCE)"
level=info ts=2018-09-13T13:38:14.096624109Z caller=main.go:224 host_details="(Linux 4.15.0-32-generic #35-Ubuntu SMP Fri Aug 10 17:58:07 UTC 2018 x86_64 1bee9e9b78cf (none))"
level=info ts=2018-09-13T13:38:14.096641396Z caller=main.go:225 fd_limits="(soft=1048576, hard=1048576)"
level=info ts=2018-09-13T13:38:14.097715256Z caller=web.go:415 component=web msg="Start listening for connections" address=:9090
level=info ts=2018-09-13T13:38:14.097400393Z caller=main.go:533 msg="Starting TSDB ..."
level=info ts=2018-09-13T13:38:14.098718401Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536530400000 maxt=1536537600000 ulid=01CQ0FW3ME8Q5W2AN5F9CB7R0R
level=info ts=2018-09-13T13:38:14.100315658Z caller=web.go:467 component=web msg="router prefix" prefix=/prometheus
level=info ts=2018-09-13T13:38:14.101793727Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536732000000 maxt=1536753600000 ulid=01CQ78486TNX5QZTBF049PQHSM
level=info ts=2018-09-13T13:38:14.102267346Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536537600000 maxt=1536732000000 ulid=01CQ78DE7HSQK0C0F5AZ46YGF0
level=info ts=2018-09-13T13:38:14.102660295Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536775200000 maxt=1536782400000 ulid=01CQ7SAT4RM21Y0PT5GNSS146Q
level=info ts=2018-09-13T13:38:14.103075885Z caller=repair.go:39 component=tsdb msg="found healthy block" mint=1536753600000 maxt=1536775200000 ulid=01CQ7SV8WJ3C2W5S3RTAHC2GHB
level=error ts=2018-09-13T14:05:18.208469169Z caller=wal.go:275 component=tsdb msg="WAL corruption detected; truncating" err="unexpected CRC32 checksum d0465484, want 0" file=/opt/prometheus/data/.prom2-data/wal/007357 pos=15504363
level=info ts=2018-09-13T14:05:19.471459777Z caller=main.go:543 msg="TSDB started"
level=info ts=2018-09-13T14:05:19.471604598Z caller=main.go:603 msg="Loading configuration file" filename=/etc/prometheus.yml
level=info ts=2018-09-13T14:05:19.499156711Z caller=main.go:629 msg="Completed loading of configuration file" filename=/etc/prometheus.yml
level=info ts=2018-09-13T14:05:19.499228186Z caller=main.go:502 msg="Server is ready to receive web requests."

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

Ζέσταμα

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

Ανάλυση TSDB στο Prometheus 2

Ανάλυση TSDB στο Prometheus 2

Οι πτώσεις στη χρήση μνήμης υποδεικνύουν ότι ο Prometheus δεν μπορεί να διαμορφώσει όλες τις χρεώσεις από την αρχή και ότι ορισμένες πληροφορίες χάνονται.
Δεν έχω μάθει τους ακριβείς λόγους για την υψηλή χρήση της CPU και της μνήμης. Υποψιάζομαι ότι αυτό οφείλεται στη δημιουργία νέων χρονοσειρών στο head block με υψηλή συχνότητα.

Αιχμές CPU

Εκτός από τις πυκνώσεις, που δημιουργούν ένα αρκετά υψηλό φορτίο I/O, έχω παρατηρήσει σοβαρές αιχμές στο φορτίο της CPU κάθε δύο λεπτά. Οι εκρήξεις είναι μεγαλύτερες με υψηλή εισερχόμενη κίνηση και μοιάζουν σαν να προκαλούνται από τον συλλέκτη απορριμμάτων Go, τουλάχιστον ορισμένοι πυρήνες είναι πλήρως φορτωμένοι.

Ανάλυση TSDB στο Prometheus 2

Ανάλυση TSDB στο Prometheus 2

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

Ανάλυση TSDB στο Prometheus 2

Μπορεί επίσης να παρατηρήσετε ότι ο εξαγωγέας Prometheus κλείνει για ένα δευτερόλεπτο.

Ανάλυση TSDB στο Prometheus 2

Μπορούμε να δούμε συσχετίσεις με τη συλλογή απορριμμάτων (GC).

Ανάλυση TSDB στο Prometheus 2

Συμπέρασμα

Το TSDB στο Prometheus 2 είναι γρήγορο, ικανό να χειριστεί εκατομμύρια χρονοσειρές και ταυτόχρονα χιλιάδες εγγραφές ανά δευτερόλεπτο χρησιμοποιώντας μάλλον μέτριο υλικό. Η χρήση της CPU και του δίσκου I/O είναι επίσης εντυπωσιακή. Το παράδειγμά μου έδειξε έως και 200 μετρήσεις ανά δευτερόλεπτο ανά χρησιμοποιημένο πυρήνα.

Για να προγραμματίσετε την επέκταση, πρέπει να θυμάστε ότι υπάρχει αρκετή μνήμη και πρέπει να είναι πραγματική μνήμη. Η ποσότητα της χρησιμοποιούμενης μνήμης, την οποία παρατήρησα, ήταν περίπου 5 GB ανά 100 εγγραφές ανά δευτερόλεπτο της εισερχόμενης ροής, η οποία, συνολικά με την κρυφή μνήμη του λειτουργικού συστήματος, έδωσε περίπου 000 GB κατειλημμένης μνήμης.

Φυσικά, υπάρχει ακόμη πολλή δουλειά που πρέπει να γίνει για να εξημερωθούν οι αιχμές εισόδου/εξόδου της CPU και του δίσκου, και αυτό δεν προκαλεί έκπληξη, δεδομένου του πόσο νεαρό TSDB Prometheus 2 συγκρίνεται με τα InnoDB, TokuDB, RocksDB, WiredTiger, αλλά όλα είχαν παρόμοια προβλήματα στην αρχή του κύκλου ζωής τους.

Πηγή: www.habr.com

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