Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Η ιστορία της δημιουργίας του VKontakte βρίσκεται στη Wikipedia· την είπε ο ίδιος ο Pavel. Φαίνεται πως όλοι την ξέρουν ήδη. Σχετικά με τα εσωτερικά, την αρχιτεκτονική και τη δομή του ιστότοπου στο HighLoad++ Pavel μου είπε το 2010. Πολλοί διακομιστές έχουν διαρρεύσει από τότε, επομένως θα ενημερώσουμε τις πληροφορίες: θα τις ανατέψουμε, θα βγάλουμε τα εσωτερικά, θα το ζυγίσουμε και θα δούμε τη συσκευή VK από τεχνική άποψη.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Αλεξέι Ακούλοβιτς (AterCattus) προγραμματιστής υποστήριξης στην ομάδα VKontakte. Η απομαγνητοφώνηση αυτής της έκθεσης είναι μια συλλογική απάντηση σε συχνές ερωτήσεις σχετικά με τη λειτουργία της πλατφόρμας, την υποδομή, τους διακομιστές και την αλληλεπίδραση μεταξύ τους, αλλά όχι σχετικά με την ανάπτυξη, συγκεκριμένα περί σιδήρου. Ξεχωριστά, σχετικά με τις βάσεις δεδομένων και το τι διαθέτει η VK, σχετικά με τη συλλογή αρχείων καταγραφής και την παρακολούθηση ολόκληρου του έργου στο σύνολό του. Λεπτομέρειες κάτω από το κόψιμο.



Για περισσότερα από τέσσερα χρόνια ασχολούμαι με κάθε είδους εργασίες που σχετίζονται με το backend.

  • Μεταφόρτωση, αποθήκευση, επεξεργασία, διανομή πολυμέσων: βίντεο, ζωντανή ροή, ήχος, φωτογραφίες, έγγραφα.
  • Υποδομή, πλατφόρμα, παρακολούθηση προγραμματιστών, αρχεία καταγραφής, περιφερειακές κρυφές μνήμες, CDN, ιδιόκτητο πρωτόκολλο RPC.
  • Ενοποίηση με εξωτερικές υπηρεσίες: ειδοποιήσεις push, ανάλυση εξωτερικού συνδέσμου, ροή RSS.
  • Βοηθώντας τους συναδέλφους σε διάφορες ερωτήσεις, οι απαντήσεις στις οποίες απαιτούν βουτιά σε άγνωστο κώδικα.

Κατά τη διάρκεια αυτής της περιόδου, είχα ένα χέρι σε πολλά στοιχεία του ιστότοπου. Θέλω να μοιραστώ αυτή την εμπειρία.

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

Όλα, ως συνήθως, ξεκινούν με έναν διακομιστή ή μια ομάδα διακομιστών που δέχονται αιτήματα.

Μπροστινός διακομιστής

Ο μπροστινός διακομιστής δέχεται αιτήματα μέσω HTTPS, RTMP και WSS.

HTTPS - πρόκειται για αιτήματα για την κύρια και την έκδοση ιστού για κινητές συσκευές του ιστότοπου: vk.com και m.vk.com, και άλλους επίσημους και ανεπίσημους πελάτες του API μας: πελάτες για κινητές συσκευές, αγγελιοφόροι. Έχουμε δεξίωση RTMP-επισκεψιμότητα για Ζωντανές μεταδόσεις με ξεχωριστούς μπροστινούς διακομιστές και WSS- συνδέσεις για Streaming API.

Για HTTPS και WSS σε διακομιστές αξίζει nginx. Για εκπομπές RTMP, πρόσφατα μεταβήκαμε στη δική μας λύση είχε, αλλά ξεφεύγει από το πεδίο εφαρμογής της έκθεσης. Για ανοχή σφαλμάτων, αυτοί οι διακομιστές διαφημίζουν κοινές διευθύνσεις IP και ενεργούν ομαδικά, ώστε εάν υπάρχει πρόβλημα σε έναν από τους διακομιστές, τα αιτήματα των χρηστών να μην χάνονται. Για το HTTPS και το WSS, αυτοί οι ίδιοι διακομιστές κρυπτογραφούν την κυκλοφορία προκειμένου να αναλάβουν μέρος του φορτίου της CPU.

Δεν θα μιλήσουμε περαιτέρω για WSS και RTMP, αλλά μόνο για τυπικά αιτήματα HTTPS, τα οποία συνήθως σχετίζονται με ένα έργο web.

Backend

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

Το διακομιστές kPHP, στο οποίο εκτελείται ο δαίμονας HTTP, επειδή το HTTPS είναι ήδη αποκρυπτογραφημένο. Ο kPHP είναι ένας διακομιστής που εκτελείται μοντέλα prefork: ξεκινά μια κύρια διαδικασία, μια δέσμη θυγατρικών διεργασιών, τους περνάει υποδοχές ακρόασης και επεξεργάζονται τα αιτήματά τους. Σε αυτήν την περίπτωση, οι διεργασίες δεν επανεκκινούνται μεταξύ κάθε αιτήματος από τον χρήστη, αλλά απλώς επαναφέρουν την κατάστασή τους στην αρχική κατάσταση μηδενικής τιμής - αίτημα μετά από αίτημα, αντί για επανεκκίνηση.

