Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud

Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud
Γεια σας, είμαι ο Sergey Elantsev, αναπτύσσομαι εξισορροπητής φόρτου δικτύου στο Yandex.Cloud. Προηγουμένως, οδήγησα την ανάπτυξη του εξισορροπητή L7 για την πύλη Yandex - οι συνάδελφοι αστειεύονται ότι ό,τι και να κάνω, αποδεικνύεται ότι είναι εξισορροπητής. Θα πω στους αναγνώστες του Habr πώς να διαχειριστούν το φορτίο σε μια πλατφόρμα cloud, ποιο θεωρούμε το ιδανικό εργαλείο για την επίτευξη αυτού του στόχου και πώς προχωράμε προς την κατασκευή αυτού του εργαλείου.

Αρχικά, ας εισαγάγουμε ορισμένους όρους:

  • VIP (Virtual IP) - Διεύθυνση IP εξισορροπητή
  • Διακομιστής, backend, παράδειγμα - μια εικονική μηχανή που εκτελεί μια εφαρμογή
  • RIP (Real IP) - διεύθυνση IP διακομιστή
  • Έλεγχος υγείας - έλεγχος ετοιμότητας διακομιστή
  • Ζώνη διαθεσιμότητας, AZ - απομονωμένη υποδομή σε κέντρο δεδομένων
  • Περιοχή - μια ένωση διαφορετικών AZ

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

Ένας εξισορροπητής φορτίου ταξινομείται συχνά από το επίπεδο πρωτοκόλλου από το μοντέλο OSI στο οποίο εκτελείται. Το Cloud Balancer λειτουργεί σε επίπεδο TCP, το οποίο αντιστοιχεί στο τέταρτο επίπεδο, L4.

Ας προχωρήσουμε σε μια επισκόπηση της αρχιτεκτονικής του Cloud balancer. Σταδιακά θα αυξήσουμε το επίπεδο λεπτομέρειας. Χωρίζουμε τα στοιχεία του εξισορροπητή σε τρεις κατηγορίες. Η κλάση επιπέδου διαμόρφωσης είναι υπεύθυνη για την αλληλεπίδραση με τον χρήστη και αποθηκεύει την κατάσταση προορισμού του συστήματος. Το επίπεδο ελέγχου αποθηκεύει την τρέχουσα κατάσταση του συστήματος και διαχειρίζεται συστήματα από την κατηγορία επιπέδου δεδομένων, τα οποία είναι άμεσα υπεύθυνα για την παράδοση της κίνησης από τους πελάτες στις παρουσίες σας.

Επίπεδο δεδομένων

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

Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud

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

Επίπεδο διαμόρφωσης

 
Το βασικό συστατικό του επιπέδου διαμόρφωσης είναι το API, μέσω του οποίου εκτελούνται βασικές λειτουργίες με εξισορροπητές: δημιουργία, διαγραφή, αλλαγή της σύνθεσης των περιπτώσεων, λήψη αποτελεσμάτων υγειονομικών ελέγχων κ.λπ. Από τη μία πλευρά, αυτό είναι ένα REST API και Άλλο, εμείς στο Cloud χρησιμοποιούμε πολύ συχνά το πλαίσιο gRPC, επομένως «μεταφράζουμε» το REST σε gRPC και στη συνέχεια χρησιμοποιούμε μόνο gRPC. Οποιοδήποτε αίτημα οδηγεί στη δημιουργία μιας σειράς ασύγχρονων ανίκανων εργασιών που εκτελούνται σε μια κοινή ομάδα εργαζομένων Yandex.Cloud. Οι εργασίες είναι γραμμένες με τέτοιο τρόπο ώστε να μπορούν να ανασταλούν ανά πάσα στιγμή και στη συνέχεια να επανεκκινηθούν. Αυτό εξασφαλίζει επεκτασιμότητα, επαναληψιμότητα και καταγραφή των λειτουργιών.

Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud

Ως αποτέλεσμα, η εργασία από το API θα κάνει ένα αίτημα στον ελεγκτή υπηρεσίας εξισορρόπησης, το οποίο είναι γραμμένο στο Go. Μπορεί να προσθέσει και να αφαιρέσει εξισορροπητές, να αλλάξει τη σύνθεση των backend και των ρυθμίσεων. 

Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud

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

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

Ελεγκτής υγειονομικού ελέγχου

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

Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud

