Optimizacija opterećenja na Highload projektu s ElasticSearch

Hej Habr! Moje ime je Maxim Vasiliev, radim kao analitičar i voditelj projekta u FINCH-u. Danas bih vam želio reći kako smo pomoću ElasticSearcha uspjeli obraditi 15 milijuna zahtjeva u 6 minuta i optimizirati dnevna opterećenja na stranici jednog od naših klijenata. Nažalost, morat ćemo bez imena, budući da imamo NDA, nadamo se da sadržaj članka neće patiti od toga. Idemo.

Kako projekt funkcionira

Na našem backendu stvaramo usluge koje osiguravaju rad web stranica i mobilne aplikacije naših klijenata. Opća struktura može se vidjeti na dijagramu:

Optimizacija opterećenja na Highload projektu s ElasticSearch

U procesu rada obrađujemo veliki broj transakcija: kupnje, plaćanja, operacije sa stanjima korisnika, za koje pohranjujemo veliki broj logova, kao i uvoz i izvoz tih podataka u vanjske sustave.

Postoje i obrnuti procesi kada primamo podatke od klijenta i prenosimo ih korisniku. Osim toga, još uvijek postoje procesi za rad s plaćanjima i bonus programima.

Kratka pozadina

U početku smo koristili PostgreSQL kao jedino skladište podataka. Njegove standardne prednosti za DBMS: prisutnost transakcija, razvijen jezik za uzorkovanje podataka, širok raspon alata za integraciju; u kombinaciji s dobrim performansama zadovoljio je naše potrebe dosta dugo.

U Postgres smo pohranili apsolutno sve podatke: od transakcija do vijesti. No, broj korisnika je rastao, a s njim i broj zahtjeva.

Za razumijevanje, godišnji broj sesija u 2017. samo na desktop stranici je 131 milijun. U 2018. - 125 milijuna. 2019. opet 130 milijuna. Dodajte još 100-200 milijuna s mobilne verzije stranice i mobilne aplikacije, i vi dobit će ogroman broj zahtjeva.

S rastom projekta, Postgres se prestao nositi s opterećenjem, nismo imali vremena - pojavio se velik broj raznih upita za koje nismo mogli stvoriti dovoljan broj indeksa.

Shvatili smo da postoji potreba za drugim spremištima podataka koja bi zadovoljila naše potrebe i oslobodila PostgreSQL. Kao moguće opcije razmatrani su Elasticsearch i MongoDB. Potonji je izgubio na sljedećim bodovima:

  1. Spora brzina indeksiranja kako raste količina podataka u indeksima. Uz Elastic, brzina ne ovisi o količini podataka.
  2. Nema pretraživanja cijelog teksta

Stoga smo odabrali Elastic za sebe i pripremili se za prijelaz.

Prijelaz na Elastic

1. Započeli smo prijelaz s usluge pretraživanja prodajnih mjesta. Naš klijent ima ukupno oko 70 prodajnih mjesta, a za to je potrebno nekoliko vrsta pretraživanja na stranici i aplikaciji:

  • Pretraga teksta po nazivu grada
  • Geografsko pretraživanje unutar zadanog radijusa od neke točke. Primjerice, ako korisnik želi vidjeti koja su mu prodajna mjesta najbliža domu.
  • Pretraživanje po zadanom kvadratu - korisnik crta kvadrat na karti i prikazuju mu se sve točke u tom radijusu.
  • Pretraživanje po dodatnim filterima. Prodajna mjesta se međusobno razlikuju po asortimanu

Ako govorimo o organizaciji, onda u Postgresu imamo izvor podataka i za mapu i za vijesti, a u Elastic Snapshotovi se uzimaju iz izvornih podataka. Činjenica je da se u početku Postgres nije mogao nositi s pretraživanjem po svim kriterijima. Ne samo da je bilo mnogo indeksa, mogli su se i preklapati, pa se Postgres planer izgubio i nije razumio koji indeks treba koristiti.

2. Sljedeća na redu bila je rubrika vijesti. Publikacije se pojavljuju na stranici svaki dan kako se korisnik ne bi izgubio u protoku informacija, podatke je potrebno sortirati prije izdavanja. Tome služi pretraga: stranicu možete pretraživati ​​po tekstualnom podudaranju, a pritom spojiti dodatne filtere, budući da su i oni napravljeni kroz Elastic.

3. Zatim smo premjestili obradu transakcije. Korisnici mogu kupiti određeni proizvod na stranici i sudjelovati u nagradnoj igri. Nakon takvih kupnji obrađujemo veliku količinu podataka, posebno vikendima i praznicima. Za usporedbu, ako je običnim danima broj kupnji negdje između 1,5-2 milijuna, onda blagdanima ta brojka može doseći 53 milijuna.

Istodobno, podaci se moraju obraditi u najkraćem mogućem vremenu - korisnici ne vole čekati rezultat nekoliko dana. Preko Postgresa nema načina da postignemo takve rokove - često smo dobivali zaključavanja, a dok smo obrađivali sve zahtjeve korisnici nisu mogli provjeriti jesu li dobili nagrade ili ne. Ovo nije baš ugodno za posao, pa smo obradu preselili na Elasticsearch.