Κατανομή φορτίου

Όλα τα backend μας δεν είναι μια τεράστια δεξαμενή μηχανημάτων που μπορούν να επεξεργαστούν οποιοδήποτε αίτημα. Εμείς αυτοί χωρίζονται σε ξεχωριστές ομάδες: γενικό, κινητό, api, βίντεο, σταδιοποίηση... Το πρόβλημα σε μια ξεχωριστή ομάδα μηχανών δεν θα επηρεάσει όλα τα άλλα. Σε περίπτωση προβλημάτων με το βίντεο, ο χρήστης που ακούει μουσική δεν θα γνωρίζει καν για τα προβλήματα. Σε ποιο backend θα στείλετε το αίτημα αποφασίζεται από το nginx στο μπροστινό μέρος σύμφωνα με τη διαμόρφωση.

Μετρική συλλογή και εξισορρόπηση

Για να καταλάβουμε πόσα αυτοκίνητα πρέπει να έχουμε σε κάθε ομάδα, εμείς μην βασίζεστε στο QPS. Τα backends είναι διαφορετικά, έχουν διαφορετικά αιτήματα, κάθε αίτημα έχει διαφορετική πολυπλοκότητα στον υπολογισμό του QPS. Γι' αυτό εμείς λειτουργούμε με την έννοια του φορτίου στο διακομιστή στο σύνολό του - στη CPU και perf.

Έχουμε χιλιάδες τέτοιους διακομιστές. Κάθε φυσικός διακομιστής εκτελεί μια ομάδα kPHP για την ανακύκλωση όλων των πυρήνων (επειδή το kPHP είναι μονού νήματος).

Διακομιστής περιεχομένου

Το CS ή Content Server είναι χώρος αποθήκευσης. Ο CS είναι ένας διακομιστής που αποθηκεύει αρχεία και επεξεργάζεται επίσης τα μεταφορτωμένα αρχεία και όλα τα είδη σύγχρονων εργασιών στο παρασκήνιο που του αναθέτει η κύρια διεπαφή ιστού.

Έχουμε δεκάδες χιλιάδες φυσικούς διακομιστές που αποθηκεύουν αρχεία. Στους χρήστες αρέσει να ανεβάζουν αρχεία και μας αρέσει να τα αποθηκεύουμε και να τα κοινοποιούμε. Μερικοί από αυτούς τους διακομιστές είναι κλειστοί από ειδικούς διακομιστές pu/pp.

pu/pp

Αν ανοίξατε την καρτέλα δικτύου στο VK, είδατε pu/pp.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Τι είναι το pu/pp; Εάν κλείνουμε τον έναν διακομιστή μετά τον άλλο, τότε υπάρχουν δύο επιλογές για τη μεταφόρτωση και τη λήψη ενός αρχείου στον διακομιστή που έκλεισε: άμεσα μέσω http://cs100500.userapi.com/path ή μέσω ενδιάμεσου διακομιστή - http://pu.vk.com/c100500/path.

Το Pu είναι το ιστορικό όνομα για τη μεταφόρτωση φωτογραφιών και το pp είναι ο διακομιστής μεσολάβησης φωτογραφιών. Δηλαδή, ένας διακομιστής είναι για ανέβασμα φωτογραφιών και ένας άλλος για ανέβασμα. Τώρα δεν φορτώνονται μόνο φωτογραφίες, αλλά το όνομα έχει διατηρηθεί.

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

Δεδομένου ότι τα μηχανήματα είναι κλειστά από τα άλλα μηχανήματα μας, έχουμε την πολυτέλεια να μην τους δίνουμε «λευκές» εξωτερικές IP, και δώσε "γκρίζο". Με αυτόν τον τρόπο εξοικονομήσαμε το IP pool και εγγυηθήκαμε την προστασία των μηχανημάτων από εξωτερική πρόσβαση - απλά δεν υπάρχει IP για να μπείτε σε αυτό.

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

Το επίμαχο σημείο είναι ότι στην προκειμένη περίπτωση ο πελάτης διατηρεί λιγότερες συνδέσεις. Εάν υπάρχει η ίδια IP για πολλά μηχανήματα - με τον ίδιο κεντρικό υπολογιστή: pu.vk.com ή pp.vk.com, το πρόγραμμα περιήγησης πελάτη έχει ένα όριο στον αριθμό των ταυτόχρονων αιτημάτων σε έναν κεντρικό υπολογιστή. Αλλά στην εποχή του πανταχού HTTP/2, πιστεύω ότι αυτό δεν είναι πλέον τόσο σχετικό.

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

