Optimisation de la charge sur un projet Highload avec ElasticSearch

Hé Habr ! Je m'appelle Maxim Vasiliev, je travaille comme analyste et chef de projet chez FINCH. Aujourd'hui, je voudrais vous raconter comment, grâce à ElasticSearch, nous avons pu traiter 15 millions de requêtes en 6 minutes et optimiser les chargements quotidiens sur le site d'un de nos clients. Malheureusement, nous devrons nous passer de noms, puisque nous avons un NDA, nous espérons que le contenu de l'article n'en souffrira pas. Allons-y.

Comment fonctionne le projet

Sur notre backend, nous créons des services qui assurent la performance des sites Web et de l'application mobile de nos clients. La structure générale peut être vue dans le diagramme:

Optimisation de la charge sur un projet Highload avec ElasticSearch

En cours de travail, nous traitons un grand nombre de transactions : achats, paiements, opérations avec les soldes des utilisateurs, pour lesquels nous stockons de nombreux journaux, ainsi que l'importation et l'exportation de ces données vers des systèmes externes.

Il existe également des processus inverses lorsque nous recevons des données du client et que nous les transférons à l'utilisateur. De plus, il existe toujours des processus pour travailler avec les paiements et les programmes de bonus.

Bref historique

Initialement, nous avons utilisé PostgreSQL comme seul magasin de données. Ses avantages standards pour un SGBD : la présence de transactions, un langage d'échantillonnage de données développé, une large gamme d'outils d'intégration ; combinées à de bonnes performances ont satisfait nos besoins pendant assez longtemps.

Nous avons stocké absolument toutes les données dans Postgres : des transactions aux actualités. Mais le nombre d'utilisateurs a augmenté, et avec lui le nombre de demandes.

Pour comprendre, le nombre annuel de sessions en 2017 uniquement sur le site de bureau est de 131 millions. En 2018 - 125 millions. 2019 à nouveau 130 millions. Ajoutez encore 100 à 200 millions à partir de la version mobile du site et de l'application mobile, et vous recevra un grand nombre de demandes.

Avec la croissance du projet, Postgres a cessé de faire face à la charge, nous n'avions pas le temps - un grand nombre de requêtes diverses sont apparues, pour lesquelles nous n'avons pas pu créer un nombre suffisant d'index.

Nous avons compris qu'il y avait un besoin pour d'autres magasins de données qui répondraient à nos besoins et allégeraient PostgreSQL. Elasticsearch et MongoDB ont été considérés comme des options possibles. Ce dernier a perdu sur les points suivants :

  1. Vitesse d'indexation lente à mesure que la quantité de données dans les index augmente. Avec Elastic, la vitesse ne dépend pas de la quantité de données.
  2. Pas de recherche plein texte

Nous avons donc choisi Elastic pour nous-mêmes et préparé la transition.

Transition vers Elastic

1. Nous avons commencé la transition du service de recherche de point de vente. Notre client totalise environ 70 000 points de vente, et cela nécessite plusieurs types de recherches sur le site et dans l'application :

  • Recherche de texte par nom de ville
  • Geosearch dans un rayon donné à partir d'un certain point. Par exemple, si l'utilisateur souhaite voir quels points de vente sont les plus proches de son domicile.
  • Recherche par un carré donné - l'utilisateur dessine un carré sur la carte, et tous les points de ce rayon lui sont montrés.
  • Recherche par filtres supplémentaires. Les points de vente diffèrent les uns des autres dans l'assortiment

Si nous parlons de l'organisation, alors dans Postgres, nous avons une source de données à la fois pour la carte et les actualités, et dans Elastic Snapshots sont extraits des données d'origine. Le fait est qu'au départ, Postgres ne pouvait pas faire face à la recherche selon tous les critères. Non seulement il y avait de nombreux index, mais ils pouvaient également se chevaucher, de sorte que le planificateur Postgres s'est perdu et n'a pas compris quel index utiliser.

2. Vient ensuite la section des actualités. Des publications apparaissent sur le site tous les jours afin que l'utilisateur ne se perde pas dans le flux d'informations, les données doivent être triées avant émission. C'est à cela que sert la recherche : vous pouvez effectuer une recherche sur le site par correspondance de texte, et en même temps connecter des filtres supplémentaires, car ils sont également effectués via Elastic.

3. Ensuite, nous avons déplacé le traitement des transactions. Les utilisateurs peuvent acheter un certain produit sur le site et participer à un tirage au sort. Après de tels achats, nous traitons une grande quantité de données, notamment les week-ends et les jours fériés. À titre de comparaison, si les jours ordinaires, le nombre d'achats se situe entre 1,5 et 2 millions, alors les jours fériés, ce chiffre peut atteindre 53 millions.

Dans le même temps, les données doivent être traitées dans les plus brefs délais - les utilisateurs n'aiment pas attendre le résultat pendant plusieurs jours. Il n'y a aucun moyen d'atteindre de tels délais via Postgres - nous recevions souvent des verrous, et pendant que nous traitions toutes les demandes, les utilisateurs ne pouvaient pas vérifier s'ils avaient reçu des prix ou non. Ce n'est pas très agréable pour les entreprises, nous avons donc déplacé le traitement vers Elasticsearch.

