Βελτιστοποίηση φόρτωσης σε ένα έργο Highload με το ElasticSearch

Γεια σου Χαμπρ! Ονομάζομαι Maxim Vasiliev, εργάζομαι ως αναλυτής και project manager στο FINCH. Σήμερα θα ήθελα να σας πω πώς, χρησιμοποιώντας το ElasticSearch, μπορέσαμε να επεξεργαστούμε 15 εκατομμύρια αιτήματα σε 6 λεπτά και να βελτιστοποιήσουμε τις ημερήσιες φορτώσεις στον ιστότοπο ενός από τους πελάτες μας. Δυστυχώς, θα πρέπει να κάνουμε χωρίς ονόματα, αφού έχουμε NDA, ελπίζουμε ότι το περιεχόμενο του άρθρου δεν θα υποφέρει από αυτό. Πάμε.

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

Στο backend μας, δημιουργούμε υπηρεσίες που διασφαλίζουν την απόδοση των ιστοσελίδων των πελατών μας και της εφαρμογής για κινητά. Η γενική δομή φαίνεται στο διάγραμμα:

Βελτιστοποίηση φόρτωσης σε ένα έργο Highload με το ElasticSearch

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

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

Σύντομο φόντο

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

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

Για να κατανοήσουμε, ο ετήσιος αριθμός περιόδων σύνδεσης το 2017 μόνο στον ιστότοπο για υπολογιστές είναι 131 εκατομμύρια. Το 2018 - 125 εκατομμύρια. 2019 πάλι 130 εκατομμύρια. Προσθέστε άλλα 100-200 εκατομμύρια από την έκδοση για κινητά του ιστότοπου και την εφαρμογή για κινητά και εσείς θα λάβει έναν τεράστιο αριθμό αιτημάτων.

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

Καταλάβαμε ότι υπήρχε ανάγκη για άλλα καταστήματα δεδομένων που θα κάλυπταν τις ανάγκες μας και θα έβγαζαν το φορτίο από την PostgreSQL. Το Elasticsearch και το MongoDB θεωρήθηκαν ως πιθανές επιλογές. Ο τελευταίος έχασε στους εξής βαθμούς:

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

Έτσι επιλέξαμε το Elastic για εμάς και προετοιμαστήκαμε για τη μετάβαση.

Μετάβαση στο ελαστικό

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

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

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

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

3. Στη συνέχεια μετακινήσαμε την επεξεργασία συναλλαγής. Οι χρήστες μπορούν να αγοράσουν ένα συγκεκριμένο προϊόν στον ιστότοπο και να συμμετάσχουν σε μια κλήρωση. Μετά από τέτοιες αγορές, επεξεργαζόμαστε μεγάλο όγκο δεδομένων, ειδικά τα Σαββατοκύριακα και τις αργίες. Για σύγκριση, εάν τις συνηθισμένες ημέρες ο αριθμός των αγορών είναι κάπου μεταξύ 1,5-2 εκατομμυρίων, τότε στις αργίες ο αριθμός μπορεί να φτάσει τα 53 εκατομμύρια.

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

Περιοδικότητα

Τώρα οι ενημερώσεις διαμορφώνονται βάσει συμβάντων, σύμφωνα με τις ακόλουθες συνθήκες:

  1. Σημεία πώλησης. Μόλις λάβουμε δεδομένα από εξωτερική πηγή, ξεκινάμε αμέσως την ενημέρωση.
  2. Νέα. Μόλις γίνει επεξεργασία οποιασδήποτε είδησης στον ιστότοπο, αποστέλλεται αυτόματα στο Elastic.

Και εδώ αξίζει να αναφέρουμε τα πλεονεκτήματα του Elastic. Στο Postgres, όταν στέλνετε ένα αίτημα, πρέπει να περιμένετε μέχρι να επεξεργαστεί ειλικρινά όλες τις εγγραφές. Μπορείτε να στείλετε 10 εγγραφές στο Elastic και να αρχίσετε να εργάζεστε αμέσως, χωρίς να περιμένετε να διανεμηθούν οι εγγραφές σε όλα τα Shards. Φυσικά, κάποιο Shard ή Replica μπορεί να μην δουν τα δεδομένα αμέσως, αλλά όλα θα είναι διαθέσιμα πολύ σύντομα.

Μέθοδοι ολοκλήρωσης

Υπάρχουν 2 τρόποι ενσωμάτωσης με το Elastic:

  1. Μέσω ενός εγγενούς πελάτη μέσω TCP. Το εγγενές πρόγραμμα οδήγησης σταδιακά εξαφανίζεται: δεν υποστηρίζεται πλέον, έχει πολύ άβολη σύνταξη. Επομένως, πρακτικά δεν το χρησιμοποιούμε και προσπαθούμε να το εγκαταλείψουμε εντελώς.
  2. Μέσω μιας διεπαφής HTTP που μπορεί να χρησιμοποιεί τόσο αιτήματα JSON όσο και σύνταξη Lucene. Το τελευταίο είναι μια μηχανή κειμένου που χρησιμοποιεί Elastic. Σε αυτήν την έκδοση, έχουμε τη δυνατότητα ομαδοποίησης μέσω αιτημάτων JSON μέσω HTTP. Αυτή είναι η επιλογή που προσπαθούμε να χρησιμοποιήσουμε.

Χάρη στη διεπαφή HTTP, μπορούμε να χρησιμοποιήσουμε βιβλιοθήκες που παρέχουν μια ασύγχρονη υλοποίηση του προγράμματος-πελάτη HTTP. Μπορούμε να εκμεταλλευτούμε το Batch και το ασύγχρονο API, το οποίο έχει ως αποτέλεσμα υψηλή απόδοση, κάτι που βοήθησε πολύ τις ημέρες της μεγάλης προσφοράς (περισσότερα για αυτό παρακάτω)

Μερικοί αριθμοί για σύγκριση:

  • Αποθήκευση χρηστών Bounty Postgres σε 20 νήματα χωρίς ομαδοποίηση: 460713 εγγραφές σε 42 δευτερόλεπτα
  • Elastic + reactive client για 10 νήματα + batch για 1000 στοιχεία: 596749 εγγραφές σε 11 δευτερόλεπτα
  • Elastic + reactive client για 10 νήματα + batch για 1000 στοιχεία: 23801684 καταχωρήσεις σε 4 λεπτά

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

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

Βελτιστοποίηση φόρτωσης σε ένα έργο Highload με το ElasticSearch

μεγάλη προώθηση

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

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

Στις αρχές του 2019, αποφασίσαμε ότι χρειαζόμασταν το ElasticSearch. Για έναν ολόκληρο χρόνο οργανώναμε την επεξεργασία των ληφθέντων δεδομένων στο Elastic και την έκδοσή τους στο api της εφαρμογής για κινητά και της ιστοσελίδας. Ως αποτέλεσμα, την επόμενη χρονιά κατά τη διάρκεια της εκστρατείας, επεξεργαστήκαμε 15 συμμετοχές σε 131 λεπτά.

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

Συμπέρασμα/Συμπεράσματα

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

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

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

⌘⌘⌘

Ευχαριστώ για την ανάγνωση. Εάν η εταιρεία σας χρησιμοποιεί επίσης ElasticSearch και έχει τις δικές της περιπτώσεις υλοποίησης, τότε πείτε μας. Θα είναι ενδιαφέρον να μάθετε πώς είναι οι άλλοι 🙂

Πηγή: www.habr.com

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