Πριν από λίγο καιρό αποκτήσαμε μια βελτιωμένη έκδοση του διακομιστή μεσολάβησης. Τώρα θα σας πω πώς διαφέρουν από τα συνηθισμένα και γιατί είναι απαραίτητο.

Κυρ.

Τον Σεπτέμβριο του 2017, η Oracle, η οποία είχε αγοράσει προηγουμένως τη Sun, απέλυσε τεράστιο αριθμό υπαλλήλων της Sun. Μπορούμε να πούμε ότι αυτή τη στιγμή η εταιρεία έπαψε να υπάρχει. Κατά την επιλογή ενός ονόματος για το νέο σύστημα, οι διαχειριστές μας αποφάσισαν να αποτίσουν φόρο τιμής στη μνήμη αυτής της εταιρείας και ονόμασαν το νέο σύστημα Sun. Μεταξύ μας την αποκαλούμε απλά «ήλιους».

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

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

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

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

Υποστήριξη βάρους. Τώρα μπορούμε να αντέξουμε οικονομικά να εγκαταστήσουμε μηχανήματα διαφορετικής ισχύος ανάλογα με τις ανάγκες και επίσης, σε περίπτωση προσωρινών προβλημάτων, να αλλάξουμε τα βάρη των «ηλίων» που λειτουργούν για να μειώσουν το φορτίο πάνω τους, ώστε να «ξεκουραστούν» και να αρχίσουν να λειτουργούν ξανά.

Κοινή χρήση κατά αναγνωριστικό περιεχομένου. Ένα αστείο πράγμα με την κοινή χρήση: συνήθως μοιράζουμε περιεχόμενο έτσι ώστε διαφορετικοί χρήστες να πηγαίνουν στο ίδιο αρχείο μέσω του ίδιου "sun" ώστε να έχουν μια κοινή κρυφή μνήμη.

Πρόσφατα κυκλοφορήσαμε την εφαρμογή «Τριφύλλι». Πρόκειται για ένα διαδικτυακό κουίζ σε ζωντανή μετάδοση, όπου ο οικοδεσπότης κάνει ερωτήσεις και οι χρήστες απαντούν σε πραγματικό χρόνο, επιλέγοντας επιλογές. Η εφαρμογή έχει μια συνομιλία όπου οι χρήστες μπορούν να συνομιλούν. Μπορεί να συνδεθεί ταυτόχρονα στην εκπομπή περισσότερα από 100 χιλιάδες άτομα. Όλοι γράφουν μηνύματα που αποστέλλονται σε όλους τους συμμετέχοντες και ένα avatar συνοδεύεται από το μήνυμα. Εάν 100 χιλιάδες άνθρωποι έρχονται για ένα avatar σε έναν «ήλιο», τότε μπορεί μερικές φορές να κυλήσει πίσω από ένα σύννεφο.

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

Ήλιος από μέσα

Reverse proxy στο nginx, cache είτε σε RAM είτε σε γρήγορους δίσκους Optane/NVMe. Παράδειγμα: http://sun4-2.userapi.com/c100500/path — ένας σύνδεσμος προς τον «ήλιο», ο οποίος βρίσκεται στην τέταρτη περιοχή, τη δεύτερη ομάδα διακομιστών. Κλείνει το αρχείο διαδρομής, το οποίο βρίσκεται φυσικά στον διακομιστή 100500.

κρύπτη

Προσθέτουμε έναν ακόμη κόμβο στο αρχιτεκτονικό μας σχήμα - το περιβάλλον προσωρινής αποθήκευσης.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

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

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

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

Για να προσδιορίσουμε την περιοχή του χρήστη, εμείς συλλέγουμε προθέματα δικτύου BGP που ανακοινώνονται στις περιοχές. Στην περίπτωση εναλλακτικής, πρέπει επίσης να αναλύσουμε τη βάση δεδομένων geoip εάν δεν μπορούσαμε να βρούμε την IP με προθέματα. Καθορίζουμε την περιοχή από την IP του χρήστη. Στον κώδικα, μπορούμε να δούμε μία ή περισσότερες περιοχές του χρήστη - εκείνα τα σημεία στα οποία βρίσκεται πιο κοντά γεωγραφικά.

Πώς λειτουργεί;

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

Ταυτόχρονα, δαίμονες - υπηρεσίες σε περιοχές - κατά καιρούς έρχονται στο API και λένε: «Είμαι τέτοια και τέτοια κρυφή μνήμη, δώστε μου μια λίστα με τα πιο δημοφιλή αρχεία στην περιοχή μου που δεν υπάρχουν ακόμα σε εμένα. ” Το API παραδίδει ένα σωρό αρχεία ταξινομημένα κατά βαθμολογία, ο δαίμονας τα κατεβάζει, τα μεταφέρει στις περιοχές και παραδίδει τα αρχεία από εκεί. Αυτή είναι η θεμελιώδης διαφορά μεταξύ pu/pp και Sun από τις κρυφές μνήμες: δίνουν το αρχείο μέσω του εαυτού τους αμέσως, ακόμα κι αν αυτό το αρχείο δεν βρίσκεται στη μνήμη cache, και η κρυφή μνήμη πρώτα κατεβάζει το αρχείο στον εαυτό της και μετά αρχίζει να το δίνει πίσω.

