
Άρτεμ Ντενίσοφ ( , )
Το Badoo είναι η μεγαλύτερη ιστοσελίδα γνωριμιών στον κόσμο. Αυτή τη στιγμή έχουμε περίπου 330 εκατομμύρια εγγεγραμμένους χρήστες παγκοσμίως. Αλλά αυτό που είναι πιο σημαντικό για τη σημερινή μας συζήτηση είναι ότι αποθηκεύουμε περίπου 3 petabytes φωτογραφιών χρηστών. Κάθε μέρα, οι χρήστες μας ανεβάζουν περίπου 3,5 εκατομμύρια νέες φωτογραφίες και το φορτίο ανάγνωσης είναι περίπου... 80 χιλιάδες αιτήματα ανά δευτερόλεπτοΑυτό είναι αρκετά μεγάλο για το backend μας και μερικές φορές μπορεί να είναι δύσκολο.

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

Όπως είπα, αυτή θα είναι μια αναδρομή, και για να ξεκινήσουμε από κάπου, ας πάρουμε το πιο κοινότοπο παράδειγμα.

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

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

Προσθέτουμε κάποιο πεδίο στον χώρο αποθήκευσης με πληροφορίες χρήστη. Αυτό θα είναι το κλειδί sharding. Στην περίπτωσή μας, το ονομάσαμε place_id και αυτό το place id δείχνει τον τόπο όπου αποθηκεύονται οι φωτογραφίες των χρηστών. Δημιουργούμε χάρτες.
Στο πρώτο στάδιο, αυτό μπορεί να γίνει ακόμη και χειροκίνητα - λέμε ότι μια φωτογραφία αυτού του χρήστη με μια τέτοια τοποθεσία θα προσγειωθεί σε έναν τέτοιο διακομιστή. Χάρη σε αυτόν τον χάρτη, γνωρίζουμε πάντα πότε ένας χρήστης ανεβάζει μια φωτογραφία, πού να την αποθηκεύσουμε και ξέρουμε από πού να την δώσουμε.
Πρόκειται για ένα εντελώς ασήμαντο σχέδιο, αλλά έχει αρκετά σημαντικά πλεονεκτήματα. Το πρώτο είναι ότι είναι απλό, όπως είπα, και το δεύτερο είναι ότι με αυτήν την προσέγγιση μπορούμε εύκολα να κλιμακώσουμε οριζόντια, απλώς παραδίδοντας νέα αυτοκίνητα και προσθέτοντάς τα στον χάρτη. Δεν χρειάζεται να γίνει τίποτα άλλο.
Έτσι ήταν και για εμάς για κάποιο διάστημα.

Ήταν κάπου γύρω στο 2009. Παρέδιδαν αυτοκίνητα, παρέδιδαν…
Και κάποια στιγμή αρχίσαμε να παρατηρούμε ότι αυτό το σχέδιο είχε ορισμένες ελλείψεις. Ποιες ελλείψεις;
Καταρχάς, πρόκειται για περιορισμένη χωρητικότητα. Δεν μπορούμε να χωρέσουμε όσους σκληρούς δίσκους θα θέλαμε σε έναν φυσικό διακομιστή. Και αυτό έχει γίνει ένα συγκεκριμένο πρόβλημα με την πάροδο του χρόνου και με την ανάπτυξη του συνόλου δεδομένων.
Και δεύτερον, αυτή είναι μια άτυπη διαμόρφωση μηχανών, καθώς τέτοιες μηχανές είναι δύσκολο να επαναχρησιμοποιηθούν σε ορισμένες άλλες συστάδες, είναι αρκετά συγκεκριμένες, δηλαδή πρέπει να είναι αδύναμες στην απόδοση, αλλά ταυτόχρονα με έναν μεγάλο σκληρό δίσκο.
Όλα αυτά ίσχυαν για το 2009, αλλά, κατ' αρχήν, αυτές οι απαιτήσεις εξακολουθούν να ισχύουν σήμερα. Έχουμε μια αναδρομή, οπότε το 2009 όλα ήταν πολύ άσχημα με αυτό.
Και το τελευταίο σημείο είναι η τιμή.

Η τιμή ήταν πολύ υψηλή τότε και έπρεπε να αναζητήσουμε εναλλακτικές λύσεις. Δηλαδή, έπρεπε να αξιοποιήσουμε καλύτερα τόσο τον χώρο στα κέντρα δεδομένων όσο και τους φυσικούς διακομιστές όπου βρίσκονταν όλα αυτά. Και οι μηχανικοί συστημάτων μας ξεκίνησαν μια μεγάλη μελέτη, στην οποία εξέτασαν μια σειρά από διαφορετικές επιλογές. Εξέτασαν επίσης συστήματα αρχείων συμπλέγματος, όπως το PolyCeph και το Lustre. Υπήρχαν προβλήματα απόδοσης και αρκετά βαριά λειτουργία. Αρνήθηκαν. Προσπάθησαν να τοποθετήσουν ολόκληρο το σύνολο δεδομένων μέσω NFS σε κάθε δίσκο για να το κλιμακώσουν με κάποιο τρόπο. Η ανάγνωση επίσης δεν πήγε καλά, δοκίμασαν διαφορετικές λύσεις από διαφορετικούς προμηθευτές.
Και στο τέλος, καταλήξαμε στη χρήση αυτού που ονομάζεται Δίκτυο Χώρου Αποθήκευσης.

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

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

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

