Belastningsoptimering på et Highload-projekt med ElasticSearch

Hej Habr! Mit navn er Maxim Vasiliev, jeg arbejder som analytiker og projektleder hos FINCH. I dag vil jeg gerne fortælle dig, hvordan vi ved hjælp af ElasticSearch var i stand til at behandle 15 millioner anmodninger på 6 minutter og optimere den daglige belastning på en af ​​vores kunders websted. Vi bliver desværre nødt til at undvære navne, da vi har en NDA, håber vi at artiklens indhold ikke lider under dette. Lad os gå.

Hvordan projektet fungerer

På vores backend skaber vi tjenester, der sikrer ydeevnen af ​​vores klients hjemmesider og mobilapplikation. Den generelle struktur kan ses i diagrammet:

Belastningsoptimering på et Highload-projekt med ElasticSearch

Under arbejdet behandler vi et stort antal transaktioner: køb, betalinger, operationer med brugersaldi, som vi gemmer en masse logfiler for, samt importerer og eksporterer disse data til eksterne systemer.

Der er også omvendte processer, når vi modtager data fra klienten og overfører dem til brugeren. Derudover er der stadig processer for at arbejde med betalinger og bonusprogrammer.

Kort baggrund

I starten brugte vi PostgreSQL som det eneste datalager. Dets standardfordele for et DBMS: tilstedeværelsen af ​​transaktioner, et udviklet datasamplingsprog, en bred vifte af værktøjer til integration; kombineret med god ydeevne tilfredsstillede vores behov i ret lang tid.

Vi gemte absolut alle data i Postgres: fra transaktioner til nyheder. Men antallet af brugere voksede, og med det antallet af forespørgsler.

For forståelse er det årlige antal sessioner i 2017 kun på desktop-webstedet 131 millioner. I 2018 - 125 millioner. 2019 igen 130 millioner Tilføj yderligere 100-200 millioner fra mobilversionen af ​​siden og mobilapplikationen, og du vil få et stort antal anmodninger.

Med væksten i projektet holdt Postgres op med at klare belastningen, vi havde ikke tid - et stort antal forskellige forespørgsler dukkede op, som vi ikke kunne oprette et tilstrækkeligt antal indekser til.

Vi forstod, at der var et behov for andre datalagre, der ville levere vores behov og tage belastningen af ​​PostgreSQL. Elasticsearch og MongoDB blev betragtet som mulige muligheder. Sidstnævnte tabte på følgende punkter:

  1. Langsom indekseringshastighed, efterhånden som mængden af ​​data i indekser vokser. Med Elastic afhænger hastigheden ikke af mængden af ​​data.
  2. Ingen fuldtekstsøgning

Så vi valgte Elastic for os selv og forberedte os på overgangen.

Overgang til elastik

1. Vi startede overgangen fra søgetjenesten for salgssteder. Vores kunde har i alt omkring 70 salgssteder, og det kræver flere typer søgninger på siden og i applikationen:

  • Tekstsøgning efter bynavn
  • Geosearch inden for en given radius fra et tidspunkt. For eksempel hvis brugeren ønsker at se, hvilke salgssteder der er tættest på hans bolig.
  • Søg efter en given firkant - brugeren tegner en firkant på kortet, og alle punkter i denne radius vises til ham.
  • Søg med yderligere filtre. Salgssteder adskiller sig fra hinanden i sortiment

Taler vi om organisationen, så har vi i Postgres en datakilde til både kortet og nyhederne, og i Elastic Snapshots er taget fra de originale data. Faktum er, at Postgres oprindeligt ikke kunne klare søgningen efter alle kriterier. Ikke alene var der mange indekser, de kunne også overlappe hinanden, så Postgres-planlæggeren gik tabt og forstod ikke hvilket indeks, der skulle bruges.

2. Næste i rækken var nyhedssektionen. Publikationer vises på siden hver dag, så brugeren ikke farer vild i informationsstrømmen, dataene skal sorteres inden udsendelse. Det er det, der søges efter: Du kan søge på siden efter tekstmatch, og samtidig tilslutte yderligere filtre, da de også er lavet gennem Elastic.

3. Så flyttede vi transaktionsbehandlingen. Brugere kan købe et bestemt produkt på siden og deltage i en præmielodtrækning. Efter sådanne køb behandler vi en stor mængde data, især i weekender og helligdage. Til sammenligning, hvis antallet af køb på almindelige dage er et sted mellem 1,5-2 millioner, så kan tallet på helligdage nå 53 millioner.

Samtidig skal dataene behandles på kortest mulig tid - brugere kan ikke lide at vente på resultatet i flere dage. Der er ingen måde at opnå sådanne deadlines gennem Postgres - vi modtog ofte låse, og mens vi behandlede alle anmodninger, kunne brugerne ikke kontrollere, om de modtog præmier eller ej. Dette er ikke særlig behageligt for erhvervslivet, så vi flyttede behandlingen til Elasticsearch.