Σε αυτή την περίπτωση παίρνουμε περιεχόμενο πιο κοντά στους χρήστες και την κατανομή του φορτίου του δικτύου. Για παράδειγμα, μόνο από την κρυφή μνήμη της Μόσχας διανέμουμε περισσότερα από 1 Tbit/s κατά τις ώρες αιχμής.

Αλλά υπάρχουν προβλήματα - Οι διακομιστές cache δεν είναι ελαστικοί. Για εξαιρετικά δημοφιλές περιεχόμενο, μερικές φορές δεν υπάρχει αρκετό δίκτυο για ξεχωριστό διακομιστή. Οι διακομιστές μας cache είναι 40-50 Gbit/s, αλλά υπάρχει περιεχόμενο που φράζει εντελώς ένα τέτοιο κανάλι. Προχωράμε προς την υλοποίηση αποθήκευσης περισσότερων του ενός αντιγράφων δημοφιλών αρχείων στην περιοχή. Ελπίζω ότι θα το εφαρμόσουμε μέχρι το τέλος του χρόνου.

Εξετάσαμε τη γενική αρχιτεκτονική.

  • Μπροστινοί διακομιστές που δέχονται αιτήματα.
  • Backend που επεξεργάζονται αιτήματα.
  • Αποθηκευτικοί χώροι που κλείνουν από δύο τύπους διακομιστή μεσολάβησης.
  • Περιφερειακές κρύπτες.

Τι λείπει από αυτό το διάγραμμα; Φυσικά, οι βάσεις δεδομένων στις οποίες αποθηκεύουμε δεδομένα.

Βάσεις δεδομένων ή μηχανές

Δεν τις λέμε βάσεις δεδομένων, αλλά μηχανές - Κινητήρες, γιατί πρακτικά δεν έχουμε βάσεις δεδομένων με τη γενικά αποδεκτή έννοια.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Αυτό είναι ένα απαραίτητο μέτρο.. Αυτό συνέβη επειδή το 2008-2009, όταν η VK είχε εκρηκτική αύξηση στη δημοτικότητα, το έργο λειτούργησε εξ ολοκλήρου σε MySQL και Memcache και υπήρχαν προβλήματα. Η MySQL λάτρευε να κολλάει και να καταστρέφει αρχεία, μετά από τα οποία δεν ανακτούσε, και η απόδοση του Memcache σταδιακά υποβαθμίστηκε και έπρεπε να γίνει επανεκκίνηση.

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

Η λύση ήταν επιτυχής. Υπήρχε μια ευκαιρία να γίνει αυτό, όπως και μια ακραία αναγκαιότητα, γιατί δεν υπήρχαν άλλοι τρόποι κλιμάκωσης εκείνη την εποχή. Δεν υπήρχαν πολλές βάσεις δεδομένων, η NoSQL δεν υπήρχε ακόμα, υπήρχαν μόνο MySQL, Memcache, PostrgreSQL - και αυτό είναι.

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

Τύποι κινητήρων

Η ομάδα έγραψε αρκετούς κινητήρες. Εδώ είναι μόνο μερικά από αυτά: φίλος, συμβουλές, εικόνα, ipdb, γράμματα, λίστες, αρχεία καταγραφής, memcached, meowdb, ειδήσεις, νοστράδαμος, φωτογραφία, λίστες αναπαραγωγής, pmemcached, sandbox, αναζήτηση, αποθήκευση, επισημάνσεις "μου αρέσει", εργασίες, ...

Για κάθε εργασία που απαιτεί συγκεκριμένη δομή δεδομένων ή επεξεργάζεται άτυπα αιτήματα, η ομάδα C γράφει μια νέα μηχανή. Γιατί όχι.

Έχουμε ξεχωριστό κινητήρα μνήμη, που μοιάζει με κανονικό, αλλά με ένα σωρό καλούδια, και που δεν επιβραδύνει. Όχι το ClickHouse, αλλά λειτουργεί επίσης. Διατίθεται χωριστά pmemcached - Είναι επίμονο memcached, το οποίο μπορεί επίσης να αποθηκεύσει δεδομένα στο δίσκο, επιπλέον, από ό,τι χωράει στη μνήμη RAM, ώστε να μην χάνονται δεδομένα κατά την επανεκκίνηση. Υπάρχουν διάφοροι κινητήρες για μεμονωμένες εργασίες: ουρές, λίστες, σετ - όλα όσα απαιτεί το έργο μας.