Και εδώ όλα παίζουν ρόλο στα χέρια μας.
Το είπα ήδη στην πρώτη διαφάνεια: έχουμε 80 χιλιάδες αιτήματα ανά δευτερόλεπτο για ανάγνωση με μόνο 3,5 εκατομμύρια ανεβάσματα την ημέρα. Δηλαδή, αυτή είναι μια διαφορά τριών τάξεων μεγέθους. Είναι προφανές ότι η ανάγνωση χρειάζεται βελτιστοποίηση και είναι σχεδόν σαφές πώς.
Υπάρχει ένα ακόμη μικρό σημείο. Η ιδιαιτερότητα της υπηρεσίας είναι ότι ένα άτομο εγγράφεται, ανεβάζει μια φωτογραφία, μετά αρχίζει να παρακολουθεί ενεργά άλλους ανθρώπους, να τους κάνει like, εμφανίζεται ενεργά σε άλλους ανθρώπους. Στη συνέχεια βρίσκει έναν σύντροφο ή δεν βρίσκει σύντροφο, όπως συμβαίνει, και σταματά να χρησιμοποιεί την υπηρεσία για κάποιο χρονικό διάστημα. Αυτή τη στιγμή, όταν τη χρησιμοποιεί, οι φωτογραφίες του είναι πολύ δημοφιλείς - έχουν ζήτηση, τις βλέπουν πολλοί άνθρωποι. Μόλις σταματήσει να το κάνει αυτό, γρήγορα εγκαταλείπει τις τόσο εντατικές εμφανίσεις σε άλλους ανθρώπους όπως πριν, και οι φωτογραφίες του πρακτικά δεν ζητούνται.

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

Προσθέτουμε ένα άλλο σχετικά μικρό πριν από το μεγάλο σύμπλεγμα με αποθηκευτικό χώρο, το οποίο ονομάζεται photocaches (photoscache). Στην πραγματικότητα, αυτό είναι απλώς ένα proxy προσωρινής αποθήκευσης.
Πώς λειτουργεί εσωτερικά; Ορίστε ο χρήστης μας, ορίστε ο αποθηκευτικός χώρος. Όλα είναι όπως πριν. Τι προσθέτουμε μεταξύ τους;

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

Η προσωρινή μνήμη χωρίζεται λογικά σε τρία επίπεδα. Όταν λέω «τρία επίπεδα», δεν εννοώ ότι υπάρχει κάποιο πολύπλοκο σύστημα εκεί. Όχι, είναι απλώς τρεις κατάλογοι στο σύστημα αρχείων:
- Αυτό είναι ένα buffer όπου τοποθετούνται οι φωτογραφίες που μόλις λήφθηκαν από το proxy.
- Αυτή είναι μια hot cache που αποθηκεύει φωτογραφίες που ζητούνται ενεργά αυτήν τη στιγμή.
- Και μια ψυχρή προσωρινή μνήμη, όπου οι φωτογραφίες σταδιακά εξέρχονται από την θερμή προσωρινή μνήμη όταν υποβάλλονται λιγότερα αιτήματα σε αυτές.
Για να λειτουργήσει αυτό, πρέπει με κάποιο τρόπο να διαχειριστούμε αυτήν την προσωρινή μνήμη, πρέπει να αναδιατάξουμε τις φωτογραφίες σε αυτήν, κ.λπ. Αυτή είναι επίσης μια πολύ πρωτόγονη διαδικασία.

Το Nginx απλώς γράφει στο RAMDisk access.log για κάθε αίτημα, υποδεικνύοντας τη διαδρομή προς τη φωτογραφία που μόλις εξυπηρέτησε (σχετική διαδρομή, φυσικά) και από ποιο partition εξυπηρέτησε. Δηλαδή, μπορεί να πει "photo 1" και στη συνέχεια είτε buffer, είτε hot cache, είτε cold cache, είτε proxy.
Ανάλογα με αυτό, πρέπει με κάποιο τρόπο να αποφασίσουμε τι θα κάνουμε με τη φωτογραφία.
Έχουμε ένα μικρό δαιμόνιο που τρέχει σε κάθε μηχάνημα και διαβάζει συνεχώς αυτό το αρχείο καταγραφής και αποθηκεύει στατιστικά στοιχεία σχετικά με τη χρήση ορισμένων φωτογραφιών στη μνήμη του.

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

Οι φωτογραφίες που ζητούνται σπάνια και έχουν ζητηθεί λιγότερο συχνά μεταφέρονται σταδιακά από την «hot cache» στην «cold cache».

