Για να κατανοήσουμε ευκολότερα τι είναι αυτό το άρθρο, ας ξεκινήσουμε με την αλλαγή στη μέση ημερήσια στατιστική του Stack Overflow. Τα ακόλουθα στοιχεία προέρχονται από τα στατιστικά στοιχεία της 12ης Νοεμβρίου 2013:
- Ο εξισορροπητής φορτίου δέχτηκε 148.084.833 αιτήματα HTTP
- Από αυτές, οι 36.095.312 ήταν φορτώσεις σελίδων
- 833.992.982.627 byte (776 GB) κυκλοφορίας HTTP χρησιμοποιούνται για την αποστολή
- Ελήφθησαν συνολικά 286.574.644.032 bytes (267 GB) δεδομένων
- Συνολικά στάλθηκαν 1.125.992.557.312 bytes (1.048 GB) δεδομένων
- 334.572.103 ερωτήματα SQL (συμπεριλαμβανομένων μόνο από αιτήσεις HTTP)
- 412.865.051 αιτήσεις επανάληψης
- 3.603.418 αιτήματα Tag Engine
- Χρειάστηκαν 558.224.585 ms (155 ώρες) σε ερωτήματα SQL
- Χρειάστηκαν 99.346.916 ms (27 ώρες) σε αιτήματα Redis
- Ξοδέψατε 132.384.059 ms (36 ώρες) στο αίτημα μηχανής ετικετών
- Χρειάστηκαν 2.728.177.045 ms (757 ώρες) για ASP.Net επεξεργασία της διαδικασίας
Τα ακόλουθα δεδομένα δείχνουν τις αλλαγές στα στατιστικά στοιχεία από τις 9 Φεβρουαρίου 2016, ώστε να μπορείτε να συγκρίνετε:
- Αιτήματα HTTP που ελήφθησαν από τον εξισορροπητή φορτίου: 209.420.973 (+61.336.090)
- 66.294.789 (+30.199.477) εκ των οποίων φόρτωση σελίδας
- Απεσταλμένα δεδομένα HTTP: 1.240.266.346.053 (+406.273.363.426) bytes (1,24 TB)
- Συνολικός αριθμός ληφθέντων δεδομένων: 569.449.470.023 (+282.874.825.991) bytes (569 GB)
- Συνολικός αριθμός δεδομένων που στάλθηκαν: 3.084.303.599.266 (+1.958.311.041.954) bytes (3,08 TB)
- Ερωτήματα SQL (μόνο από αιτήσεις HTTP): 504.816.843 (+170.244.740)
- Επισκέψεις Redis Cache: 5,831,683,114 (+5,418,818,063)
- Ελαστικές αναζητήσεις: 17.158.874 (δεν εντοπίστηκαν το 2013)
- Αιτήματα μηχανών ετικετών: 3,661,134 (+57,716)
- Αθροιστικός χρόνος που καταναλώνεται για την εκτέλεση ερωτημάτων SQL: 607.073.066 (+48.848.481) ms (168 ώρες)
- Χρόνος επίσκεψης κρυφής μνήμης Redis που καταναλώθηκε: 10,396,073 (-88,950,843) ms (2.8 ώρες)
- Χρόνος που καταναλώνεται από αιτήματα Tag Engine: 147,018,571 (+14,634,512) ms (40.8 ώρες)
- Χρόνος που καταναλώνεται στην επεξεργασία ASP.Net: 1.609.944.301 (-1.118.232.744) ms (447 ώρες)
- 22,71 (-5,29) ms 49.180.275 σελίδες τεύχους μέσος χρόνος απόδοσης (εκ των οποίων 19,12 ms καταναλώνονται σε ASP.Net)
- 11,80 (-53,2) ms 6.370.076 πρώτες σελίδες μέσος χρόνος απόδοσης (εκ των οποίων 8,81 ms καταναλώνονται σε ASP.Net)
Ίσως αναρωτιέστε γιατί η ASP.Net επεξεργάζεται 61 εκατομμύρια περισσότερα αιτήματα την ημέρα, αλλά μειώνει τον χρόνο επεξεργασίας κατά 757 ώρες (σε σύγκριση με το 2013). Αυτό οφείλεται κυρίως στις αναβαθμίσεις που κάναμε στους διακομιστές μας στις αρχές του 2015, καθώς και σε πολλές εργασίες βελτιστοποίησης απόδοσης εντός εφαρμογής. Μην ξεχνάτε: η απόδοση εξακολουθεί να είναι ένα σημείο πώλησης. Εάν είστε πιο περίεργοι για τις συγκεκριμένες λεπτομέρειες υλικού, μην ανησυχείτε, θα δώσω τις συγκεκριμένες λεπτομέρειες υλικού των διακομιστών που χρησιμοποιούνται για την εκτέλεση αυτών των τοποθεσιών με τη μορφή παραρτήματος στο επόμενο άρθρο (θα ενημερώσω αυτόν τον σύνδεσμο όταν έρθει η ώρα).
Τι έχει αλλάξει λοιπόν τα τελευταία δύο χρόνια; Όχι πολύ, απλώς αντικαθιστώντας ορισμένους διακομιστές και εξοπλισμό δικτύου. Ακολουθεί μια επισκόπηση των διακομιστών που χρησιμοποιούνται για τη λειτουργία του ιστότοπού σας σήμερα (σημειώστε πώς έχουν αλλάξει από το 2013)
- 4 διακομιστές Microsoft SQL Server (2 από τους οποίους χρησιμοποιούν νέο υλικό)
- 11 διακομιστές Web IIS (νέο υλικό)
- 2 διακομιστές Redis (νέο υλικό)
- 3 διακομιστές Tag Engine (2 από τους οποίους χρησιμοποιούν νέο υλικό)
- 3 διακομιστές Elasticsearch (όπως παραπάνω)
- 4 διακομιστές εξισορρόπησης φορτίου HAProxy (2 προστέθηκαν για υποστήριξη CloudFlare)
- 2 συσκευές δικτύου (Nexus 5596 core + 2232TM Fabric Extender, όλες οι συσκευές έχουν αναβαθμιστεί σε εύρος ζώνης 10 Gbps)
- 2 x Fortinet 800C Firewall (αντικαθιστά το Cisco 5525-X ASA)
- 2 δρομολογητές Cisco ASR-1001 (αντικαθιστά τους δρομολογητές Cisco 3945)
- 2 δρομολογητές Cisco ASR-1001-x (ΝΕΟ!) )
Τι χρειαζόμαστε για να λειτουργήσει το Stack Overflow; Δεν έχουν αλλάξει πολλά από το 2013, αλλά χάρη στις βελτιστοποιήσεις και το νέο υλικό που αναφέρθηκε παραπάνω, χρειαζόμαστε πλέον μόνο έναν διακομιστή ιστού. Έχουμε ήδη δοκιμάσει αυτή την κατάσταση ακούσια, με επιτυχία αρκετές φορές. Σημείωση: Μόλις είπα ότι λειτουργεί, δεν είπα ότι είναι καλή ιδέα. Αλλά κάθε φορά που συμβαίνει αυτό, είναι αρκετά ενδιαφέρον.
Τώρα που έχουμε κάποιους βασικούς αριθμούς σχετικά με τις ιδέες κλιμάκωσης διακομιστή, ας δούμε πώς φτιάξαμε αυτές τις ενδιαφέρουσες ιστοσελίδες. Λίγα συστήματα υπάρχουν εντελώς ανεξάρτητα (και τα δικά μας δεν αποτελούν εξαίρεση) και χωρίς μια ολιστική άποψη που να ενσωματώνει αυτά τα μέρη, η έννοια του αρχιτεκτονικού σχεδιασμού μειώνεται σημαντικά. Στόχος μας είναι να κατανοήσουμε τη συνολική κατάσταση. Θα υπάρξουν πολλά άρθρα που θα εμβαθύνουν σε κάθε συγκεκριμένο πεδίο στο μέλλον. Αυτό το άρθρο είναι απλώς μια περίληψη της λογικής δομής του βασικού υλικού και το επόμενο άρθρο θα περιέχει συγκεκριμένες λεπτομέρειες σχετικά με αυτό το υλικό.
Αν θέλετε να δείτε πώς μοιάζει αυτό το υλικό σήμερα, εδώ είναι μερικές φωτογραφίες που τράβηξα από το ντουλάπι Α (το ντουλάπι Β είναι ακριβώς το ίδιο με αυτό) όταν αναβάθμισα τον διακομιστή τον Φεβρουάριο του 2015:
Τώρα, ας βουτήξουμε στη διάταξη της αρχιτεκτονικής. Ακολουθεί μια περίληψη της λογικής αρχιτεκτονικής των κύριων υπαρχόντων συστημάτων:
Βασικές αρχές
Ακολουθούν ορισμένες κοινές αρχές που δεν χρειάζεται να εισαχθούν με τη σειρά τους:
- Όλα έχουν περιττά αντίγραφα ασφαλείας.
- Όλοι οι διακομιστές και οι συσκευές δικτύου έχουν τουλάχιστον δύο συνδέσεις εύρους ζώνης 10 Gbps.
- Όλοι οι διακομιστές διαθέτουν δύο πηγές ενέργειας που παρέχουν ισχύ μέσω δύο σετ μονάδων UPS, δύο γεννήτριες πίσω τους και δύο τροφοδοτήσεις τάσης δικτύου.
- Όλοι οι διακομιστές έχουν ένα πλεονάζον αντίγραφο ασφαλείας που βρίσκεται στο Rack A και στο Rack B.
- Όλοι οι διακομιστές και οι υπηρεσίες έχουν διπλά περιττά αντίγραφα ασφαλείας σε ξεχωριστό κέντρο δεδομένων (στο Κολοράντο), αν και καλύπτω κυρίως τη Νέα Υόρκη.
- Όλα έχουν περιττά αντίγραφα ασφαλείας.
διαδίκτυο
Πρώτα πρέπει να βρείτε τον ιστότοπό μας, ο οποίος είναι θέμα DNS. Η εύρεση ιστότοπων είναι γρήγορη, επομένως το δίνουμε τώρα στο CloudFlare επειδή έχουν διακομιστές DNS σε κάθε γωνιά του κόσμου. Ενημερώνουμε τις εγγραφές DNS μέσω API και είναι υπεύθυνοι για τη «διαχείριση» του DNS. Ωστόσο, στο κακό μυαλό μας, εξακολουθούμε να έχουμε τους δικούς μας διακομιστές DNS λόγω των βαθιά ριζωμένων ζητημάτων εμπιστοσύνης. Όταν η αποκάλυψη είναι αποκαλυπτική – ίσως λόγω των προβλημάτων GPL, Punyon ή προσωρινής αποθήκευσης – και οι άνθρωποι εξακολουθούν να θέλουν να προγραμματίσουν για να αποσπάσουν την προσοχή τους, μεταβαίνουμε στους δικούς μας διακομιστές DNS.
Μόλις το πρόγραμμα περιήγησής σας βρει την κρυψώνα μας, η κίνηση HTTP από τους τέσσερις ISP μας (Level 3, Zayo, Cogent και Lightower στη Νέα Υόρκη) εισέρχεται σε έναν από τους τέσσερις προηγμένους δρομολογητές μας. Χρησιμοποιούμε το Border Gateway Protocol (BGP, ένα πολύ τυπικό πρωτόκολλο) για την κυκλοφορία peer-to-peer από παρόχους δικτύου για να την ελέγξουμε και να παρέχουμε τον πιο αποτελεσματικό τρόπο πρόσβασης στις υπηρεσίες μας. Οι δρομολογητές ASR-1001 και ASR-1001-X χωρίζονται σε δύο ομάδες, καθεμία από τις οποίες θα πρέπει να χρησιμοποιεί ενεργή/ενεργή λειτουργία για τη διαχείριση της κυκλοφορίας και από τους δύο παρόχους δικτύου – εδώ υπάρχουν περιττά αντίγραφα ασφαλείας. Αν και όλα έχουν το ίδιο φυσικό εύρος ζώνης 10 Gbps, η κίνηση από το εξωτερικό εξακολουθεί να είναι ανεξάρτητη από την κίνηση από το εξωτερικό VLAN και συνδέεται με την εξισορρόπηση φορτίου ξεχωριστά. Αφού η κίνηση περάσει από το δρομολογητή, θα έρθετε στον εξισορροπητή φορτίου.
Νομίζω ότι ίσως είναι καιρός να αναφέρουμε ότι έχουμε MPLS με εύρος ζώνης 10 Gbps μεταξύ των δύο κέντρων δεδομένων, αν και αυτό δεν σχετίζεται πραγματικά άμεσα με τις υπηρεσίες ιστότοπου. Χρησιμοποιούμε αυτήν την τεχνολογία για να πραγματοποιήσουμε αναπαραγωγή εκτός τοποθεσίας και ταχεία ανάκτηση δεδομένων για την αντιμετώπιση ορισμένων καταστάσεων έκτακτης ανάγκης. «Μα Νικ, δεν υπάρχει πλεονασμός σε αυτό!» Λοιπόν, από τεχνική άποψη έχετε δίκιο (με τη θετική έννοια), είναι πραγματικά ένα μόνο σημείο αποτυχίας σε αυτό το επίπεδο. Αλλά περίμενε! Μέσω του παρόχου δικτύου, έχουμε επίσης δύο επιπλέον διαδρομές ανακατεύθυνσης OSPF (το MPLS είναι η πρώτη επιλογή και αυτές είναι η δεύτερη και η τρίτη επιλογή για λόγους κόστους). Κάθε ένα από τα προαναφερθέντα σύνολα συσκευών θα συνδεθεί στο κέντρο δεδομένων του Κολοράντο ανάλογα για να εξισορροπήσει την κυκλοφορία του δικτύου σε περίπτωση ανακατεύθυνσης. Φυσικά, θα μπορούσαμε να είχαμε συνδέσει αυτά τα δύο σετ συσκευών μεταξύ τους, έτσι ώστε να υπάρχουν τέσσερα σετ μονοπατιών, αλλά ξεχάστε το, ας προχωρήσουμε.
Εξισορρόπηση φορτίου (HAProxy)
Η εξισορρόπηση φορτίου υλοποιείται με το HAProxy 1.5.15, που τρέχει στο CentOS 7 (η αγαπημένη μας έκδοση του Linux). Και προσθέστε πρωτόκολλο ασφαλούς μετάδοσης TLS (SSL) στο HAProxy. Παρακολουθούμε επίσης το HAProxy 1.7, το οποίο θα παρέχει υποστήριξη για το πρωτόκολλο HTTP/2 αμέσως.
Σε αντίθεση με άλλους διακομιστές με διπλές συνδέσεις δικτύου LACP 10 Gbps, κάθε εξισορροπητής φορτίου έχει δύο συνδέσεις 10 Gbps: μία για το εξωτερικό δίκτυο και η άλλη για το DMZ. Αυτοί οι διακομιστές διαθέτουν μνήμη 64 GB ή περισσότερο για να χειρίζονται το επίπεδο πρωτοκόλλου SSL πιο αποτελεσματικά. Όταν μπορούμε να αποθηκεύσουμε προσωρινά και να επαναχρησιμοποιήσουμε περισσότερες περιόδους λειτουργίας TLS στη μνήμη, καταναλώνουμε λιγότερους υπολογιστικούς πόρους όταν συνδεόμαστε στον ίδιο πελάτη. Αυτό σημαίνει ότι είμαστε σε θέση να επαναφέρουμε τις συνεδρίες με ταχύτερο και φθηνότερο τρόπο. Η μνήμη είναι τόσο φθηνή που είναι μια εύκολη επιλογή.
Η ίδια η εξισορρόπηση φορτίου είναι εύκολο να ρυθμιστεί. Ακούμε διαφορετικούς ιστότοπους σε πολλές διαφορετικές IP (κυρίως για λόγους διαχείρισης πιστοποιητικών και DNS) και στη συνέχεια δρομολογούμε την κυκλοφορία σε διαφορετικά backend (κυρίως με βάση τις κεφαλίδες του κεντρικού υπολογιστή). Το μόνο πράγμα που κάνουμε εδώ είναι να περιορίσουμε τον ρυθμό και να ξύσουμε κάποιες πληροφορίες κεφαλίδας (από το επίπεδο ιστού) για να συνδεθούμε στα μηνύματα καταγραφής συστήματος του HAProxy, με αυτόν τον τρόπο μπορούμε να καταγράψουμε μετρήσεις απόδοσης για κάθε αίτημα. Θα το αναφέρουμε λεπτομερώς αργότερα.
Επίπεδο Web (IIS 8.5, ASP.Net MVC 5.2.3 και .Net 4.6.1)
Η εξισορρόπηση φορτίου κατανέμει την κυκλοφορία μεταξύ 9 από αυτό που ονομάζουμε κύριο διακομιστή ιστού (01-09) και 2 διακομιστές ιστού ανάπτυξης (10-11, το περιβάλλον δοκιμής μας). Ο κύριος διακομιστής εκτελεί το Stack Overflow, το Careers και όλους τους ιστότοπους Stack Exchange, ενώ το meta.stackoverflow.com και το meta.stackexchange.com εκτελούνται σε δύο άλλους διακομιστές. Η ίδια η κύρια εφαρμογή Ερωτήσεων και απαντήσεων είναι πολλαπλών μισθωτών, πράγμα που σημαίνει ότι μια μεμονωμένη εφαρμογή χειρίζεται όλες τις αιτήσεις από την τοποθεσία Ερωτήσεων και απαντήσεων. Με άλλα λόγια, μπορούμε να εκτελέσουμε ολόκληρη την εφαρμογή Q&A σε έναν χώρο συγκέντρωσης εφαρμογών σε έναν διακομιστή. Άλλες εφαρμογές όπως Careers, API v2, Mobile API κ.λπ., είναι ανεξάρτητες. Δείτε τι βλέπετε στις υπηρεσίες IIS για τους κύριους διακομιστές και τους διακομιστές προγραμματιστών:
Ακολουθεί η κατανομή του επιπέδου ιστού του Stack Overflow όπως φαίνεται στο Opserver (ο εσωτερικός μας πίνακας ελέγχου παρακολούθησης):
Και εδώ είναι η κατανάλωση πόρων αυτών των διακομιστών ιστού:
Θα μπω σε περισσότερες λεπτομέρειες σε επόμενο άρθρο σχετικά με το γιατί παρέχουμε υπερβολικά τόσους πολλούς πόρους, εστιάζοντας στην κυλιόμενη κατασκευή, το περιθώριο και τον πλεονασμό.
Επίπεδο υπηρεσίας (IIS, ASP.Net MVC 5.2.3, . NET 4.6.1 και HTTP. SYS)
Δίπλα στο επίπεδο ιστού βρίσκεται το επίπεδο υπηρεσίας. Τρέχουν επίσης πάνω από το IIS 2012 στα Windows 8.5R2. Αυτό το επίπεδο εκτελεί ορισμένες εσωτερικές υπηρεσίες που υποστηρίζουν το επίπεδο ιστού και άλλα εσωτερικά συστήματα του περιβάλλοντος παραγωγής. Οι δύο κύριες υπηρεσίες είναι: "Stack Server", ο οποίος εκτελεί μια μηχανή ετικετών και βασίζεται σε http.sys (όχι IIS). Providence API (με βάση τις υπηρεσίες IIS). Ένα ενδιαφέρον γεγονός: Έπρεπε να συσχετίσω τις δύο διαδικασίες για να συνδεθώ σε διαφορετικές υποδοχές, επειδή ο διακομιστής στοίβας θα είχε πρόσβαση στις κρυφές μνήμες L2 και L3 πολύ συχνά κατά την ανανέωση της λίστας ζητημάτων σε διαστήματα δύο λεπτών.
Τα μηχανήματα που εκτελούν αυτές τις υπηρεσίες είναι ζωτικής σημασίας για τη μηχανή ετικετών και τα API παρασκηνίου, επομένως πρέπει να είναι περιττά, αλλά όχι 9x περιττά. Για παράδειγμα, φορτώνουμε όλα τα άρθρα και τις ετικέτες τους από τη βάση δεδομένων κάθε n λεπτά (προς το παρόν 2 λεπτά), κάτι που δεν είναι χαμηλό. Δεν θέλουμε να επαναλάβουμε αυτήν τη λειτουργία φόρτωσης 9 φορές στο επίπεδο ιστού, 3 φορές είναι αρκετά ασφαλές για εμάς. Χρησιμοποιούμε επίσης διαφορετικές διαμορφώσεις υλικού για αυτούς τους διακομιστές για καλύτερη βελτιστοποίηση για τα υπολογιστικά χαρακτηριστικά και τα χαρακτηριστικά φόρτωσης δεδομένων της μηχανής ετικετών και των εργασιών ελαστικού ευρετηρίου (που εκτελούνται επίσης σε αυτό το επίπεδο). Η ίδια η "μηχανή ετικετών" είναι ένα σχετικά περίπλοκο θέμα που θα καλυφθεί σε ένα ειδικό άρθρο. Η βασική αρχή είναι ότι όταν αποκτάτε πρόσβαση στη διεύθυνση /questions/tagged/java, επισκέπτεστε τη μηχανή προσθήκης ετικετών για να λάβετε τις ερωτήσεις που ταιριάζουν με αυτήν. Η μηχανή χειρίζεται όλη την αντιστοίχιση ετικετών εκτός από το /search, επομένως παντού, συμπεριλαμβανομένης της νέας πλοήγησης, λαμβάνει δεδομένα μέσω αυτής της υπηρεσίας.
Προσωρινή αποθήκευση & Δημοσίευση/Εγγραφή (Redis)
Χρησιμοποιήσαμε το Redis σε ορισμένα σημεία και έχει σταθερή σταθερότητα. Αν και υπάρχουν έως και 160 δισεκατομμύρια λειτουργίες ανά μήνα, η CPU ανά περίπτωση δεν υπερβαίνει το 2%, το οποίο είναι συνήθως χαμηλότερο:
Χρησιμοποιούμε το Redis για συστήματα προσωρινής αποθήκευσης επιπέδου L1/L2. Το επίπεδο "L1" είναι η προσωρινή μνήμη HTTP που λειτουργεί σε διακομιστή ιστού ή σε οποιαδήποτε παρόμοια εφαρμογή. Το επίπεδο "L2" είναι η λήψη δεδομένων μέσω του Redis μετά την αποτυχία της προσωρινής μνήμης του προηγούμενου επιπέδου. Τα δεδομένα μας αποθηκεύονται σε μορφή Protobuf, που υλοποιείται μέσω του protobuf-dot-net που γράφτηκε από τον Marc Gravel. Για τον πελάτη Redis, χρησιμοποιήσαμε τη βιβλιοθήκη StackExchange.Redis, η οποία είναι μια βιβλιοθήκη ανοιχτού κώδικα που αναπτύχθηκε εσωτερικά. Εάν ένας διακομιστής ιστού δεν χτυπήσει και στις κρυφές μνήμες L1 και L2, ανακτά δεδομένα από τις πηγές δεδομένων του (ερωτήματα βάσης δεδομένων, κλήσεις API κ.λπ.) και αποθηκεύει τα αποτελέσματα στην τοπική κρυφή μνήμη και στο Redis. Ο επόμενος διακομιστής μπορεί να λείπει από την κρυφή μνήμη L1 κατά την ανάκτηση των ίδιων δεδομένων, αλλά θα ανακτήσει τα δεδομένα στο L2/Redis, εξαλείφοντας την ανάγκη για ερωτήματα βάσης δεδομένων ή κλήσεις API.
Διαχειριζόμαστε επίσης πολλούς ιστότοπους Q&A, ο καθένας με τη δική του κρυφή μνήμη L1/L2: κλειδί ως πρόθεμα στην κρυφή μνήμη L1 και αναγνωριστικό βάσης δεδομένων στην κρυφή μνήμη L2/Redis. Θα εμβαθύνουμε σε αυτό το θέμα σε μελλοντικά άρθρα.
Εκτός από τους δύο κύριους διακομιστές Redis (έναν κύριο και έναν υποτελή) που εκτελούν όλες τις παρουσίες του ιστότοπου, δημιουργήσαμε επίσης ένα στιγμιότυπο για μηχανική εκμάθηση (κυρίως για λόγους μνήμης) χρησιμοποιώντας δύο άλλους αποκλειστικούς διακομιστές slave. Αυτή η ομάδα διακομιστών χρησιμοποιείται για την παροχή υπηρεσιών όπως η σύσταση ερωτήσεων στην αρχική σελίδα και η καλύτερη αντιστοίχιση εργασιών. Αυτή η πλατφόρμα ονομάζεται Providence και ο Kevin Montrose έγραψε σχετικά.
Ο κύριος διακομιστής Redis έχει 256 GB μνήμης RAM (χρησιμοποιούνται περίπου 90 GB) και ο διακομιστής Providence έχει 384 GB μνήμης (χρησιμοποιούνται περίπου 125 GB).
Το Redis δεν προορίζεται μόνο για προσωρινή αποθήκευση, αλλά διαθέτει επίσης μηχανισμό δημοσίευσης και εγγραφής όπου ένας διακομιστής μπορεί να δημοσιεύσει ένα μήνυμα και άλλοι συνδρομητές μπορούν να λάβουν το μήνυμα (συμπεριλαμβανομένου του Redis από μεταγενέστερους πελάτες στον διακομιστή). Χρησιμοποιούμε αυτόν τον μηχανισμό για να εκκαθαρίσουμε την προσωρινή μνήμη L1 σε άλλες υπηρεσίες για να διατηρήσουμε τη συνέπεια της προσωρινής μνήμης στον διακομιστή ιστού. Αλλά έχει μια άλλη σημαντική χρήση: τα websockets.
Websockets (NetGain)
Χρησιμοποιούμε websockets για να προωθήσουμε ενημερώσεις σε πραγματικό χρόνο στους χρήστες, όπως ειδοποιήσεις στην επάνω γραμμή, ψήφους, νέα πλοήγηση, νέες απαντήσεις, σχόλια και άλλα.
Ο ίδιος ο διακομιστής υποδοχής εκτελείται στο επίπεδο ιστού, χρησιμοποιώντας εγγενείς υποδοχές. Αυτή είναι μια πολύ μικρή εφαρμογή που βασίζεται στην υλοποίηση της βιβλιοθήκης ανοιχτού κώδικα: StackExchange.NetGain. Σε ώρες αιχμής, είχαμε περίπου 500.000 ταυτόχρονες συνδέσεις websocket, που είναι πολλά προγράμματα περιήγησης. Διασκεδαστικό γεγονός: ορισμένα από αυτά τα προγράμματα περιήγησης είναι ανοιχτά για περισσότερους από 18 μήνες και θα πρέπει να βρείτε κάποιον για να δείτε αν αυτοί οι προγραμματιστές είναι ακόμα ζωντανοί. Το παρακάτω γράφημα δείχνει το μοτίβο της ταυτόχρονης λειτουργίας websocket αυτήν την εβδομάδα:
Γιατί να χρησιμοποιήσετε websockets; Στην κλίμακα μας, είναι πολύ πιο αποτελεσματικό από τις δημοσκοπήσεις. Με αυτόν τον τρόπο, μπορούμε απλά να προωθήσουμε περισσότερα δεδομένα με λιγότερους πόρους και να είμαστε πιο σε πραγματικό χρόνο για τους χρήστες. Ωστόσο, αυτή η προσέγγιση δεν είναι χωρίς προβλήματα: οι προσωρινές θύρες, οι εξαντλημένες λαβές αρχείων στους εξισορροπητές φορτίου, είναι πολύ ενδιαφέροντα προβλήματα και θα μιλήσουμε για αυτά αργότερα.
Αναζήτηση (Elasticsearch)
Spoiler: Δεν υπάρχουν πολλά για να ενθουσιαστείτε εδώ. Το επίπεδο ιστού χρησιμοποιεί το Elasticsearch 1.4 και υλοποιεί έναν εξαιρετικά ελαφρύ, υψηλής απόδοσης πελάτη StackExchange.Elastic. Σε αντίθεση με τα περισσότερα πράγματα, δεν σκοπεύουμε να ανοίξουμε αυτό το μέρος, απλώς και μόνο επειδή εκθέτει ένα πολύ μικρό υποσύνολο των API που πρέπει να χρησιμοποιήσουμε. Είμαι σίγουρος ότι η δημοσιοποίησή του υπερτερεί της απώλειας και θα μπερδέψει μόνο τους προγραμματιστές. Χρησιμοποιούμε το elastic:/search σε αυτά τα μέρη για να υπολογίσουμε σχετικές ερωτήσεις και να δώσουμε προτάσεις όταν κάνουμε ερωτήσεις.
Κάθε ελαστικό σύμπλεγμα (ένα για κάθε κέντρο δεδομένων) περιέχει 3 κόμβους, ο καθένας με το δικό του ευρετήριο. Ο ιστότοπος Careers έχει επίσης ορισμένα πρόσθετα ευρετήρια. Ένα ελαφρώς λιγότερο τυπικό μέρος της διαμόρφωσής μας σε ελαστικούς κύκλους είναι ότι το σύμπλεγμα των 3 διακομιστών μας είναι λίγο πιο ισχυρό από τη συνηθισμένη διαμόρφωση: κάθε διακομιστής χρησιμοποιεί χώρο αποθήκευσης SSD, μνήμη 192 GB, διπλή δικτύωση εύρους ζώνης 10 Gbps.
Ο ίδιος τομέας εφαρμογής του Stack Server (ναι, μας πέταξε το .Net Core σε αυτό το μέρος) φιλοξενεί επίσης μια μηχανή ετικετών, η οποία χρησιμοποιεί επίσης το Elasticsearch για συνεχή ευρετηρίαση. Εδώ χρησιμοποιούμε ένα μικρό κόλπο, όπως η χρήση του ROWVERSION στον SQL Server (η πηγή δεδομένων) για σύγκριση με το έγγραφο "τελευταία θέση" στο Elastic. Επειδή είναι προφανώς διαδοχικό, είναι εύκολο για εμάς να ανιχνεύσουμε και να ευρετηριάσουμε το περιεχόμενο εάν τροποποιηθεί μετά την τελευταία επίσκεψη.
Ο κύριος λόγος που χρησιμοποιούμε το Elasticsearch αντί για τεχνολογίες όπως η αναζήτηση πλήρους κειμένου SQL είναι η επεκτασιμότητα και η οικονομική αποδοτικότητά του. Η SQL είναι σχετικά ακριβή στις CPU, ενώ η Elastic είναι πολύ φθηνότερη και έχει πολλές νέες δυνατότητες τον τελευταίο καιρό. Γιατί να μην χρησιμοποιήσετε το Solr; Πρέπει να κάνουμε αναζήτηση σε όλο το δίκτυο (με πολλαπλά ευρετήρια ταυτόχρονα) και το Solr δεν υποστηρίζει αυτό το σενάριο τη στιγμή των αποφάσεών μας. Ο λόγος που δεν έχουμε χρησιμοποιήσει ακόμα το 2.x είναι επειδή οι τύποι έχουν αλλάξει πολύ στο 2.x, πράγμα που σημαίνει ότι πρέπει να ευρετηριάζουμε ξανά τα πάντα αν θέλουμε να αναβαθμίσουμε. Απλώς δεν έχω αρκετό χρόνο για να προγραμματίσω τις αλλαγές απαιτήσεων και τις μετεγκαταστάσεις.
Βάση δεδομένων (SQL Server)
Χρησιμοποιούμε τον SQL Server ως ενιαία πηγή αλήθειας. Όλα τα δεδομένα στο Elastic και το Redis προέρχονται από τον SQL Server. Έχουμε δύο συμπλέγματα SQL Server και έχουμε ρυθμιστεί με ομάδες διαθεσιμότητας AlwaysOn. Κάθε σύμπλεγμα έχει έναν κύριο διακομιστή στη Νέα Υόρκη (ο οποίος αναλαμβάνει σχεδόν όλο το φορτίο) και έναν διακομιστή ρεπλίκα, εκτός από έναν διακομιστή ρεπλίκα στο Κολοράντο (το κέντρο δεδομένων αποκατάστασης καταστροφών). Όλες οι λειτουργίες αντιγραφής είναι ασύγχρονες.
Το πρώτο σύμπλεγμα είναι ένα σύνολο διακομιστών Dell R720xd, ο καθένας με 384 GB μνήμης, έναν PCIe SSD με 4 TB χώρου και δύο επεξεργαστές 12 πυρήνων. Περιλαμβάνει το Stack Overflow, το Sites (αυτό είναι κακό όνομα, θα το εξηγήσω αργότερα), το PRIZM και τη βάση δεδομένων του Mobile.
Το δεύτερο σύμπλεγμα είναι ένα σύνολο διακομιστών Dell R730xd, ο καθένας με 768 GB μνήμης, έναν PCIe SSD με 6 TB χώρου και δύο επεξεργαστές 8 πυρήνων. Αυτό το σύμπλεγμα περιέχει όλες τις άλλες βάσεις δεδομένων, συμπεριλαμβανομένων των Careers, Open ID, Chat, αρχείων καταγραφής εξαιρέσεων και άλλων τοποθεσιών Q&A (π.χ. Super User, Server Fault κ.λπ.).
Στο επίπεδο της βάσης δεδομένων, θέλουμε να διατηρήσουμε τη χρήση της CPU σε πολύ χαμηλό επίπεδο, αν και στην πράξη η χρήση της CPU θα είναι ελαφρώς υψηλότερη όταν παρουσιάζονται ορισμένα προγραμματισμένα προβλήματα προσωρινής αποθήκευσης (τα οποία αντιμετωπίζουμε). Επί του παρόντος, οι NY-SQL02 και 04 είναι οι κύριοι διακομιστές και οι 01 και 03 είναι οι διακομιστές ρεπλίκα και μόλις τους επανεκκινήσαμε σήμερα λόγω της αναβάθμισης του SSD. Δείτε την απόδοσή τους τις τελευταίες 24 ώρες:
Η χρήση της SQL είναι πολύ απλή. Απλό σημαίνει γρήγορο. Ενώ ορισμένες δηλώσεις ερωτημάτων μπορούν να διαστραφούν, η αλληλεπίδρασή μας με την ίδια την SQL γίνεται με έναν αρκετά εγγενή τρόπο. Έχουμε κάποια παλαιού τύπου Linq2Sql, αλλά όλες οι νέες εξελίξεις μας χρησιμοποιούν το Dapper, το πλαίσιο micro-ORM ανοιχτού κώδικα που χρησιμοποιεί POCO. Επιτρέψτε μου να το εξηγήσω αλλιώς: Το Stack Overflow έχει μόνο μία αποθηκευμένη διαδικασία στη βάση δεδομένων του και θα σκοτώσω αυτήν την τελευταία αποθηκευμένη διαδικασία που απομένει και θα την αντικαταστήσω με κώδικα.
Βιβλιοθήκη
Λοιπόν, ας αλλάξουμε γνώμη, εδώ είναι πράγματα που μπορούν να σας βοηθήσουν πιο άμεσα. Έχω αναφέρει μερικά από αυτά στο παρελθόν, αλλά θα σας δώσω μια λίστα με τις πολλές βιβλιοθήκες ανοιχτού κώδικα .Net που διατηρούμε και που χρησιμοποιούν όλοι. Τα ανοίγουμε επειδή δεν έχουν βασική επιχειρηματική αξία, αλλά μπορούν να βοηθήσουν προγραμματιστές σε όλο τον κόσμο. Ελπίζω να μπορείτε να τα χρησιμοποιήσετε τώρα:
- Dapper (.Net Core) – Ένα πλαίσιο micro-ORM υψηλής απόδοσης για ADO.Net
- StackExchange.Redis – Ένας πελάτης Redis υψηλής απόδοσης
- MiniProfiler – ένα ελαφρύ προφίλ που χρησιμοποιούμε σε κάθε σελίδα (υποστηρίζει επίσης Ruby, Go και Node)
- Εξαιρετικό - Για καταγραφή σφαλμάτων σε SQL, JSON, MySQL κ.λπ
- Jil – Σειριοποίηση και αποσειριοποιητής JSON υψηλής απόδοσης
- Sigil – .Net CIL Generation Helper (χρησιμοποιείται όταν η C# δεν είναι αρκετά γρήγορη)
- NetGain – Διακομιστής websocket υψηλής απόδοσης
- Opserver – Πίνακας ελέγχου παρακολούθησης που δημοσκοπεί απευθείας τα περισσότερα συστήματα και μπορεί να ανακτήσει πληροφορίες από το Orion, το Bosun ή το WMI
- Bosun – Σύστημα παρακολούθησης στο παρασκήνιο, γραμμένο σε Go
|