Laadoptimalisatie op een Highload-project met ElasticSearch

Hé Habr! Mijn naam is Maxim Vasiliev, ik werk als analist en projectmanager bij FINCH. Vandaag wil ik u vertellen hoe we met behulp van ElasticSearch 15 miljoen verzoeken in 6 minuten konden verwerken en de dagelijkse belasting op de site van een van onze klanten konden optimaliseren. Helaas zullen we het zonder namen moeten doen, aangezien we een geheimhoudingsverklaring hebben, hopen we dat de inhoud van het artikel hier niet onder zal lijden. Laten we gaan.

Hoe het project werkt

Op onze backend creëren we services die zorgen voor de prestaties van de websites en mobiele applicaties van onze klanten. De algemene structuur is te zien in het diagram:

Laadoptimalisatie op een Highload-project met ElasticSearch

Tijdens het werk verwerken we een groot aantal transacties: aankopen, betalingen, bewerkingen met gebruikerssaldi, waarvoor we veel logboeken opslaan, en we importeren en exporteren deze gegevens naar externe systemen.

Er zijn ook omgekeerde processen wanneer we gegevens van de klant ontvangen en overdragen aan de gebruiker. Daarnaast zijn er nog processen voor het werken met betalingen en bonusprogramma's.

Korte achtergrond

Aanvankelijk gebruikten we PostgreSQL als enige gegevensopslag. De standaardvoordelen voor een DBMS: de aanwezigheid van transacties, een ontwikkelde taal voor gegevensbemonstering, een breed scala aan tools voor integratie; gecombineerd met goede prestaties voldeed het lange tijd aan onze behoeften.

We hebben werkelijk alle data in Postgres opgeslagen: van transacties tot nieuws. Maar het aantal gebruikers groeide, en daarmee ook het aantal verzoeken.

Voor alle duidelijkheid, het jaarlijkse aantal sessies in 2017 alleen op de desktopsite is 131 miljoen. In 2018 - 125 miljoen. 2019 weer 130 miljoen. Voeg nog eens 100-200 miljoen toe van de mobiele versie van de site en de mobiele applicatie, en je zal een groot aantal aanvragen krijgen.

Met de groei van het project stopte Postgres met het omgaan met de belasting, we hadden geen tijd - er verscheen een groot aantal verschillende zoekopdrachten waarvoor we niet voldoende indexen konden maken.

We begrepen dat er behoefte was aan andere datastores die in onze behoeften zouden voorzien en PostgreSQL zouden ontlasten. Elasticsearch en MongoDB werden als mogelijke opties beschouwd. Laatstgenoemde verloor op de volgende punten:

  1. Lage indexeringssnelheid naarmate de hoeveelheid gegevens in indexen toeneemt. Bij Elastic hangt de snelheid niet af van de hoeveelheid data.
  2. Geen full-text zoeken

Dus kozen we Elastic voor onszelf en bereidden we ons voor op de overgang.

Overgang naar elastisch

1. We zijn begonnen met de overgang van de zoekservice voor verkooppunten. Onze klant heeft in totaal ongeveer 70 verkooppunten en dit vereist verschillende soorten zoekopdrachten op de site en in de applicatie:

  • Tekst zoeken op plaatsnaam
  • Geosearch binnen een bepaalde straal vanaf een bepaald punt. Bijvoorbeeld als de gebruiker wil zien welke verkooppunten het dichtst bij zijn huis zijn.
  • Zoeken op een bepaald vierkant - de gebruiker tekent een vierkant op de kaart en alle punten in deze straal worden aan hem getoond.
  • Zoek op extra filters. Verkooppunten verschillen van elkaar in assortiment

Als we het over de organisatie hebben, dan hebben we in Postgres een gegevensbron voor zowel de kaart als het nieuws, en in Elastic worden snapshots uit de originele gegevens gehaald. Feit is dat Postgres aanvankelijk niet op alle criteria kon zoeken. Er waren niet alleen veel indexen, ze konden elkaar ook overlappen, waardoor de Postgres-planner verloren ging en niet begreep welke index hij moest gebruiken.

2. De volgende in de rij was de nieuwssectie. Elke dag verschijnen er publicaties op de site, zodat de gebruiker niet verdwaalt in de informatiestroom, de gegevens moeten worden gesorteerd voordat ze worden uitgegeven. Dit is waar zoeken voor is: u kunt de site doorzoeken op tekstovereenkomst en tegelijkertijd extra filters koppelen, aangezien deze ook via Elastic worden gemaakt.

3. Daarna hebben we de transactieverwerking verplaatst. Gebruikers kunnen op de site een bepaald product kopen en deelnemen aan een prijstrekking. Na dergelijke aankopen verwerken we een grote hoeveelheid gegevens, vooral in het weekend en op feestdagen. Ter vergelijking: als op gewone dagen het aantal aankopen ergens tussen de 1,5 en 2 miljoen ligt, dan kan dat op feestdagen oplopen tot 53 miljoen.

Tegelijkertijd moeten de gegevens in de kortst mogelijke tijd worden verwerkt - gebruikers houden er niet van om meerdere dagen op het resultaat te wachten. Er is geen manier om dergelijke deadlines te halen via Postgres - we kregen vaak sloten en terwijl we alle verzoeken aan het verwerken waren, konden gebruikers niet controleren of ze prijzen hadden ontvangen of niet. Dit is niet erg prettig voor het bedrijfsleven, dus hebben we de verwerking verplaatst naar Elasticsearch.