Και όταν μας τελειώνει ο χώρος στην προσωρινή μνήμη, απλώς αρχίζουμε να διαγράφουμε τα πάντα από την ψυχρή προσωρινή μνήμη αδιακρίτως. Και αυτό λειτουργεί καλά, παρεμπιπτόντως.
Για να αποθηκευτεί αμέσως η φωτογραφία κατά την proxying στο buffer, χρησιμοποιούμε την οδηγία proxy_store και το buffer είναι επίσης ένας δίσκος RAM, δηλαδή για τον χρήστη λειτουργεί πολύ γρήγορα. Αυτό αφορά τα εσωτερικά του ίδιου του διακομιστή προσωρινής αποθήκευσης.
Το ερώτημα παραμένει πώς θα κατανεμηθούν τα αιτήματα σε αυτούς τους διακομιστές.
Ας υποθέσουμε ότι υπάρχει ένα σύμπλεγμα από είκοσι μηχανήματα αποθήκευσης και τρεις διακομιστές προσωρινής αποθήκευσης (έτσι συνέβη).

Πρέπει με κάποιο τρόπο να προσδιορίσουμε ποια αιτήματα αφορούν ποιες φωτογραφίες και πού θα προσγειωθούμε.
Η πιο απλή επιλογή είναι το Round Robin. Ή μήπως να το κάνω τυχαία;
Αυτό προφανώς έχει μια σειρά από μειονεκτήματα, επειδή θα χρησιμοποιήσουμε την προσωρινή μνήμη πολύ αναποτελεσματικά σε μια τέτοια περίπτωση. Τα αιτήματα θα καταλήξουν σε μερικά τυχαία μηχανήματα: εδώ είναι αποθηκευμένα στην προσωρινή μνήμη, στο γειτονικό δεν είναι πλέον εκεί. Και αν όλα αυτά λειτουργούν, τότε πολύ άσχημα. Ακόμα και με έναν μικρό αριθμό μηχανημάτων στο σύμπλεγμα.
Πρέπει με κάποιο τρόπο να προσδιορίσουμε με σαφήνεια ποιος διακομιστής θα λάβει ποιο αίτημα.
Υπάρχει ένας απλός τρόπος. Παίρνουμε το hash από τη διεύθυνση URL ή το hash από το sharding key μας, το οποίο βρίσκεται στη διεύθυνση URL, και το διαιρούμε ισόποσα με τον αριθμό των διακομιστών. Θα λειτουργήσει; Θα λειτουργήσει.

Δηλαδή, έχουμε ένα αίτημα 2%, για παράδειγμα, για κάποιο "example_url" που θα εμφανίζεται πάντα στον διακομιστή με ευρετήριο "XNUMX" και η προσωρινή μνήμη θα χρησιμοποιείται συνεχώς όσο το δυνατόν καλύτερα.
Υπάρχει όμως ένα πρόβλημα με την επαναδιανομή σε ένα τέτοιο σχήμα. Επαναδιανομή - εννοώ την αλλαγή του αριθμού των διακομιστών.
Ας υποθέσουμε ότι το σύμπλεγμα προσωρινής αποθήκευσης δεν είναι πλέον στο επίπεδο που απαιτείται και αποφασίζουμε να προσθέσουμε ένα άλλο μηχάνημα.
Ας προσθέσουμε.

Τώρα όλα διαιρούνται όχι με το τρία, αλλά με το τέσσερα. Έτσι, σχεδόν όλα τα κλειδιά που είχαμε πριν, σχεδόν όλες οι διευθύνσεις URL, τώρα βρίσκονται σε άλλους διακομιστές. Ολόκληρη η προσωρινή μνήμη ακυρώθηκε σε μια στιγμή. Όλα τα αιτήματα έπεσαν στον χώρο αποθήκευσης του συμπλέγματός μας, αρρώστησε, η υπηρεσία απέτυχε και οι χρήστες δυσαρεστήθηκαν. Δεν θέλω να το κάνω αυτό.
Ούτε αυτή η επιλογή μας ταιριάζει.
Τι πρέπει λοιπόν να κάνουμε; Θα πρέπει με κάποιο τρόπο να χρησιμοποιούμε αποτελεσματικά την προσωρινή μνήμη, να στέλνουμε πάντα το ίδιο αίτημα στον ίδιο διακομιστή, αλλά ταυτόχρονα να είμαστε ανθεκτικοί στο resharding. Και υπάρχει μια τέτοια λύση, δεν είναι τόσο περίπλοκη. Ονομάζεται συνεπής κατακερματισμός.

Πώς μοιάζει;

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

Κάθε διακομιστής ορίζεται από ένα σημείο και ο τομέας που πηγαίνει δεξιόστροφα προς αυτόν, ανάλογα, εξυπηρετείται από αυτόν τον κεντρικό υπολογιστή. Όταν λαμβάνουμε αιτήματα, βλέπουμε αμέσως ότι, για παράδειγμα, το αίτημα Α - έχει ένα τέτοιο hash - και εξυπηρετείται από τον διακομιστή 2. Το αίτημα Β - από τον διακομιστή 3. Και ούτω καθεξής.