periodičnost

Sada se ažuriranja konfiguriraju na temelju događaja, prema sljedećim uvjetima:

  1. Prodajna mjesta. Čim dobijemo podatke iz vanjskog izvora, odmah pokrećemo ažuriranje.
  2. Vijesti. Čim se neka vijest uredi na stranici, ona se automatski šalje Elasticu.

Ovdje opet vrijedi spomenuti prednosti Elastic-a. U Postgresu, kada šaljete zahtjev, morate čekati da pošteno obradi sve zapise. Možete poslati 10 zapisa na Elastic i početi raditi odmah, bez čekanja da se zapisi distribuiraju po svim Shardovima. Naravno, neki Shard ili Replica možda neće odmah vidjeti podatke, ali sve će biti dostupno vrlo brzo.

Metode integracije

Postoje 2 načina za integraciju s Elasticom:

  1. Preko izvornog klijenta preko TCP-a. Izvorni upravljački program postupno izumire: više nije podržan, ima vrlo nezgodnu sintaksu. Stoga ga praktički ne koristimo i pokušavamo ga potpuno napustiti.
  2. Putem HTTP sučelja koje može koristiti i JSON zahtjeve i Lucene sintaksu. Posljednji je tekstualni mehanizam koji koristi Elastic. U ovoj verziji dobivamo mogućnost grupnog slanja JSON zahtjeva preko HTTP-a. Ovo je opcija koju pokušavamo koristiti.

Zahvaljujući HTTP sučelju, možemo koristiti biblioteke koje pružaju asinkronu implementaciju HTTP klijenta. Možemo iskoristiti Batch i asinkroni API, što rezultira visokim performansama, što je puno pomoglo u danima velike promocije (više o tome u nastavku)

Neke brojke za usporedbu:

  • Spremanje Postgres bounty korisnika u 20 niti bez grupiranja: 460713 zapisa u 42 sekunde
  • Elastični + reaktivni klijent za 10 niti + serija za 1000 elemenata: 596749 zapisa u 11 sekundi
  • Elastični + reaktivni klijent za 10 niti + serija za 1000 elemenata: 23801684 unosa u 4 minute

Sada smo napisali upravitelj HTTP zahtjeva koji gradi JSON kao Batch/ne Batch i šalje ga putem bilo kojeg HTTP klijenta, bez obzira na biblioteku. Također možete odabrati slanje zahtjeva sinkrono ili asinkrono.

U nekim integracijama još uvijek koristimo službenog transportnog klijenta, ali to je samo stvar sljedećeg refaktoriranja. U ovom slučaju za obradu se koristi prilagođeni klijent izgrađen na temelju Spring WebClient-a.

Optimizacija opterećenja na Highload projektu s ElasticSearch

velika promocija

Jednom godišnje projekt ugošćuje veliku promociju za korisnike - to je isti Highload, jer u ovom trenutku radimo s desecima milijuna korisnika u isto vrijeme.

Obično su vrhunci opterećenja za vrijeme praznika, ali ova promocija je na sasvim drugoj razini. Pretprošle godine, na dan promocije, prodali smo 27 jedinica robe. Podaci su se obrađivali više od pola sata, što je izazvalo neugodnosti za korisnike. Korisnici su dobili nagrade za sudjelovanje, no postalo je jasno da se proces mora ubrzati.

Početkom 2019. odlučili smo da nam treba ElasticSearch. Cijelu godinu smo organizirali obradu zaprimljenih podataka u Elastic-u i njihovo izdavanje u api mobilne aplikacije i web stranice. Kao rezultat toga, sljedeće godine tijekom kampanje, obradili smo 15 unosa u 131 minuta.

Budući da imamo dosta ljudi koji žele kupiti robu i sudjelovati u izvlačenju nagrada na promocijama, ovo je privremena mjera. Sada Elastic-u šaljemo ažurne podatke, ali u budućnosti planiramo arhivirane podatke za protekle mjesece prenijeti u Postgres kao trajnu pohranu. Kako ne bi začepili elastični indeks, koji također ima svoja ograničenja.

Zaključak/Zaključci

Trenutno smo sve usluge koje smo željeli prebacili na Elastic i za sada smo na tome stali. Sada gradimo indeks u Elastic-u na vrhu glavne trajne pohrane u Postgresu, koji preuzima opterećenje korisnika.

U budućnosti planiramo prenijeti usluge ako shvatimo da zahtjev za podacima postaje previše raznolik i pretražuje se u neograničenom broju stupaca. Ovo više nije zadatak za Postgres.

Ako nam je potrebno pretraživanje cijelog teksta u funkcionalnosti ili ako imamo puno različitih kriterija pretraživanja, tada već znamo da to treba prevesti u Elastic.

⌘⌘⌘

Hvala na čitanju. Ako vaša tvrtka također koristi ElasticSearch i ima vlastite slučajeve implementacije, recite nam. Bit će zanimljivo saznati kako su drugi 🙂

Izvor: www.habr.com

Dodajte komentar