Συστάδες

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

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

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

RPC proxy

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

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

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

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

Συγκεκριμένες υλοποιήσεις

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

Για τη MySQL, την οποία έχουμε ακόμα εδώ κι εκεί, χρησιμοποιούμε db-proxy και για το ClickHouse - Γατάκι.

Λειτουργεί γενικά έτσι. Υπάρχει ένας συγκεκριμένος διακομιστής, εκτελεί kPHP, Go, Python - γενικά, κάθε κώδικας που μπορεί να χρησιμοποιήσει το πρωτόκολλο RPC μας. Ο κώδικας εκτελείται τοπικά σε έναν διακομιστή μεσολάβησης RPC - κάθε διακομιστής όπου βρίσκεται ο κώδικας εκτελεί τον δικό του τοπικό διακομιστή μεσολάβησης. Κατόπιν αιτήματος, ο πληρεξούσιος καταλαβαίνει πού να πάει.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

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

Ένα παράδειγμα ενός σχήματος TL σύμφωνα με το οποίο λειτουργούν όλοι οι κινητήρες.

memcache.not_found                                = memcache.Value;
memcache.strvalue	value:string flags:int = memcache.Value;
memcache.addOrIncr key:string flags:int delay:int value:long = memcache.Value;

tasks.task
    fields_mask:#
    flags:int
    tag:%(Vector int)
    data:string
    id:fields_mask.0?long
    retries:fields_mask.1?int
    scheduled_time:fields_mask.2?int
    deadline:fields_mask.3?int
    = tasks.Task;
 
tasks.addTask type_name:string queue_id:%(Vector int) task:%tasks.Task = Long;

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

RPC πάνω από TL πάνω από TCP/UDP… UDP;

Έχουμε ένα πρωτόκολλο RPC για την εκτέλεση αιτημάτων μηχανών που εκτελείται πάνω από το σχήμα TL. Όλα αυτά λειτουργούν μέσω μιας σύνδεσης TCP/UDP. Το TCP είναι κατανοητό, αλλά γιατί χρειαζόμαστε συχνά το UDP;

Το UDP βοηθά αποφύγετε το πρόβλημα ενός τεράστιου αριθμού συνδέσεων μεταξύ διακομιστών. Εάν κάθε διακομιστής έχει έναν διακομιστή μεσολάβησης RPC και, γενικά, μπορεί να πάει σε οποιαδήποτε μηχανή, τότε υπάρχουν δεκάδες χιλιάδες συνδέσεις TCP ανά διακομιστή. Υπάρχει ένα φορτίο, αλλά είναι άχρηστο. Στην περίπτωση του UDP αυτό το πρόβλημα δεν υπάρχει.

Χωρίς περιττή χειραψία TCP. Αυτό είναι ένα τυπικό πρόβλημα: όταν εκκινείται ένας νέος κινητήρας ή ένας νέος διακομιστής, δημιουργούνται πολλές συνδέσεις TCP ταυτόχρονα. Για μικρά αιτήματα ελαφρού βάρους, για παράδειγμα, ωφέλιμο φορτίο UDP, όλη η επικοινωνία μεταξύ του κώδικα και του κινητήρα είναι δύο πακέτα UDP: το ένα πετά προς τη μία κατεύθυνση, το δεύτερο προς την άλλη. Ένα ταξίδι μετ' επιστροφής - και ο κωδικός έλαβε απάντηση από τον κινητήρα χωρίς χειραψία.

Ναι, όλα λειτουργούν με πολύ μικρό ποσοστό απώλειας πακέτων. Το πρωτόκολλο έχει υποστήριξη για αναμεταδόσεις και χρονικά όρια, αλλά αν χάσουμε πολλά, θα πάρουμε σχεδόν TCP, κάτι που δεν είναι κερδοφόρο. Δεν οδηγούμε το UDP σε ωκεανούς.

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

Μόνιμη αποθήκευση δεδομένων

Οι μηχανές γράφουν binlogs. Το binlog είναι ένα αρχείο στο τέλος του οποίου προστίθεται ένα συμβάν για μια αλλαγή κατάστασης ή δεδομένων. Σε διαφορετικές λύσεις ονομάζεται διαφορετικά: δυαδικό αρχείο καταγραφής, WAL, ΑΟΦ, αλλά η αρχή είναι η ίδια.