Τι συμβαίνει σε αυτήν την περίπτωση κατά την επαναδιατύπωση;

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

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

Και δεν θα θέλαμε πραγματικά να αναγεννήσουμε αυτόν τον χάρτη σε αυτό το σημείο, να ακυρώσουμε μέρος της προσωρινής μνήμης και ούτω καθεξής, αν, για παράδειγμα, το μηχάνημα επανεκκινηθεί και χρειαστεί να εξυπηρετήσουμε με κάποιο τρόπο τα αιτήματα. Απλώς διατηρούμε μια εφεδρική προσωρινή μνήμη φωτογραφιών σε κάθε ιστότοπο, η οποία λειτουργεί ως αντικατάσταση για οποιοδήποτε μηχάνημα που είναι αυτήν τη στιγμή εκτός λειτουργίας. Και αν ξαφνικά κάποιος διακομιστής μας δεν είναι διαθέσιμος, η κίνηση πηγαίνει εκεί. Φυσικά, δεν έχουμε προσωρινή μνήμη εκεί, δηλαδή είναι κρύα, αλλά, τουλάχιστον, επεξεργάζονται τα αιτήματα των χρηστών. Εάν αυτό είναι ένα σύντομο χρονικό διάστημα, τότε είμαστε απολύτως ήρεμοι γι' αυτό. Υπάρχει απλώς περισσότερο φορτίο στον χώρο αποθήκευσης. Εάν αυτό είναι ένα μεγάλο χρονικό διάστημα, τότε μπορούμε ήδη να πάρουμε μια απόφαση - να αφαιρέσουμε αυτόν τον διακομιστή από τον χάρτη ή όχι, ή ίσως να τον αντικαταστήσουμε με έναν άλλο.
Αυτό αφορά το σύστημα προσωρινής αποθήκευσης. Ας δούμε τα αποτελέσματα.
Φαίνεται ότι δεν υπάρχει τίποτα περίπλοκο εδώ. Αλλά αυτή η μέθοδος διαχείρισης της προσωρινής μνήμης μας έδωσε ποσοστό επιτυχίας περίπου 98%. Δηλαδή, από αυτά τα 80 χιλιάδες αιτήματα ανά δευτερόλεπτο, μόνο τα 1600 φτάνουν στις αποθήκες, και αυτό είναι ένα εντελώς φυσιολογικό φορτίο, επιβιώνουν ήρεμα από αυτό, έχουμε πάντα ένα απόθεμα.
Τοποθετήσαμε αυτούς τους διακομιστές σε τρία από τα DC μας και αποκτήσαμε τρία σημεία παρουσίας - Πράγα, Μαϊάμι και Χονγκ Κονγκ.

Έτσι, βρίσκονται λίγο-πολύ τοπικά σε κάθε μία από τις αγορές-στόχους μας.
Και ως ωραίο πλεονέκτημα, αποκτήσαμε αυτόν τον διακομιστή μεσολάβησης προσωρινής αποθήκευσης, όπου η CPU είναι στην πραγματικότητα αδρανής, επειδή δεν είναι τόσο απαραίτητη για την παράδοση του περιεχομένου. Και εκεί, χρησιμοποιώντας NGINX + Lua, εφαρμόσαμε πολλή λογική βοηθητικών προγραμμάτων.