Ας μιλήσουμε περισσότερο για τους υγειονομικούς ελέγχους. Μπορούν να χωριστούν σε διάφορες κατηγορίες. Οι έλεγχοι έχουν διαφορετικά κριτήρια επιτυχίας. Οι έλεγχοι TCP πρέπει να δημιουργήσουν με επιτυχία μια σύνδεση εντός καθορισμένου χρονικού διαστήματος. Οι έλεγχοι HTTP απαιτούν τόσο επιτυχημένη σύνδεση όσο και απάντηση με κωδικό κατάστασης 200.

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

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

Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud

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

Η διαφορά είναι ότι οι πελάτες υποβάλλουν αιτήματα σε VIP, ενώ οι έλεγχοι υγείας κάνουν αιτήματα σε κάθε μεμονωμένο RIP. Εδώ προκύπτει ένα ενδιαφέρον πρόβλημα: δίνουμε στους χρήστες μας την ευκαιρία να δημιουργήσουν πόρους σε γκρι δίκτυα IP. Ας φανταστούμε ότι υπάρχουν δύο διαφορετικοί ιδιοκτήτες cloud που έχουν κρύψει τις υπηρεσίες τους πίσω από εξισορροπητές. Κάθε ένα από αυτά έχει πόρους στο υποδίκτυο 10.0.0.1/24, με τις ίδιες διευθύνσεις. Πρέπει να είστε σε θέση να τα διακρίνετε με κάποιο τρόπο και εδώ πρέπει να βουτήξετε στη δομή του εικονικού δικτύου Yandex.Cloud. Είναι καλύτερα να μάθετε περισσότερες λεπτομέρειες στο βίντεο από το about:cloud event, είναι σημαντικό για εμάς τώρα ότι το δίκτυο είναι πολυεπίπεδο και έχει σήραγγες που μπορούν να διακριθούν με αναγνωριστικό υποδικτύου.

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

Η αντίστροφη κίνηση πηγαίνει με τον ίδιο τρόπο: ο εξισορροπητής βλέπει ότι ο προορισμός είναι ένα γκρίζο δίκτυο από τους ελεγκτές υγείας και μετατρέπει το IPv4 σε IPv6.

VPP - η καρδιά του επιπέδου δεδομένων

Ο εξισορροπητής υλοποιείται με τη χρήση της τεχνολογίας Vector Packet Processing (VPP), ένα πλαίσιο από τη Cisco για ομαδική επεξεργασία της κίνησης δικτύου. Στην περίπτωσή μας, το πλαίσιο λειτουργεί πάνω από τη βιβλιοθήκη διαχείρισης συσκευών δικτύου χώρου χρήστη - Data Plane Development Kit (DPDK). Αυτό εξασφαλίζει υψηλή απόδοση επεξεργασίας πακέτων: συμβαίνουν πολύ λιγότερες διακοπές στον πυρήνα και δεν υπάρχουν εναλλαγές περιβάλλοντος μεταξύ του χώρου του πυρήνα και του χώρου χρήστη. 

Το VPP προχωρά ακόμη περισσότερο και αποσπά ακόμη περισσότερη απόδοση από το σύστημα συνδυάζοντας πακέτα σε παρτίδες. Τα κέρδη απόδοσης προέρχονται από την επιθετική χρήση της κρυφής μνήμης σε σύγχρονους επεξεργαστές. Χρησιμοποιούνται και οι δύο κρυφές μνήμες δεδομένων (τα πακέτα επεξεργάζονται σε «διανύσματα», τα δεδομένα είναι κοντά το ένα στο άλλο) και οι κρυφές μνήμες εντολών: στο VPP, η επεξεργασία πακέτων ακολουθεί ένα γράφημα, οι κόμβοι του οποίου περιέχουν συναρτήσεις που εκτελούν την ίδια εργασία.

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

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

n_left_from = frame->n_vectors;
while (n_left_from > 0)
{
    vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
    // ...
    while (n_left_from >= 4 && n_left_to_next >= 2)
    {
        // processing multiple packets at once
        u32 next0 = SAMPLE_NEXT_INTERFACE_OUTPUT;
        u32 next1 = SAMPLE_NEXT_INTERFACE_OUTPUT;
        // ...
        /* Prefetch next iteration. */
        {
            vlib_buffer_t *p2, *p3;

            p2 = vlib_get_buffer (vm, from[2]);
            p3 = vlib_get_buffer (vm, from[3]);

            vlib_prefetch_buffer_header (p2, LOAD);
            vlib_prefetch_buffer_header (p3, LOAD);

            CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE);
            CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, STORE);
        }
        // actually process data
        /* verify speculative enqueues, maybe switch current next frame */
        vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
                to_next, n_left_to_next,
                bi0, bi1, next0, next1);
    }

    while (n_left_from > 0 && n_left_to_next > 0)
    {
        // processing packets by one
    }

    // processed batch
    vlib_put_next_frame (vm, node, next_index, n_left_to_next);
}