Για να μην ξαναδιαβάσει ο κινητήρας ολόκληρο το binlog για πολλά χρόνια κατά την επανεκκίνηση, γράφουν οι κινητήρες στιγμιότυπα - τρέχουσα κατάσταση. Εάν είναι απαραίτητο, διαβάζουν πρώτα από αυτό και μετά ολοκληρώνουν την ανάγνωση από το binlog. Όλα τα binlog είναι γραμμένα στην ίδια δυαδική μορφή - σύμφωνα με το σχήμα TL, έτσι ώστε οι διαχειριστές να μπορούν να τα διαχειρίζονται εξίσου με τα εργαλεία τους. Δεν υπάρχει τέτοια ανάγκη για στιγμιότυπα. Υπάρχει μια γενική κεφαλίδα που υποδεικνύει ποιανού το στιγμιότυπο είναι int, η μαγεία του κινητήρα και ποιο σώμα δεν είναι σημαντικό για κανέναν. Αυτό είναι ένα πρόβλημα με τον κινητήρα που κατέγραψε το στιγμιότυπο.

Θα περιγράψω γρήγορα την αρχή της λειτουργίας. Υπάρχει ένας διακομιστής στον οποίο λειτουργεί ο κινητήρας. Ανοίγει ένα νέο κενό binlog για γράψιμο και γράφει ένα συμβάν για αλλαγή σε αυτό.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

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

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Κάποια στιγμή, όταν επανεκκινηθεί ο κινητήρας, θα υπάρχει και ένα binlog και ένα στιγμιότυπο στον δίσκο. Ο κινητήρας διαβάζει ολόκληρο το στιγμιότυπο και ανεβάζει την κατάστασή του σε ένα συγκεκριμένο σημείο.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Διαβάζει τη θέση που βρισκόταν τη στιγμή που δημιουργήθηκε το στιγμιότυπο και το μέγεθος του binlog.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Διαβάζει το τέλος του binlog για να πάρει την τρέχουσα κατάσταση και συνεχίζει να γράφει περαιτέρω συμβάντα. Αυτό είναι ένα απλό σχέδιο· όλοι οι κινητήρες μας λειτουργούν σύμφωνα με αυτό.

Αντιγραφή δεδομένων

Ως αποτέλεσμα, η αναπαραγωγή δεδομένων στο δικό μας με βάση δηλώσεις — γράφουμε στο binlog όχι αλλαγές σελίδας, αλλά συγκεκριμένα αιτήματα αλλαγής. Πολύ παρόμοιο με αυτό που έρχεται μέσω του δικτύου, μόνο ελαφρώς τροποποιημένο.

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

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Αν χρειαστεί αντίγραφο ανάγνωσηςΓια να μειωθεί το φορτίο ανάγνωσης της CPU, απλά εκκινείται η μηχανή ανάγνωσης, η οποία διαβάζει το τέλος του binlog και εκτελεί αυτές τις εντολές τοπικά.

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

Κοινή χρήση δεδομένων σε διακομιστή μεσολάβησης RPC

Πώς λειτουργεί ο διαμοιρασμός; Πώς κατανοεί ο διακομιστής μεσολάβησης σε ποιο θραύσμα συμπλέγματος να στείλει; Ο κωδικός δεν λέει: "Αποστολή για 15 θραύσματα!" - Όχι, αυτό γίνεται από τον πληρεξούσιο.

Το απλούστερο σχήμα είναι το firstint — ο πρώτος αριθμός στο αίτημα.

get(photo100_500) => 100 % N.

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

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

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

hash(photo100_500) => 3539886280 % N

Παίρνουμε επίσης τον κατακερματισμό, το υπόλοιπο της διαίρεσης και τον αριθμό θραυσμάτων.

Και οι δύο αυτές επιλογές λειτουργούν μόνο εάν είμαστε προετοιμασμένοι για το γεγονός ότι όταν αυξήσουμε το μέγεθος του συμπλέγματος, θα το χωρίσουμε ή θα το αυξήσουμε πολλαπλάσιες φορές. Για παράδειγμα, είχαμε 16 θραύσματα, δεν έχουμε αρκετά, θέλουμε περισσότερα - μπορούμε να πάρουμε με ασφάλεια 32 χωρίς διακοπές. Εάν θέλουμε να αυξήσουμε όχι πολλαπλάσια, θα υπάρξει χρόνος διακοπής λειτουργίας, επειδή δεν θα μπορούμε να χωρίσουμε τα πάντα με ακρίβεια χωρίς απώλειες. Αυτές οι επιλογές είναι χρήσιμες, αλλά όχι πάντα.

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

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

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

κούτσουρα

Γράφουμε αρχεία καταγραφής με διάφορους τρόπους. Το πιο προφανές και απλό είναι εγγραφή αρχείων καταγραφής στο memcache.

ring-buffer: prefix.idx = line

Υπάρχει ένα πρόθεμα κλειδιού - το όνομα του αρχείου καταγραφής, μια γραμμή και υπάρχει το μέγεθος αυτού του αρχείου καταγραφής - ο αριθμός των γραμμών. Παίρνουμε έναν τυχαίο αριθμό από το 0 στον αριθμό των γραμμών μείον 1. Το κλειδί στη μνήμη cache είναι ένα πρόθεμα που συνδέεται με αυτόν τον τυχαίο αριθμό. Αποθηκεύουμε τη γραμμή καταγραφής και την τρέχουσα ώρα στην τιμή.

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

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