Για παράδειγμα, μπορούμε να πειραματιστούμε με webp ή progressive jpeg (αυτές είναι αποτελεσματικές σύγχρονες μορφές), να δούμε πώς επηρεάζουν την επισκεψιμότητα, να λάβουμε κάποιες αποφάσεις, να τις ενεργοποιήσουμε για ορισμένες χώρες κ.λπ., να κάνουμε δυναμική αλλαγή μεγέθους ή να περικόψουμε φωτογραφίες εν κινήσει.
Αυτή είναι μια καλή περίπτωση χρήσης όταν έχετε, για παράδειγμα, μια εφαρμογή για κινητά που εμφανίζει φωτογραφίες και η εφαρμογή για κινητά δεν θέλει να σπαταλήσει την CPU του προγράμματος-πελάτη για να ζητήσει μια μεγάλη φωτογραφία και στη συνέχεια να την αλλάξει σε ένα συγκεκριμένο μέγεθος για να την τοποθετήσει στην προβολή. Μπορούμε απλώς να καθορίσουμε δυναμικά ορισμένες παραμέτρους στη διεύθυνση URL σε συνθήκη UPort και η προσωρινή μνήμη φωτογραφιών θα αλλάξει το μέγεθος της ίδιας της φωτογραφίας. Κατά κανόνα, θα επιλέξει το μέγεθος που έχουμε φυσικά στον δίσκο, όσο το δυνατόν πιο κοντά σε αυτό που ζητήθηκε, και θα το μειώσει σε συγκεκριμένες συντεταγμένες.
Παρεμπιπτόντως, έχουμε διαθέσει στο κοινό βιντεοσκοπημένες ηχογραφήσεις των τελευταίων πέντε ετών του συνεδρίου προγραμματιστών συστημάτων υψηλού φορτίου. Παρακολουθήστε, μάθετε, μοιραστείτε και εγγραφείτε στο .
Μπορούμε επίσης να προσθέσουμε πολλή λογική προϊόντος εκεί. Για παράδειγμα, μπορούμε να προσθέσουμε διαφορετικά υδατογραφήματα με βάση τις παραμέτρους URL, μπορούμε να θολώσουμε φωτογραφίες, να κάνουμε θόλωση ή pixelate. Αυτό συμβαίνει όταν θέλουμε να δείξουμε μια φωτογραφία ενός ατόμου, αλλά δεν θέλουμε να δείξουμε το πρόσωπό του, λειτουργεί καλά, όλα εφαρμόζονται εδώ.
Τι πετύχαμε; Πήραμε τρία σημεία παρουσίας, καλό ποσοστό επιτυχίας και ταυτόχρονα δεν έχουμε CPU σε αδράνεια σε αυτά τα μηχανήματα. Τώρα έχει γίνει, φυσικά, πιο σημαντικό από πριν. Πρέπει να εγκαταστήσουμε πιο ισχυρά μηχανήματα, αλλά αξίζει τον κόπο.
Πρόκειται για το να χαρίζεις φωτογραφίες. Όλα είναι αρκετά ξεκάθαρα και προφανή εδώ. Νομίζω ότι δεν έχω ανακαλύψει την Αμερική, σχεδόν κάθε CDN λειτουργεί έτσι.
Και, πιθανότατα, ένας έμπειρος ακροατής μπορεί να έχει την εξής ερώτηση: γιατί να μην πάρουμε απλώς και να αλλάξουμε τα πάντα σε CDN; Θα ήταν περίπου το ίδιο, όλα τα σύγχρονα CDN μπορούν να το κάνουν αυτό. Και υπάρχουν διάφοροι λόγοι.
Το πρώτο είναι οι φωτογραφίες.

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

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

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

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

Έχουν προστεθεί διακομιστές προσωρινής αποθήκευσης, τα προβλήματα απόδοσης έχουν εξαλειφθεί. Όλα είναι καλά. Το σύνολο δεδομένων αυξάνεται. Το 2013, είχαμε περίπου 80 διακομιστές συνδεδεμένους σε αποθηκευτικούς χώρους και περίπου 40 διακομιστές προσωρινής αποθήκευσης σε κάθε DC. Αυτό αντιστοιχεί σε 560 terabyte δεδομένων σε κάθε DC, δηλαδή περίπου ένα petabyte συνολικά.

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

Σε αυτό το διάγραμμα, το οποίο είναι σχεδιασμένο - με SAN, με μηχανήματα και cache συνδεδεμένα σε αυτό - υπάρχουν πολλά σημεία αποτυχίας. Αν έχουμε ήδη ασχοληθεί με την αποτυχία των διακομιστών προσωρινής αποθήκευσης, όλα είναι λίγο πολύ προβλέψιμα και σαφή, τότε από την πλευρά της αποθήκευσης όλα ήταν πολύ χειρότερα.
Πρώτον, το ίδιο το Δίκτυο Περιοχής Αποθήκευσης (SAN), το οποίο μπορεί να παρουσιάσει βλάβη.
Δεύτερον, συνδέεται μέσω οπτικών ινών με τα τερματικά μηχανήματα. Μπορεί να υπάρχουν προβλήματα με οπτικές κάρτες, μπουζί.

Φυσικά, δεν υπάρχουν τόσα πολλά από αυτά όσο με το ίδιο το SAN, αλλά, παρ' όλα αυτά, αυτά είναι επίσης σημεία αποτυχίας.
Στη συνέχεια, το ίδιο το μηχάνημα, το οποίο είναι συνδεδεμένο με την αποθήκευση. Μπορεί επίσης να παρουσιάσει βλάβη.

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

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

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

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

Δεν είναι πολύ φορτωμένο. Γνωρίζουμε ότι έχουμε λίγες εγγραφές. Η ουρά είναι απλώς ένας πίνακας στο MySQL, όπου γράφονται γραμμές όπως "πρέπει να δημιουργηθεί αντίγραφο ασφαλείας αυτής της φωτογραφίας". Με οποιαδήποτε αλλαγή ή μεταφόρτωση, αντιγράφουμε από την κύρια ενότητα για να δημιουργήσουμε αντίγραφα ασφαλείας ασύγχρονα ή απλώς για να δημιουργήσουμε αντίγραφα ασφαλείας.
Και έτσι έχουμε πάντα δύο συνεχόμενα διαμερίσματα. Ακόμα κι αν ένα μέρος αυτού του συστήματος αποτύχει, μπορούμε πάντα να αλλάξουμε το κύριο διαμέρισμα με το αντίγραφο ασφαλείας και όλα θα συνεχίσουν να λειτουργούν.
Αλλά εξαιτίας αυτού, το φόρτο ανάγνωσης αυξάνεται σημαντικά, επειδή εκτός από τους πελάτες που διαβάζουν από το κύριο διαμέρισμα, επειδή πρώτα κοιτάζουν τη φωτογραφία εκεί (είναι πιο πρόσφατη εκεί), και στη συνέχεια αναζητούν στο αντίγραφο ασφαλείας, αν δεν τη βρουν (αλλά το NGINX το κάνει απλά αυτό), συν το σύστημα δημιουργίας αντιγράφων ασφαλείας μας διαβάζει τώρα από το κύριο διαμέρισμα. Όχι ότι αυτό ήταν ένα σημείο συμφόρησης, αλλά δεν θέλαμε να αυξήσουμε το φόρτο, ουσιαστικά, έτσι απλά.
Και προσθέσαμε έναν τρίτο δίσκο, ο οποίος είναι ένας μικρός SSD, και τον ονομάσαμε buffer.