periodiciteit

Updates worden nu gebeurtenisgebaseerd geconfigureerd volgens de volgende voorwaarden:

  1. Verkoop punten. Zodra we data van een externe bron ontvangen, starten we direct met de update.
  2. Nieuws. Zodra er nieuws op de site wordt bewerkt, wordt het automatisch naar Elastic verzonden.

Ook hier is het vermelden waard de voordelen van Elastic. In Postgres moet u bij het verzenden van een verzoek wachten tot alle records eerlijk zijn verwerkt. U kunt 10 records naar Elastic sturen en direct aan het werk gaan, zonder te wachten tot de records over alle Shards zijn verdeeld. Het is natuurlijk mogelijk dat sommige Shard of Replica de gegevens niet meteen zien, maar alles zal zeer binnenkort beschikbaar zijn.

integratie methodes

Er zijn 2 manieren om te integreren met Elastic:

  1. Via een native client via TCP. De native driver sterft geleidelijk uit: hij wordt niet langer ondersteund, hij heeft een erg onhandige syntaxis. Daarom gebruiken we het praktisch niet en proberen we het volledig te verlaten.
  2. Via een HTTP-interface die zowel JSON-verzoeken als Lucene-syntaxis kan gebruiken. De laatste is een tekstengine die Elastic gebruikt. In deze versie krijgen we de mogelijkheid om via JSON-verzoeken via HTTP te batchen. Dit is de optie die we proberen te gebruiken.

Dankzij de HTTP-interface kunnen we bibliotheken gebruiken die een asynchrone implementatie van de HTTP-client bieden. We kunnen profiteren van Batch en de asynchrone API, wat resulteert in hoge prestaties, wat veel heeft geholpen in de dagen van de grote promotie (meer daarover hieronder)

Enkele cijfers ter vergelijking:

  • Postgres bounty-gebruikers opslaan in 20 threads zonder groepering: 460713 records in 42 seconden
  • Elastic + reactieve client voor 10 threads + batch voor 1000 elementen: 596749 records in 11 seconden
  • Elastic + reactieve client voor 10 threads + batch voor 1000 elementen: 23801684 inzendingen in 4 minuten

Nu hebben we een HTTP-verzoekmanager geschreven die JSON bouwt als Batch / niet Batch en deze via elke HTTP-client verzendt, ongeacht de bibliotheek. U kunt er ook voor kiezen om verzoeken synchroon of asynchroon te verzenden.

In sommige integraties gebruiken we nog steeds de officiële transportclient, maar dit is slechts een kwestie van de volgende refactoring. In dit geval wordt voor de verwerking een op basis van Spring WebClient gebouwde klant op maat gebruikt.

Laadoptimalisatie op een Highload-project met ElasticSearch

grote promotie

Een keer per jaar organiseert het project een grote promotie voor gebruikers - dit is dezelfde Highload, aangezien we op dit moment met tientallen miljoenen gebruikers tegelijkertijd werken.

Meestal zijn er pieken in de belasting tijdens de feestdagen, maar deze promotie is van een heel ander niveau. Vorig jaar, op de dag van de promotie, hebben we 27 goederen verkocht. De gegevens werden meer dan een half uur verwerkt, wat voor gebruikers ongemak veroorzaakte. Gebruikers ontvingen prijzen voor deelname, maar het werd duidelijk dat het proces versneld moest worden.

Begin 2019 besloten we dat we ElasticSearch nodig hadden. Een jaar lang organiseerden we de verwerking van de ontvangen data in Elastic en de uitgifte ervan in de api van de mobiele applicatie en website. Als gevolg hiervan hebben we het volgende jaar tijdens de campagne verwerkt 15 inzendingen in 131 minuten.

Aangezien we veel mensen hebben die goederen willen kopen en willen deelnemen aan de trekking van prijzen in promoties, is dit een tijdelijke maatregel. Nu sturen we up-to-date informatie naar Elastic, maar in de toekomst zijn we van plan om gearchiveerde informatie van de afgelopen maanden over te zetten naar Postgres als permanente opslag. Om de elastische index niet te verstoppen, die ook zijn beperkingen heeft.

Conclusie/Conclusies

Op dit moment hebben we alle services die we wilden naar Elastic overgedragen en hebben we hier voorlopig op gepauzeerd. Nu bouwen we een index in Elastic bovenop de permanente hoofdopslag in Postgres, die de gebruikersbelasting overneemt.

In de toekomst zijn we van plan om services over te dragen als we begrijpen dat het gegevensverzoek te divers wordt en wordt gezocht naar een onbeperkt aantal kolommen. Dit is niet langer een taak voor Postgres.

Als we full-text zoeken in functionaliteit nodig hebben of als we veel verschillende zoekcriteria hebben, dan weten we al dat dit vertaald moet worden naar Elastic.

Bedankt voor het lezen. Als uw bedrijf ook ElasticSearch gebruikt en eigen implementatiecases heeft, laat het ons weten. Het zal interessant zijn om te weten hoe anderen zijn 🙂

Bron: www.habr.com

Voeg een reactie