Ο κινητήρας είναι πολύ παλιός, υπάρχουν συστάδες που είναι ήδη 6-7 ετών. Υπάρχουν προβλήματα με αυτό που προσπαθούμε να λύσουμε, για παράδειγμα, αρχίσαμε να χρησιμοποιούμε ενεργά το ClickHouse για την αποθήκευση αρχείων καταγραφής.

Συλλογή αρχείων καταγραφής στο ClickHouse

Αυτό το διάγραμμα δείχνει πώς μπαίνουμε στους κινητήρες μας.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

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

  • Αντικαταστήστε κάποια μηχανή με το ClickHouse.
  • αντικαταστήστε τον διακομιστή μεσολάβησης RPC, ο οποίος δεν έχει πρόσβαση στο ClickHouse, με κάποια λύση που μπορεί και μέσω RPC.

Η μηχανή είναι απλή - την αντικαθιστούμε με έναν διακομιστή ή ένα σύμπλεγμα διακομιστών με το ClickHouse.

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

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Μερικές φορές δεν θέλουμε να εφαρμόσουμε το σχήμα RPC σε μη τυπικές λύσεις, για παράδειγμα, στο nginx. Επομένως, το KittenHouse έχει τη δυνατότητα να λαμβάνει αρχεία καταγραφής μέσω UDP.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

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

Παρακολούθηση

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

Μετρήσεις συστήματος

Λειτουργεί σε όλους τους διακομιστές μας netdata, το οποίο συλλέγει στατιστικά στοιχεία και τα στέλνει στο Άνθρακας γραφίτη. Επομένως, το ClickHouse χρησιμοποιείται ως σύστημα αποθήκευσης και όχι το Whisper, για παράδειγμα. Εάν είναι απαραίτητο, μπορείτε να διαβάσετε απευθείας από το ClickHouse ή να χρησιμοποιήσετε Γκράφανα για μετρήσεις, γραφήματα και αναφορές. Ως προγραμματιστές, έχουμε αρκετή πρόσβαση στο Netdata και στο Grafana.

Μετρήσεις προϊόντων

Για ευκολία, έχουμε γράψει πολλά πράγματα. Για παράδειγμα, υπάρχει ένα σύνολο συνηθισμένων συναρτήσεων που σας επιτρέπουν να γράψετε τιμές Counts, UniqueCounts σε στατιστικά στοιχεία, τα οποία αποστέλλονται κάπου περαιτέρω.

statlogsCountEvent   ( ‘stat_name’,            $key1, $key2, …)
statlogsUniqueCount ( ‘stat_name’, $uid,    $key1, $key2, …)
statlogsValuetEvent  ( ‘stat_name’, $value, $key1, $key2, …)

$stats = statlogsStatData($params)

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

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

Έχουμε συναρτήσεις που γράφουν αυτές τις μετρήσεις στην τοπική memcacheγια να μειώσετε τον αριθμό των καταχωρήσεων. Μία φορά σε σύντομο χρονικό διάστημα κυκλοφόρησε τοπικά stats-daemon συγκεντρώνει όλα τα αρχεία. Στη συνέχεια, ο δαίμονας συγχωνεύει τις μετρήσεις σε δύο επίπεδα διακομιστών κούτσουρα-συλλέκτες, το οποίο συγκεντρώνει στατιστικά στοιχεία από ένα σωρό μηχανές μας, έτσι ώστε το στρώμα πίσω από αυτά να μην πεθάνει.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Αν χρειαστεί, μπορούμε να γράψουμε απευθείας σε κούτσουρα-συλλέκτες.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Αλλά η εγγραφή από κώδικα απευθείας στους συλλέκτες, παρακάμπτοντας το stas-daemom, είναι μια κακώς επεκτάσιμη λύση επειδή αυξάνει το φορτίο στον συλλέκτη. Η λύση είναι κατάλληλη μόνο εάν για κάποιο λόγο δεν μπορούμε να ανεβάσουμε το memcache stats-daemon στο μηχάνημα, ή χάλασε και πήγαμε κατευθείαν.

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

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Στη συνέχεια, μπορούμε να κάνουμε δυαδικές επιλογές "σχεδόν SQL" από τον κώδικα.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Πείραμα