Πώς λειτουργεί τώρα.
Ο χρήστης ανεβάζει μια φωτογραφία στο buffer και στη συνέχεια ένα συμβάν εμφανίζεται στην ουρά που πρέπει να αντιγραφεί σε δύο partitions. Αντιγράφεται και η φωτογραφία παραμένει στο buffer για κάποιο χρονικό διάστημα (ας πούμε, μια ημέρα) και μόνο τότε γίνεται λήψη της από εκεί. Αυτό βελτιώνει σημαντικά την εμπειρία του χρήστη, επειδή ο χρήστης που ανεβάζει μια φωτογραφία, κατά κανόνα, ζητά αμέσως να αρχίσει να την ακολουθεί ή ανανέωσε ο ίδιος τη σελίδα. Αλλά όλα εξαρτώνται από την εφαρμογή που κάνει τη μεταφόρτωση.
Ή, για παράδειγμα, άλλα άτομα, στα οποία άρχισε να εμφανίζεται, στέλνουν αμέσως αιτήματα για αυτήν τη φωτογραφία. Δεν βρίσκεται ακόμα στην προσωρινή μνήμη, το πρώτο αίτημα γίνεται πολύ γρήγορα. Στην πραγματικότητα, το ίδιο συμβαίνει και με την προσωρινή μνήμη φωτογραφιών. Η αργή αποθήκευση δεν συμμετέχει καθόλου σε αυτό. Και όταν μέσα σε μια μέρα ανακτηθεί, είτε είναι ήδη αποθηκευμένη στην προσωρινή μας στρώση, είτε πιθανότατα δεν χρειάζεται πλέον από κανέναν. Δηλαδή, η εμπειρία χρήστη εδώ έχει βελτιωθεί σημαντικά λόγω τέτοιων απλών χειρισμών.
Λοιπόν, και το πιο σημαντικό: σταματήσαμε να χάνουμε δεδομένα.

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

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

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

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

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

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

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

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

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

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

Συλλέγουμε μια σειρά από μετρήσεις για αυτό το σύστημα και το υπό όρους ποσοστό επιτυχίας ενός τέτοιου μηχανισμού είναι περίπου 95%. Δηλαδή, η καθυστέρηση αυτού του αντιγράφου ασφαλείας είναι μικρή και, λόγω αυτού, είμαστε πρακτικά εγγυημένοι ότι, μετά την μεταφόρτωση της φωτογραφίας, θα την τραβήξουμε την πρώτη φορά και δεν θα πάμε πουθενά δεύτερη φορά.
Τι άλλο πήραμε, λοιπόν, που ήταν πραγματικά ωραίο;
Προηγουμένως, είχαμε κύρια διαμερίσματα αντιγράφων ασφαλείας και διαβάζαμε από αυτά διαδοχικά. Δηλαδή, πάντα ψάχναμε πρώτα στο κύριο και μετά στο αντίγραφο ασφαλείας. Ήταν μία κίνηση.
Τώρα χρησιμοποιούμε την ανάγνωση από δύο μηχανές ταυτόχρονα. Διανέμουμε τα αιτήματα χρησιμοποιώντας Round Robin. Σε ένα μικρό ποσοστό περιπτώσεων, υποβάλλουμε δύο αιτήματα. Συνολικά, όμως, έχουμε πλέον διπλάσιο χώρο ανάγνωσης από πριν. Και το φόρτο έχει μειωθεί σημαντικά τόσο στις μηχανές αποστολής όσο και απευθείας στις αποθήκες, κάτι που είχαμε και εκείνη την εποχή.
Όσο για την ανοχή σφαλμάτων. Στην πραγματικότητα, αυτό ήταν που κυρίως αγωνιζόμασταν. Με την ανοχή σφαλμάτων, όλα πήγαν περίφημα εδώ.

Ένα αυτοκίνητο χαλάει.

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

