Bonjour, Habr ! Je m'appelle Maxim Vassiliev, je travaille comme analyste et chef de projet chez FINCH. Aujourd'hui, je voudrais expliquer comment, grĂące Ă ElasticSearch, nous avons pu traiter 15 millions de requĂȘtes en 6 minutes et optimiser les charges quotidiennes sur le site de l'un de nos clients. Malheureusement, nous devrons nous passer de noms, car nous avons un NDA, mais nous espĂ©rons que le contenu de l'article ne souffrira pas de cela. Allons-y.
Comment le projet est structuré
Dans notre backend, nous crĂ©ons des services qui assurent le bon fonctionnement des sites et de l'application mobile de notre client. La structure gĂ©nĂ©rale peut ĂȘtre vue sur le schĂ©ma :

Dans le cadre de notre travail, nous traitons un grand nombre de transactions : achats, paiements, opérations sur les soldes des utilisateurs, pour lesquelles nous stockons de nombreux logs, et nous importons également et exportons ces données vers des systÚmes externes.
Des processus inverses se déroulent également, lorsque nous recevons des données du client et les transmettons aux utilisateurs. En outre, il existe des processus relatifs aux paiements et aux programmes de bonus.
Une brĂšve histoire
Au dĂ©part, nous utilisions PostgreSQL comme unique stockage de donnĂ©es. Ses avantages standards pour les SGBD : la prĂ©sence de transactions, un langage de requĂȘte dĂ©veloppĂ©, un large Ă©ventail d'outils pour l'intĂ©gration ; associĂ©s Ă une bonne performance, ils satisfaisaient nos besoins pendant assez longtemps.
Nous stockions dans Postgres absolument toutes les donnĂ©es : des transactions aux actualitĂ©s. Mais le nombre d'utilisateurs augmentait, et avec lui, le nombre de requĂȘtes.
Pour donner une idĂ©e, le nombre annuel de sessions en 2017 sur le site desktop Ă©tait de 131 millions. En 2018, il est tombĂ© Ă 125 millions. En 2019, il a de nouveau atteint 130 millions. Ajoutez-y encore 100 Ă 200 millions de la version mobile du site et de l'application mobile, et vous obtiendrez un nombre colossal de requĂȘtes.
Avec la croissance du projet, Postgres a cessĂ© de gĂ©rer la charge, nous n'arrivions plus Ă suivre â un grand nombre de requĂȘtes variĂ©es sont apparues, pour lesquelles nous n'avons pas pu crĂ©er un nombre suffisant d'index.
Nous comprenions qu'il était nécessaire d'avoir d'autres systÚmes de stockage qui répondraient à nos besoins et allégeraient la charge sur PostgreSQL. Nous avons envisagé Elasticsearch et MongoDB comme options possibles. La derniÚre a échoué sur les points suivants :
- Une vitesse d'indexation lente avec l'augmentation du volume de données dans les index. Avec Elastic, la vitesse n'est pas affectée par le volume de données.
- Pas de recherche en texte intégral
C'est ainsi que nous avons choisi Elastic et nous nous sommes préparés à la migration.
Migration vers Elastic
1. Nous avons commencé la migration avec le service de recherche de points de vente. Notre client a environ 70 000 points de vente au total, et il nécessite plusieurs types de recherches sur le site et dans l'application :
- Recherche textuelle par nom de localité
- Recherche géographique dans un rayon donné à partir d'un point. Par exemple, si l'utilisateur veut voir quels points de vente sont les plus proches de chez lui.
- Recherche par un carrĂ© dĂ©fini â l'utilisateur trace un carrĂ© sur la carte et tous les points dans ce rayon lui sont montrĂ©s.
- Recherche par filtres supplémentaires. Les points de vente diffÚrent les uns des autres par leur assortiment.
En ce qui concerne l'organisation, dans Postgres, nous avons une source de donnĂ©es tant pour la carte que pour les nouvelles, et dans Elastic, des instantanĂ©s des donnĂ©es originales sont créés. Le fait est qu'Ă l'origine, Postgres ne parvenait pas Ă effectuer des recherches selon tous les critĂšres. Non seulement il y avait de nombreux index, mais ils pouvaient Ă©galement se chevaucher, ce qui perdait le planificateur de Postgres et l'empĂȘchait de comprendre quel index utiliser.
2. Ensuite, c'Ă©tait au tour de la section des nouvelles. Chaque jour, de nouvelles publications apparaissent sur le site, et pour que l'utilisateur ne se perde pas dans le flux d'informations, les donnĂ©es doivent ĂȘtre triĂ©es avant d'ĂȘtre affichĂ©es. C'est Ă©galement le but de la recherche: sur le site, il est possible de rechercher par correspondance textuelle, tout en branchant des filtres supplĂ©mentaires, puisqu'ils sont aussi rĂ©alisĂ©s via Elastic.
3. Ensuite, nous avons transfĂ©rĂ© le traitement des transactions. Les utilisateurs peuvent acheter un certain produit sur le site et participer Ă des tirages au sort. AprĂšs ces achats, nous traitons un grand volume de donnĂ©es, surtout durant les week-ends et les jours fĂ©riĂ©s. Ă titre de comparaison, en semaine, le nombre d'achats est d'environ 1,5 Ă 2 millions, alors qu'en pĂ©riode de fĂȘtes, ce chiffre peut atteindre 53 millions.
De plus, les donnĂ©es doivent ĂȘtre traitĂ©es dans les plus brefs dĂ©lais â les utilisateurs n'aiment pas attendre plusieurs jours pour connaĂźtre les rĂ©sultats. Avec Postgres, on ne peut pas atteindre de tels dĂ©lais â nous subissions souvent des blocages, et pendant que nous traitions toutes les requĂȘtes, les utilisateurs ne pouvaient pas vĂ©rifier s'ils avaient gagnĂ© des prix ou non. Ce n'est pas trĂšs agrĂ©able pour les affaires, c'est pourquoi nous avons transfĂ©rĂ© le traitement dans Elasticsearch.
Fréquence
Les mises à jour sont actuellement configurées sur une base d'événements, selon les conditions suivantes :
- Points de vente. DÚs que nous recevons des données d'une source externe, nous lançons immédiatement la mise à jour.
- Actualités. DÚs qu'une actualité est modifiée sur le site, elle est automatiquement envoyée à Elastic.
Il convient encore une fois de mentionner les avantages d'Elastic. Dans Postgres, lors de l'envoi d'une requĂȘte, il faut attendre qu'elle traite toutes les entrĂ©es. Avec Elastic, il est possible d'envoyer 10 000 enregistrements et de commencer Ă travailler immĂ©diatement, sans attendre que les donnĂ©es se rĂ©partissent sur tous les Shards. Bien sĂ»r, un Shard ou une RĂ©plica peuvent ne pas voir les donnĂ©es immĂ©diatement, mais bientĂŽt tout sera accessible.
Méthodes d'intégration
Il existe 2 méthodes d'intégration avec Elastic :
- Via le client natif par TCP. Le pilote natif est progressivement abandonné : il n'est plus soutenu et a une syntaxe trÚs peu pratique. C'est pourquoi nous l'utilisons pratiquement plus et essayons de nous en débarrasser totalement.
- Via l'interface HTTP, oĂč l'on peut utiliser Ă la fois des requĂȘtes JSON et la syntaxe Lucene. Ce dernier est le moteur texte utilisĂ© par Elastic. Dans cette option, nous avons la possibilitĂ© de Batch via des requĂȘtes JSON sur HTTP. C'est cette 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, en fin de compte, donne de hautes performances, qui ont été trÚs utiles lors des grandes opérations (à ce sujet ci-dessous)
Quelques chiffres pour la comparaison :
- Sauvegarde des utilisateurs ayant reçu des prix dans Postgres en 20 threads sans regroupements : 460 713 enregistrements en 42 secondes
- Elastic + client réactif sur 10 threads + batch de 1000 éléments : 596 749 enregistrements en 11 secondes
- Elastic + client réactif sur 10 threads + batch de 1000 éléments : 23 801 684 enregistrements en 4 minutes
Nous avons maintenant Ă©crit un gestionnaire de requĂȘtes HTTP qui construit JSON, en tant que Batch/non Batch, et envoie via n'importe quel client HTTP, indĂ©pendamment de la bibliothĂšque. Il est Ă©galement possible de choisir d'envoyer des requĂȘtes de maniĂšre synchrone ou asynchrone.
Dans certaines intégrations, nous utilisons encore le client de transport officiel, mais c'est juste une question de refactorisation prochaine. Pour le traitement, un client propre, construit sur la base de Spring WebClient, est utilisé.