Έτσι, τα Healthchecks μιλάνε μέσω IPv6 στο VPP, το οποίο τα μετατρέπει σε IPv4. Αυτό γίνεται από έναν κόμβο στο γράφημα, τον οποίο ονομάζουμε αλγοριθμικό NAT. Για την αντίστροφη κίνηση (και τη μετατροπή από IPv6 σε IPv4) υπάρχει ο ίδιος αλγοριθμικός κόμβος NAT.

Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud

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

Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud

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

Ο κατακερματισμός 5 πλειάδων μας βοηθά να εκτελούμε λιγότερους υπολογισμούς στον επόμενο συνεπή κόμβο κατακερματισμού, καθώς και να χειριζόμαστε καλύτερα τις αλλαγές στη λίστα πόρων πίσω από τον εξισορροπητή. Όταν ένα πακέτο για το οποίο δεν υπάρχει περίοδος λειτουργίας φθάνει στον εξισορροπητή, αποστέλλεται στον συνεπή κόμβο κατακερματισμού. Εδώ πραγματοποιείται η εξισορρόπηση χρησιμοποιώντας συνεπή κατακερματισμό: επιλέγουμε έναν πόρο από τη λίστα των διαθέσιμων «ζωντανών» πόρων. Στη συνέχεια, τα πακέτα αποστέλλονται στον κόμβο NAT, ο οποίος στην πραγματικότητα αντικαθιστά τη διεύθυνση προορισμού και υπολογίζει εκ νέου τα αθροίσματα ελέγχου. Όπως μπορείτε να δείτε, ακολουθούμε τους κανόνες του VPP - like to like, ομαδοποιώντας παρόμοιους υπολογισμούς για να αυξήσουμε την αποτελεσματικότητα της κρυφής μνήμης επεξεργαστή.

Συνεπής κατακερματισμός

Γιατί το επιλέξαμε και τι ακριβώς είναι; Αρχικά, ας εξετάσουμε την προηγούμενη εργασία - επιλέγοντας έναν πόρο από τη λίστα. 

Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud

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

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

Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud

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

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

Loadbalancer-κόμβος και συναρμολογημένα εξαρτήματα

Η σύνθεση των balancers και των πόρων στο VPP αναφέρεται από την τοπική υπηρεσία - loadbalancer-node. Εγγράφεται στη ροή γεγονότων από τον ελεγκτή εξισορρόπησης φορτίου και είναι σε θέση να σχεδιάσει τη διαφορά μεταξύ της τρέχουσας κατάστασης VPP και της κατάστασης στόχου που λαμβάνεται από τον ελεγκτή. Λαμβάνουμε ένα κλειστό σύστημα: συμβάντα από το API έρχονται στον ελεγκτή ισορροπίας, ο οποίος αναθέτει εργασίες στον ελεγκτή υγειονομικού ελέγχου για να ελέγξει τη «ζωντανότητα» των πόρων. Αυτό, με τη σειρά του, αναθέτει εργασίες στον κόμβο ελέγχου υγείας και συγκεντρώνει τα αποτελέσματα, μετά τα οποία τα στέλνει πίσω στον ελεγκτή εξισορρόπησης. Loadbalancer-node εγγράφεται σε συμβάντα από τον ελεγκτή και αλλάζει την κατάσταση του VPP. Σε ένα τέτοιο σύστημα, κάθε υπηρεσία γνωρίζει μόνο ό,τι είναι απαραίτητο για τις γειτονικές υπηρεσίες. Ο αριθμός των συνδέσεων είναι περιορισμένος και έχουμε τη δυνατότητα να λειτουργούμε και να κλιμακώνουμε διαφορετικά τμήματα ανεξάρτητα.

Αρχιτεκτονική εξισορρόπησης φορτίου δικτύου στο Yandex.Cloud

Ποια θέματα αποφεύχθηκαν;