Το ίδιο ισχύει και για τη συντήρηση. Απλώς απενεργοποιούμε ένα από τα μηχανήματα, το βγάζουμε χειροκίνητα από όλες τις πισίνες, σταματά η κυκλοφορία του, κάνουμε κάποια συντήρηση, διορθώνουμε κάτι εκεί, μετά το επαναφέρουμε σε λειτουργία και αυτό το αντίγραφο ασφαλείας καλύπτεται αρκετά γρήγορα. Δηλαδή, σε μια μέρα ο χρόνος διακοπής λειτουργίας ενός μηχανήματος καλύπτεται μέσα σε λίγα λεπτά. Αυτό είναι πραγματικά πολύ μικρό. Όσο για την ανοχή σφαλμάτων, επαναλαμβάνω, όλα είναι ωραία εδώ.
Ποια συμπεράσματα μπορούν να εξαχθούν από αυτό το σχήμα με πλεονασμό;
Επιτύχαμε ανοχή σφαλμάτων.
Εύκολο στη λειτουργία. Δεδομένου ότι τα μηχανήματα διαθέτουν τοπικούς σκληρούς δίσκους, είναι πολύ πιο βολικό από την άποψη των μηχανικών που εργάζονται με αυτό.
Έχουμε διπλάσιο από το αποθεματικό ανάγνωσης.
Αυτό είναι ένα πολύ καλό πλεονέκτημα εκτός από την ανοχή σφαλμάτων.
Υπάρχουν όμως προβλήματα. Τώρα έχουμε μια πολύ πιο σύνθετη ανάπτυξη ορισμένων χαρακτηριστικών που σχετίζονται με αυτό, επειδή το σύστημα έχει τελικά γίνει 100% συνεπές.

Πρέπει, ας πούμε, σε κάποια εργασία στο παρασκήνιο να σκεφτόμαστε συνεχώς: "Σε ποιον διακομιστή τρέχουμε τώρα;", "Υπάρχει όντως κάποια ενημερωμένη φωτογραφία εδώ;" κ.λπ. Φυσικά, όλα αυτά είναι τυλιγμένα σε περιτυλίγματα, και για τον προγραμματιστή που γράφει την επιχειρηματική λογική, είναι διαφανή. Αλλά, παρ' όλα αυτά, έχει εμφανιστεί αυτό το μεγάλο σύνθετο επίπεδο. Αλλά είμαστε έτοιμοι να το ανεχτούμε αυτό με αντάλλαγμα τα καλούδια που λάβαμε από αυτό.
Και εδώ πάλι προκύπτει κάποια σύγκρουση.
Συνήθιζα να λέω ότι η αποθήκευση των πάντων σε τοπικούς σκληρούς δίσκους ήταν κακή. Τώρα λέω ότι μας άρεσε.
Ναι, πράγματι, με την πάροδο του χρόνου η κατάσταση έχει αλλάξει πολύ και τώρα αυτή η προσέγγιση έχει πολλά πλεονεκτήματα. Πρώτον, έχουμε πολύ πιο απλή λειτουργία.
Δεύτερον, είναι πιο παραγωγικό, επειδή δεν έχουμε αυτούς τους αυτόματους ελεγκτές, συνδέσεις με ράφια δίσκων.
Υπάρχει ένα τεράστιο μηχάνημα εκεί, και αυτοί είναι μόνο μερικοί δίσκοι που έχουν συναρμολογηθεί ειδικά σε μια επιδρομή εδώ στο μηχάνημα.
Υπάρχουν όμως και μειονεκτήματα.

Αυτό είναι περίπου 1,5 φορές πιο ακριβό από τη χρήση SAN, ακόμη και στις σημερινές τιμές. Επομένως, αποφασίσαμε να μην μετατρέψουμε ολόκληρο το μεγάλο σύμπλεγμά μας σε τοπικούς σκληρούς δίσκους και επιλέξαμε μια υβριδική λύση.
Τα μισά από τα μηχανήματά μας λειτουργούν με σκληρούς δίσκους (εντάξει, όχι τα μισά - ίσως το 30 τοις εκατό). Και τα υπόλοιπα είναι παλιά μηχανήματα που είχαν το πρώτο σχήμα δημιουργίας αντιγράφων ασφαλείας. Απλώς τα επανατοποθετήσαμε, αφού δεν χρειαζόμαστε νέα δεδομένα ή οτιδήποτε άλλο, απλώς μετακινήσαμε τα mount από έναν φυσικό κεντρικό υπολογιστή σε δύο.
Και αποκτήσαμε ένα μεγάλο απόθεμα για ανάγνωση και το διευρύναμε. Αν νωρίτερα τοποθετούσαμε έναν αποθηκευτικό χώρο σε ένα μηχάνημα, τώρα τοποθετούμε τέσσερις σε ένα ζεύγος, για παράδειγμα. Και λειτουργεί καλά.
Ας κάνουμε μια σύντομη περίληψη για όσα έχουμε καταφέρει, για τι αγωνιστήκαμε και αν λειτούργησαν.
Αποτελέσματα της
Έχουμε χρήστες - έως και 33 εκατομμύρια.
Έχουμε τρία σημεία παρουσίας - Πράγα, Μαϊάμι, Χονγκ Κονγκ.
Περιέχουν ένα επίπεδο προσωρινής αποθήκευσης, το οποίο είναι ένα μηχάνημα με γρήγορους τοπικούς δίσκους (SSD), στο οποίο λειτουργούν απλοί μηχανισμοί από το NGINX, το access.log και οι δαίμονες Python, οι οποίοι επεξεργάζονται όλα αυτά και διαχειρίζονται την προσωρινή μνήμη.
Αν επιθυμείτε, στο έργο σας, οι φωτογραφίες να μην είναι τόσο κρίσιμες για εσάς όσο είναι για εμάς ή αν ο έλεγχος των συμβιβασμών είναι αντίθετος με την ταχύτητα ανάπτυξης και το κόστος των πόρων για εσάς προς την αντίθετη κατεύθυνση, τότε μπορείτε εύκολα να το αντικαταστήσετε με ένα CDN. Τα σύγχρονα CDN το κάνουν αυτό καλά.
Στη συνέχεια έρχεται το επίπεδο αποθήκευσης, όπου έχουμε συστάδες ζευγών μηχανημάτων που δημιουργούν αντίγραφα ασφαλείας το ένα του άλλου και τα αρχεία αντιγράφονται ασύγχρονα από το ένα στο άλλο κάθε φορά που υπάρχει κάποια αλλαγή.
Ταυτόχρονα, ορισμένα από αυτά τα μηχανήματα λειτουργούν με τοπικούς σκληρούς δίσκους.
Ορισμένα από αυτά τα μηχανήματα είναι συνδεδεμένα σε SAN.

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

