Optimització de càrrega en un projecte Highload amb ElasticSearch

Hola, Habr! Em dic Maxim Vasiliev, treballo com a analista i gestor de projectes a FINCH. Avui m'agradaria explicar-vos com, amb ElasticSearch, hem pogut processar 15 milions de consultes en 6 minuts i optimitzar la càrrega diària al lloc d'un dels nostres clients. Malauradament, haurem de prescindir de noms, com que tenim un NDA, esperem que el contingut de l'article no ho patirà. Som-hi.

Com funciona el projecte

Al nostre backend creem serveis que garanteixen la funcionalitat dels llocs web i de les aplicacions mòbils dels nostres clients. L'estructura general es pot veure al diagrama:

Optimització de càrrega en un projecte Highload amb ElasticSearch

En el procés de treball, processem un gran nombre de transaccions: compres, pagaments, transaccions amb saldos d'usuari, per a les quals emmagatzemem molts registres, i també importem i exportem aquestes dades a sistemes externs.

També hi ha processos inversos quan rebem dades del client i les transmetem a l'usuari. A més, també hi ha processos per treballar amb programes de pagaments i bonificacions.

Breu antecedents

Inicialment, vam utilitzar PostgreSQL com a únic emmagatzematge de dades. Els seus avantatges són estàndard per a un SGBD: la presència de transaccions, un llenguatge desenvolupat de recuperació de dades, una àmplia gamma d'eines per a la integració; combinat amb un bon rendiment va satisfer les nostres necessitats durant força temps.

Hem emmagatzemat absolutament totes les dades a Postgres: des de transaccions fins a notícies. Però el nombre d'usuaris va créixer, i amb ell el nombre de peticions.

Per entendre's, el nombre anual de sessions el 2017 només al lloc d'escriptori va ser de 131 milions. El 2018 - 125 milions. El 2019 de nou 130 milions. Afegiu 100-200 milions més de la versió mòbil del lloc i de l'aplicació mòbil, i rebrà un nombre colossal de peticions.

A mesura que el projecte va créixer, Postgres ja no va poder fer front a la càrrega; no vam poder seguir el ritme: van aparèixer un gran nombre de consultes diferents, per a les quals no vam poder crear un nombre suficient d'índexs.

Ens vam adonar que hi havia una necessitat d'altres magatzems de dades que satisfés les nostres necessitats i al·leguessin la càrrega de PostgreSQL. Elasticsearch i MongoDB es van considerar com a opcions possibles. Aquest últim va perdre en els punts següents:

  1. Velocitat d'indexació lenta a mesura que creix el volum de dades dels índexs. Amb Elastic, la velocitat no depèn de la quantitat de dades.
  2. No hi ha cerca de text complet

Així que vam triar Elastic per a nosaltres mateixos i ens vam preparar per a la transició.

Canvia a Elàstic

1. Vam començar la transició amb un servei de cerca de punts de venda. El nostre client disposa d'un total d'uns 70 punts de venda, i alhora es requereixen diversos tipus de cerca al web i a l'aplicació:

  • Cerca de text per nom de localitat
  • Geocerca dins d'un radi determinat des d'un punt determinat. Per exemple, si un usuari vol veure quins punts de venda són més propers a casa seva.
  • Cerca per un quadrat determinat: l'usuari dibuixa un quadrat al mapa i se li mostren tots els punts d'aquest radi.
  • Cerca per filtres addicionals. Els punts de venda difereixen entre si en l'assortiment

Parlant de l'organització, a Postgres tenim una font de dades tant per al mapa com per a les notícies, i a Elastic fem Snapshots a partir de les dades originals. El fet és que inicialment Postgres no podia fer front a la recerca de tots els criteris. No només hi havia molts índexs, sinó que també podien superposar-se, de manera que el programador de Postgres es va perdre i no entenia quin índex utilitzar.

2. El següent a la fila va ser la secció de notícies. Cada dia apareixen publicacions al lloc perquè l'usuari no es perdi en el flux d'informació, les dades s'han d'ordenar abans d'emetre. Això és el que serveix una cerca: al lloc es pot cercar per concordança de text, i alhora connectar filtres addicionals, ja que també es fan mitjançant Elastic.

3. Després vam traslladar el processament de transaccions. Els usuaris poden comprar un producte específic al lloc i participar en un sorteig. Després d'aquestes compres, processem una gran quantitat de dades, especialment els caps de setmana i festius. En comparació, si els dies normals el nombre de compres ronda els 1,5-2 milions, els dies festius la xifra pot arribar als 53 milions.

Al mateix temps, les dades s'han de processar en un temps mínim; als usuaris no els agrada esperar diversos dies per obtenir resultats. No hi ha manera d'aconseguir aquests terminis a través de Postgres: sovint rebíem blocs i mentre processàvem totes les sol·licituds, els usuaris no podien comprovar si rebien premis o no. Això no és molt agradable per als negocis, així que vam traslladar el processament a Elasticsearch.