periodicitet

Nu er opdateringer konfigureret hændelsesbaseret i henhold til følgende betingelser:

  1. Salgspunkter. Så snart vi modtager data fra en ekstern kilde, starter vi straks opdateringen.
  2. Nyheder. Så snart en nyhed er redigeret på siden, sendes den automatisk til Elastic.

Her er det igen værd at nævne fordelene ved Elastic. I Postgres, når du sender en anmodning, skal du vente, indtil den ærligt behandler alle posterne. Du kan sende 10 poster til Elastic og begynde at arbejde med det samme uden at vente på, at posterne bliver fordelt på alle Shards. Selvfølgelig kan nogle Shard eller Replica ikke se dataene med det samme, men alt vil være tilgængeligt meget snart.

Integrationsmetoder

Der er 2 måder at integrere med Elastic:

  1. Gennem en indbygget klient over TCP. Den oprindelige driver er gradvist ved at dø ud: den understøttes ikke længere, den har en meget ubekvem syntaks. Derfor bruger vi det praktisk talt ikke og forsøger helt at opgive det.
  2. Gennem en HTTP-grænseflade, der kan bruge både JSON-anmodninger og Lucene-syntaks. Den sidste er en tekstmotor, der bruger Elastic. I denne version får vi mulighed for at batch gennem JSON-anmodninger over HTTP. Dette er den mulighed, vi prøver at bruge.

Takket være HTTP-grænsefladen kan vi bruge biblioteker, der giver en asynkron implementering af HTTP-klienten. Vi kan drage fordel af Batch og den asynkrone API, som resulterer i høj ydeevne, hvilket hjalp meget i dagene med den store kampagne (mere om det nedenfor)

Nogle tal til sammenligning:

  • Lagring af Postgres bounty-brugere i 20 tråde uden gruppering: 460713 poster på 42 sekunder
  • Elastik + reaktiv klient til 10 tråde + batch til 1000 elementer: 596749 poster på 11 sekunder
  • Elastik + reaktiv klient til 10 tråde + batch til 1000 elementer: 23801684 poster på 4 minutter

Nu har vi skrevet en HTTP request manager, der bygger JSON som Batch/not Batch og sender den via enhver HTTP-klient, uanset biblioteket. Du kan også vælge at sende anmodninger synkront eller asynkront.

I nogle integrationer bruger vi stadig den officielle transportklient, men dette er kun et spørgsmål om den næste refaktorering. I dette tilfælde bruges en brugerdefineret klient bygget på basis af Spring WebClient til behandling.

Belastningsoptimering på et Highload-projekt med ElasticSearch

stor forfremmelse

En gang om året er projektet vært for en stor kampagne for brugerne - det er den samme Highload, da vi på dette tidspunkt arbejder med titusinder af brugere på samme tid.

Normalt opstår belastningstoppe i løbet af ferien, men denne kampagne er på et helt andet niveau. Forinden sidste år, på kampagnedagen, solgte vi 27 varer. Dataene blev behandlet i mere end en halv time, hvilket medførte gener for brugerne. Brugerne modtog præmier for deltagelse, men det blev klart, at processen skulle fremskyndes.

I begyndelsen af ​​2019 besluttede vi, at vi havde brug for ElasticSearch. I et helt år organiserede vi behandlingen af ​​de modtagne data i Elastic og deres udstedelse i mobilapplikationens og hjemmesidens api. Som et resultat, det næste år under kampagnen, behandlede vi 15 poster på 131 minutter.

Da vi har rigtig mange, der gerne vil købe varer og deltage i trækningen af ​​præmier i kampagner, er dette en midlertidig foranstaltning. Nu sender vi opdaterede informationer til Elastic, men i fremtiden planlægger vi at overføre arkiverede oplysninger fra de seneste måneder til Postgres som et permanent lager. For ikke at tilstoppe det elastiske indeks, som også har sine begrænsninger.

Konklusion/Konklusioner

I øjeblikket har vi overført alle de tjenester, vi ønskede, til Elastic og har holdt pause med dette indtil videre. Nu bygger vi et indeks i Elastic oven på det primære persistente lager i Postgres, som overtager brugerbelastningen.

I fremtiden planlægger vi at overføre tjenester, hvis vi forstår, at dataanmodningen bliver for forskelligartet og søges efter et ubegrænset antal kolonner. Dette er ikke længere en opgave for Postgres.

Hvis vi har brug for fuldtekstsøgning i funktionalitet eller har vi en masse forskellige søgekriterier, så ved vi allerede, at dette skal oversættes til Elastic.

⌘⌘⌘

Tak fordi du læste med. Hvis din virksomhed også bruger ElasticSearch og har sine egne implementeringssager, så fortæl os det. Det bliver interessant at vide, hvordan andre har det 🙂

Kilde: www.habr.com

Tilføj en kommentar