Επιτρέψτε μου να σας δώσω ένα παράδειγμα. Έχουμε μια ομάδα μηχανημάτων που στέλνουν φωτογραφίες από συνημμένα σε συνομιλίες, και το σχέδιο του 2009 εξακολουθεί να λειτουργεί εκεί, και κανείς δεν υποφέρει από αυτό. Όλοι είναι ευχαριστημένοι, σε όλους αρέσουν τα πάντα.
Για να μετρήσετε, πρώτα συγκεντρώστε μια σειρά από μετρήσεις, εξετάστε τες και, στη συνέχεια, αποφασίστε με τι δεν είστε ικανοποιημένοι και τι χρειάζεται βελτίωση. Για να μετρήσετε αυτό, έχουμε ένα ωραίο εργαλείο που ονομάζεται Pinba.
Σας επιτρέπει να συλλέγετε στατιστικά στοιχεία από το NGINX πολύ λεπτομερή για κάθε αίτημα και κωδικό απόκρισης, καθώς και κατανομή χρόνου - ό,τι θέλετε. Έχει συνδέσεις με κάθε είδους διαφορετικά συστήματα ανάλυσης και μπορείτε στη συνέχεια να τα δείτε όλα όμορφα.
Πρώτα μετρήσαμε και μετά βελτιώσαμε.
Στη συνέχεια. Βελτιστοποιούμε την ανάγνωση με την προσωρινή μνήμη, την εγγραφή με την sharding, αλλά αυτό είναι ένα προφανές σημείο.

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

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

Το τελευταίο σημείο είναι επίσης προφανές. Εάν η υποδομή σας δεν έχει τέτοια προβλήματα τώρα, αλλά υπάρχει κάτι που μπορεί να χαλάσει, σίγουρα θα χαλάσει όταν υπάρξει λίγο περισσότερο. Επομένως, είναι καλύτερο να το σκεφτείτε εκ των προτέρων και να μην έχετε προβλήματα. Αυτό είναι όλο για μένα.
Επαφές
»
»
Αυτή η ομιλία είναι ένα αντίγραφο μιας από τις καλύτερες ομιλίες που δόθηκε στο Συνέδριο Προγραμματιστών Συστημάτων Υψηλού Φορτίου Απομένει λιγότερο από ένας μήνας μέχρι το συνέδριο HighLoad++ 2017.
Το έχουμε ήδη έτοιμο , το πρόγραμμα διαμορφώνεται ενεργά αυτήν τη στιγμή.
Φέτος συνεχίζουμε να εξερευνούμε το θέμα των αρχιτεκτονικών και της κλιμάκωσης:
- / Ιγκόρ Βασιλίεφ
- / Ντμίτρι Εγκόροφ
- / Ανατόλι Πλασκόφσκι
- / Roman Shekhovtsov, Alexey Gromatchikov
- / Φιλίπ Ντελγκάδο
Χρησιμοποιούμε επίσης ορισμένα από αυτά τα υλικά στο διαδικτυακό μας εκπαιδευτικό μάθημα για την ανάπτυξη συστημάτων υψηλού φορτίου. — είναι μια αλυσίδα από ειδικά επιλεγμένες επιστολές, άρθρα, υλικό, βίντεο. Υπάρχουν ήδη περισσότερα από 30 μοναδικά υλικά στο εγχειρίδιό μας. Ελάτε μαζί μας!
Πηγή: www.habr.com