Periodicitat

Ara les actualitzacions es configuren en funció d'esdeveniments, d'acord amb les condicions següents:

  1. Punts de venda. Tan bon punt rebem dades d'una font externa, iniciem immediatament una actualització.
  2. Notícies. Tan bon punt s'edita qualsevol notícia al lloc, s'envia automàticament a Elastic.

Aquí de nou val la pena esmentar els avantatges d'Elastic. A Postgres, quan envieu una sol·licitud, heu d'esperar fins que processi honestament tots els registres. Podeu enviar 10 mil registres a Elastic i començar a treballar immediatament, sense esperar que els registres es distribueixin a tots els fragments. Per descomptat, és possible que alguns fragments o rèpliques no vegin les dades immediatament, però molt aviat tot estarà disponible.

Mètodes d'integració

Hi ha 2 maneres d'integrar-se amb Elastic:

  1. Mitjançant un client natiu mitjançant TCP. El controlador natiu s'està extingint a poc a poc: ja no és compatible i la seva sintaxi és molt incòmode. Per tant, pràcticament no l'utilitzem i intentem abandonar-lo completament.
  2. Mitjançant una interfície HTTP en la qual podeu utilitzar tant sol·licituds JSON com la sintaxi de Lucene. L'últim és el motor de text que utilitza Elastic. En aquesta opció, tenim la possibilitat de fer lots mitjançant sol·licituds JSON mitjançant HTTP. Aquesta és l'opció que estem intentant utilitzar.

Gràcies a la interfície HTTP, podem utilitzar biblioteques que proporcionen una implementació asíncrona del client HTTP. Podem aprofitar Batch i l'API asíncrona, que en última instància ofereix un alt rendiment, que va ajudar molt durant els dies d'una gran promoció (més informació a continuació)

Alguns números per comparar:

  • Desa d'usuaris que van rebre premis a Postgres en 20 fils sense agrupacions: 460713 registres en 42 segons
  • Client elàstic + reactiu per a 10 fils + lot per a 1000 elements: 596749 registres en 11 segons
  • Client elàstic + reactiu per a 10 fils + lot per a 1000 elements: 23801684 registres en 4 minuts

Ara hem escrit un gestor de sol·licituds HTTP que crea JSON com a lot/no-batch i l'envia a través de qualsevol client HTTP, independentment de la biblioteca. També podeu triar enviar sol·licituds de manera síncrona o asíncrona.

En algunes integracions encara fem servir el client de transport oficial, però això és només una qüestió de refactorització immediata. En aquest cas, s'utilitza el seu propi client, construït sobre la base de Spring WebClient, per al processament.

Optimització de càrrega en un projecte Highload amb ElasticSearch

Gran promoció

Un cop a l'any, el projecte acull una gran promoció per als usuaris: això és el mateix Highload, ja que en aquest moment treballem amb desenes de milions d'usuaris simultàniament.

Normalment, les càrregues punta es produeixen durant les vacances, però aquesta promoció és a un nivell completament diferent. L'any passat, el dia de la promoció, vam vendre 27 unitats de béns. Les dades van trigar més de mitja hora a processar-se, fet que va causar molèsties als usuaris. Els usuaris van rebre premis per la seva participació, però va quedar clar que calia accelerar el procés.

A principis del 2019, vam decidir que calia ElasticSearch. Durant tot un any hem organitzat el processament de les dades rebudes a Elastic i la seva sortida a l'API de l'aplicació mòbil i el lloc web. Com a resultat, l'any següent durant la promoció vam tramitar 15 entrades en 131 minuts.

Com que tenim molta gent que vol comprar el producte i participar en el sorteig de les nostres promocions, aquesta és una mesura temporal. Ara enviem la informació actual a Elastic, però en el futur tenim previst transferir la informació arxivada dels últims mesos a Postgres com a emmagatzematge permanent. Per no obstruir l'índex elàstic, que també té les seves limitacions.

Conclusió/Conclusions

De moment, hem transferit tots els serveis que volíem a Elastic i de moment hem aturat. Ara estem construint un índex a Elastic a sobre de l'emmagatzematge persistent principal de Postgres, que assumeix la càrrega de l'usuari.

En el futur, tenim previst transferir serveis si entenem que la sol·licitud de dades s'està tornant massa diversa i s'està buscant un nombre il·limitat de columnes. Això ja no és una tasca per a Postgres.

Si necessitem una cerca de text complet a la funcionalitat o si tenim molts criteris de cerca diferents, ja sabem que això s'ha de traduir a Elastic.

⌘⌘⌘

Gràcies per llegir. Si la vostra empresa també utilitza ElasticSearch i té els vostres propis casos d'implementació, feu-nos-ho saber. Serà interessant saber com ho fan els altres :)

Font: www.habr.com

Afegeix comentari