Grande opération
Une grande promotion a lieu une fois par an pour les utilisateurs - c'est ce fameux Highload, car à ce moment là , nous traitons des dizaines de millions d'utilisateurs simultanément.
Les pics de charge se produisent gĂ©nĂ©ralement pendant les jours fĂ©riĂ©s, mais cette promotion est d'un tout autre niveau. L'annĂ©e prĂ©cĂ©dente, le jour de la promotion, nous avons vendu 27 580 890 unitĂ©s. 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é qu'ElasticSearch était nécessaire. Pendant toute une année, nous avons organisé le traitement des données reçues dans Elastic et leur fourniture via l'API de l'application mobile et du site. En conséquence, l'année suivante, pendant la promotion, nous avons traité 15 131 783 enregistrements en 6 minutes.
Ătant donnĂ© qu'il y a beaucoup de personnes dĂ©sireuses d'acheter des produits et de participer Ă des tirages pendant les promotions, c'est une mesure temporaire. Actuellement, nous envoyons les informations actuelles vers Elastic, mais Ă l'avenir, nous prĂ©voyons de transfĂ©rer des informations archivĂ©es des mois prĂ©cĂ©dents vers Postgres, comme un stockage permanent. Cela nous permet d'Ă©viter de surcharger l'index Elastic, qui a aussi ses limites.
Conclusion / Résumé
à l'heure actuelle, nous avons transféré vers Elastic tous les services que nous voulions et nous avons mis cela en pause pour le moment. Maintenant, nous construisons un index dans Elastic au-dessus du stockage persistant principal dans Postgres, qui prend en charge la charge utilisateur.
à l'avenir, nous prévoyons de transférer des services si nous réalisons que les demandes de données deviennent trop variées et que la recherche s'effectue sur un nombre illimité de colonnes. Cela devient déjà une tùche pour Postgres.
Si nous avons besoin de recherche en texte intĂ©gral dans les fonctionnalitĂ©s ou si de nombreux critĂšres de recherche variĂ©s apparaissent, nous savons dĂ©jĂ que cela devra ĂȘtre transfĂ©rĂ© vers Elastic.
âââ
Merci d'avoir lu. Si votre entreprise utilise Ă©galement ElasticSearch et a ses propres cas d'implĂ©mentation, n'hĂ©sitez pas Ă en parler. Ce sera intĂ©ressant de savoir comment d'autres font đ
Source : habr.com