Όλες οι υπηρεσίες μας στο επίπεδο ελέγχου είναι γραμμένες στο Go και έχουν καλά χαρακτηριστικά κλιμάκωσης και αξιοπιστίας. Το Go έχει πολλές βιβλιοθήκες ανοιχτού κώδικα για τη δημιουργία κατανεμημένων συστημάτων. Χρησιμοποιούμε ενεργά το GRPC, όλα τα στοιχεία περιέχουν μια εφαρμογή ανακάλυψης υπηρεσίας ανοιχτού κώδικα - οι υπηρεσίες μας παρακολουθούν η μια την απόδοση της άλλης, μπορούν να αλλάξουν δυναμικά τη σύνθεσή τους και το συνδέσαμε με την εξισορρόπηση GRPC. Για μετρήσεις, χρησιμοποιούμε επίσης μια λύση ανοιχτού κώδικα. Στο επίπεδο δεδομένων, είχαμε αξιοπρεπείς επιδόσεις και μεγάλο απόθεμα πόρων: αποδείχθηκε ότι ήταν πολύ δύσκολο να συναρμολογήσουμε μια βάση στην οποία θα μπορούσαμε να βασιστούμε στην απόδοση μιας VPP και όχι μιας σιδερένιας κάρτας δικτύου.

Προβλήματα και λύσεις

Τι δεν λειτούργησε τόσο καλά; Το Go διαθέτει αυτόματη διαχείριση μνήμης, αλλά εξακολουθούν να συμβαίνουν διαρροές μνήμης. Ο ευκολότερος τρόπος για να τα αντιμετωπίσετε είναι να εκτελέσετε γορουτίνες και να θυμάστε να τα τερματίσετε. Takeaway: Παρακολουθήστε την κατανάλωση μνήμης των προγραμμάτων Go σας. Συχνά ένας καλός δείκτης είναι ο αριθμός των γορουτινών. Υπάρχει ένα πλεονέκτημα σε αυτή την ιστορία: στο Go είναι εύκολο να λαμβάνετε δεδομένα χρόνου εκτέλεσης - κατανάλωση μνήμης, τον αριθμό των γορουτίνων που εκτελούνται και πολλές άλλες παραμέτρους.

Επίσης, το Go μπορεί να μην είναι η καλύτερη επιλογή για λειτουργικές δοκιμές. Είναι αρκετά περίεργα και η τυπική προσέγγιση της «εκτέλεσης των πάντων σε CI σε μια παρτίδα» δεν είναι πολύ κατάλληλη για αυτούς. Το γεγονός είναι ότι οι λειτουργικές δοκιμές απαιτούν περισσότερο πόρους και προκαλούν πραγματικά χρονικά όρια. Εξαιτίας αυτού, οι δοκιμές ενδέχεται να αποτύχουν επειδή η CPU είναι απασχολημένη με δοκιμές μονάδας. Συμπέρασμα: Εάν είναι δυνατόν, εκτελέστε «βαριές» δοκιμές χωριστά από τις δοκιμές μονάδας. 

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

Τα σχέδιά μας

Θα κυκλοφορήσουμε έναν εσωτερικό εξισορροπητή, έναν εξισορροπητή IPv6, θα προσθέσουμε υποστήριξη για σενάρια Kubernetes, θα συνεχίσουμε να διαμοιράζουμε τις υπηρεσίες μας (προς το παρόν μόνο το healthcheck-node και το healthcheck-ctrl είναι κοινόχρηστα), θα προσθέσουμε νέους ελέγχους υγείας και θα εφαρμόσουμε επίσης έξυπνη συγκέντρωση ελέγχων. Εξετάζουμε τη δυνατότητα να κάνουμε τις υπηρεσίες μας ακόμα πιο ανεξάρτητες - ώστε να μην επικοινωνούν απευθείας μεταξύ τους, αλλά χρησιμοποιώντας μια ουρά μηνυμάτων. Μια υπηρεσία συμβατή με SQS εμφανίστηκε πρόσφατα στο Cloud Ουρά μηνυμάτων Yandex.

Πρόσφατα, πραγματοποιήθηκε η δημόσια κυκλοφορία του Yandex Load Balancer. Εξερευνώ τεκμηρίωση στην υπηρεσία, διαχειριστείτε τους εξισορροπητές με τρόπο βολικό για εσάς και αυξήστε την ανοχή σφαλμάτων των έργων σας!

Πηγή: www.habr.com

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