périodicité

Désormais, les mises à jour sont configurées en fonction des événements, selon les conditions suivantes :

  1. Points de vente. Dès que nous recevons des données d'une source externe, nous commençons immédiatement la mise à jour.
  2. Nouvelles. Dès qu'une actualité est éditée sur le site, elle est automatiquement envoyée à Elastic.

Là encore, il convient de mentionner les avantages d'Elastic. Dans Postgres, lors de l'envoi d'une requête, vous devez attendre qu'il traite honnêtement tous les enregistrements. Vous pouvez envoyer 10 XNUMX enregistrements à Elastic et commencer à travailler immédiatement, sans attendre que les enregistrements soient distribués sur tous les fragments. Bien sûr, certains Shard ou Replica peuvent ne pas voir les données tout de suite, mais tout sera disponible très bientôt.

Méthodes d'intégration

Il existe 2 façons d'intégrer Elastic :

  1. Via un client natif sur TCP. Le pilote natif s'éteint progressivement : il n'est plus supporté, il a une syntaxe très gênante. Par conséquent, nous ne l'utilisons pratiquement pas et essayons de l'abandonner complètement.
  2. Via une interface HTTP qui peut utiliser à la fois les requêtes JSON et la syntaxe Lucene. Le dernier est un moteur de texte qui utilise Elastic. Dans cette version, nous avons la possibilité de traiter par lots les requêtes JSON via HTTP. C'est l'option que nous essayons d'utiliser.

Grâce à l'interface HTTP, nous pouvons utiliser des bibliothèques qui fournissent une implémentation asynchrone du client HTTP. Nous pouvons tirer parti de Batch et de l'API asynchrone, ce qui se traduit par des performances élevées, ce qui a beaucoup aidé à l'époque de la grande promotion (plus de détails ci-dessous)

Quelques chiffres à comparer :

  • Enregistrement des utilisateurs de Postgres Bounty dans 20 threads sans regroupement : 460713 42 enregistrements en XNUMX secondes
  • Client élastique + réactif pour 10 threads + batch pour 1000 éléments : 596749 enregistrements en 11 secondes
  • Client élastique + réactif pour 10 threads + batch pour 1000 éléments : 23801684 entrées en 4 minutes

Nous avons maintenant écrit un gestionnaire de requêtes HTTP qui construit JSON en tant que Batch/not Batch et l'envoie via n'importe quel client HTTP, quelle que soit la bibliothèque. Vous pouvez également choisir d'envoyer des demandes de manière synchrone ou asynchrone.

Dans certaines intégrations, nous utilisons toujours le client de transport officiel, mais ce n'est qu'une question de la prochaine refactorisation. Dans ce cas, un client personnalisé construit sur la base de Spring WebClient est utilisé pour le traitement.

Optimisation de la charge sur un projet Highload avec ElasticSearch

grande promotion

Une fois par an, le projet organise une grande promotion pour les utilisateurs - c'est le même Highload, car à l'heure actuelle, nous travaillons avec des dizaines de millions d'utilisateurs en même temps.

Habituellement, les pics de chargement se produisent pendant les vacances, mais cette promotion se situe à un tout autre niveau. L'avant-dernière année, le jour de la promotion, nous avons vendu 27 580 890 unités de marchandises. Les données ont été traitées pendant plus d'une demi-heure, ce qui a causé des désagréments aux utilisateurs. Les utilisateurs ont reçu des prix pour leur participation, mais il est devenu évident que le processus devait être accéléré.

Début 2019, nous avons décidé que nous avions besoin d'ElasticSearch. Pendant une année entière, nous avons organisé le traitement des données reçues dans Elastic et leur émission dans l'api de l'application mobile et du site web. En conséquence, l'année suivante, pendant la campagne, nous avons traité 15 131 783 entrées en 6 minutes.

Étant donné que nous avons beaucoup de gens qui veulent acheter des biens et participer au tirage au sort des prix dans les promotions, il s'agit d'une mesure temporaire. Nous envoyons maintenant des informations à jour à Elastic, mais à l'avenir, nous prévoyons de transférer les informations archivées des derniers mois vers Postgres en tant que stockage permanent. Afin de ne pas engorger l'indice élastique, qui a aussi ses limites.

Conclusion/Conclusions

Pour le moment, nous avons transféré tous les services que nous voulions vers Elastic et nous nous sommes arrêtés là-dessus pour le moment. Nous construisons maintenant un index dans Elastic au-dessus du stockage persistant principal dans Postgres, qui prend en charge la charge de l'utilisateur.

À l'avenir, nous prévoyons de transférer des services si nous comprenons que la demande de données devient trop diversifiée et est recherchée pour un nombre illimité de colonnes. Ce n'est plus une tâche pour Postgres.

Si nous avons besoin d'une fonctionnalité de recherche en texte intégral ou si nous avons de nombreux critères de recherche différents, nous savons déjà que cela doit être traduit dans Elastic.

⌘⌘⌘

Merci d'avoir lu. Si votre entreprise utilise également ElasticSearch et a ses propres cas de mise en œuvre, dites-le nous. Ce sera intéressant de savoir comment vont les autres 🙂

Source: habr.com

Ajouter un commentaire