Το καλοκαίρι του 2018, είχαμε ένα εσωτερικό hackathon και προέκυψε η ιδέα να προσπαθήσουμε να αντικαταστήσουμε το κόκκινο μέρος του διαγράμματος με κάτι που θα μπορούσε να αποθηκεύσει μετρήσεις στο ClickHouse. Έχουμε αρχεία καταγραφής στο ClickHouse - γιατί να μην το δοκιμάσετε;

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Είχαμε ένα σχέδιο που έγραφε αρχεία καταγραφής μέσω του KittenHouse.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Αποφασίσαμε προσθέστε ένα άλλο "*House" στο διάγραμμα, το οποίο θα λάβει ακριβώς τις μετρήσεις στη μορφή όπως τις γράφει ο κώδικάς μας μέσω UDP. Στη συνέχεια, αυτό το *House τα μετατρέπει σε ένθετα, όπως κούτσουρα, τα οποία καταλαβαίνει το KittenHouse. Μπορεί να παραδώσει τέλεια αυτά τα αρχεία καταγραφής στο ClickHouse, το οποίο θα πρέπει να μπορεί να τα διαβάσει.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Το σχήμα με βάση δεδομένων memcache, stats-daemon και logs-collectors αντικαθίσταται με αυτό.

Συχνές ερωτήσεις σχετικά με την αρχιτεκτονική και το έργο του VKontakte

Το σχήμα με βάση δεδομένων memcache, stats-daemon και logs-collectors αντικαθίσταται με αυτό.

  • Υπάρχει μια αποστολή από κώδικα εδώ, ο οποίος είναι γραμμένος τοπικά στο StatsHouse.
  • Το StatsHouse γράφει μετρήσεις UDP, που έχουν ήδη μετατραπεί σε ένθετα SQL, στο KittenHouse σε παρτίδες.
  • Το KittenHouse τα στέλνει στο ClickHouse.
  • Αν θέλουμε να τα διαβάσουμε, τότε τα διαβάζουμε παρακάμπτοντας το StatsHouse - απευθείας από το ClickHouse χρησιμοποιώντας κανονική SQL.

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

Το σχέδιο δεν εξοικονομεί σίδηρο. Απαιτούνται λιγότεροι διακομιστές, δεν χρειάζονται τοπικοί stats-daemons και logs-collectors, αλλά το ClickHouse απαιτεί μεγαλύτερο διακομιστή από αυτούς του τρέχοντος σχήματος. Απαιτούνται λιγότεροι διακομιστές, αλλά πρέπει να είναι πιο ακριβοί και πιο ισχυροί.

Αναπτύσσω

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

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

Επίσης, αναπτύσσουμε πολύ το kPHP και έχει επίσης τη δική του ανάπτυξη πηγαίνω σύμφωνα με το παραπάνω διάγραμμα. Από αυτό Δυαδικός διακομιστής HTTP, τότε δεν μπορούμε να παράγουμε διαφορά - το δυαδικό αρχείο έκδοσης ζυγίζει εκατοντάδες MB. Επομένως, υπάρχει μια άλλη επιλογή εδώ - η έκδοση είναι γραμμένη binlog copyfast. Με κάθε κατασκευή αυξάνεται, και κατά την επαναφορά αυξάνεται επίσης. Εκδοχή αναπαράγονται σε διακομιστές. Οι τοπικοί αντιγραφείς βλέπουν ότι μια νέα έκδοση έχει μπει στο binlog και με την ίδια αναπαραγωγή κουτσομπολιού παίρνουν την πιο πρόσφατη έκδοση του δυαδικού αρχείου για τον εαυτό τους, χωρίς να κουράζουν τον κύριο διακομιστή μας, αλλά διανέμουν προσεκτικά το φορτίο σε όλο το δίκτυο. Αυτό που ακολουθεί χαριτωμένη επανεκκίνηση για τη νέα έκδοση.

Για τους κινητήρες μας, οι οποίοι είναι επίσης ουσιαστικά δυαδικοί, το σχήμα είναι πολύ παρόμοιο:

  • git master υποκατάστημα?
  • δυαδικό σε . Deb;
  • η έκδοση είναι γραμμένη στο binlog copyfast.
  • αναπαράγονται σε διακομιστές?
  • ο διακομιστής βγάζει ένα νέο .dep.
  • dpkg -i;
  • χαριτωμένη επανεκκίνηση στη νέα έκδοση.

Η διαφορά είναι ότι το δυαδικό μας αρχείο είναι συσκευασμένο σε αρχεία . Deb, και κατά την άντλησή τους dpkg -i τοποθετούνται στο σύστημα. Γιατί το kPHP αναπτύσσεται ως δυαδικό και οι κινητήρες αναπτύσσονται ως dpkg; Έγινε έτσι. Λειτουργεί - μην το αγγίζετε.

Χρήσιμοι σύνδεσμοι:

Ο Alexey Akulovich είναι ένας από αυτούς που, ως μέλος της Επιτροπής Προγράμματος, βοηθά PHP Ρωσία στις 17 Μαΐου θα γίνει η μεγαλύτερη εκδήλωση για προγραμματιστές PHP τον τελευταίο καιρό. Κοίτα τι ωραίο PC έχουμε, τι Ηχεία (δύο από αυτούς αναπτύσσουν πυρήνα PHP!) - φαίνεται σαν κάτι που δεν μπορείτε να χάσετε αν γράψετε PHP.

Πηγή: www.habr.com

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