Optimizacija učitavanja na Highload projektu sa ElasticSearch

Hej Habr! Moje ime je Maxim Vasiliev, radim kao analitičar i menadžer projekta u FINCH-u. Danas bih vam želio reći kako smo pomoću ElasticSearch-a uspjeli obraditi 15 miliona zahtjeva za 6 minuta i optimizirati dnevno opterećenje stranice jednog od naših klijenata. Nažalost, morat ćemo bez imena, pošto imamo NDA, nadamo se da sadržaj članka neće patiti od toga. Idemo.

Kako projekat funkcioniše

Na našem backendu kreiramo usluge koje osiguravaju performanse web stranica i mobilnih aplikacija naših klijenata. Opća struktura se može vidjeti na dijagramu:

Optimizacija učitavanja na Highload projektu sa ElasticSearch

U procesu rada obrađujemo veliki broj transakcija: kupovine, plaćanja, operacije sa korisničkim bilansima, za koje pohranjujemo veliki broj logova, kao i uvoz i izvoz ovih podataka u eksterne sisteme.

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

Kratka pozadina

U početku smo koristili PostgreSQL kao jedino skladište podataka. Njegove standardne prednosti za DBMS: prisustvo transakcija, razvijen jezik uzorkovanja podataka, širok spektar alata za integraciju; u kombinaciji sa dobrim performansama zadovoljavali su naše potrebe dosta dugo vremena.

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

Za razumijevanje, godišnji broj sesija u 2017. samo na desktop sajtu je 131 milion. U 2018. - 125 miliona. 2019. opet 130 miliona. Dodajte još 100-200 miliona sa mobilne verzije sajta i mobilne aplikacije, i vi dobiće ogroman broj zahtjeva.

S rastom projekta, Postgres je prestao da se nosi s opterećenjem, nismo imali vremena - pojavio se veliki broj raznih upita za koje nismo mogli kreirati dovoljan broj indeksa.

Shvatili smo da postoji potreba za drugim skladištima podataka koji bi zadovoljili naše potrebe i skinuli opterećenje sa PostgreSQL-a. Elasticsearch i MongoDB su razmatrani kao moguće opcije. Potonji su izgubili na sljedećim poenima:

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

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

Prelazak na elastičnu

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

  • Pretraživanje teksta po nazivu grada
  • Geoistraživanje unutar određenog radijusa iz neke tačke. Na primjer, ako korisnik želi vidjeti koja su prodajna mjesta najbliža njegovom domu.
  • Pretraživanje po datom kvadratu - korisnik nacrta kvadrat na mapi i sve tačke u ovom radijusu mu se prikazuju.
  • Pretražujte 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 Snapshots su uzeti iz originalnih podataka. Činjenica je da se u početku Postgres nije mogao nositi s pretragom po svim kriterijima. Ne samo da je bilo mnogo indeksa, već su se mogli i preklapati, tako da se Postgres planer izgubio i nije razumio koji indeks da koristi.

2. Sljedeća na redu bila je rubrika vijesti. Publikacije se pojavljuju na stranici svaki dan kako se korisnik ne bi izgubio u toku informacija, podaci se moraju sortirati prije izdavanja. To je ono čemu služi pretraga: možete pretraživati ​​stranicu po tekstualnom podudaranju, a istovremeno povezati dodatne filtere, jer se i oni prave preko Elastic-a.

3. Zatim smo premjestili obradu transakcije. Korisnici mogu kupiti određeni proizvod na sajtu i učestvovati u nagradnoj igri. Nakon ovakvih kupovina obrađujemo veliku količinu podataka, posebno vikendom i praznicima. Poređenja radi, ako je običnim danima broj kupovina negde između 1,5-2 miliona, onda na praznike brojka može dostići 53 miliona.

Istovremeno, podaci se moraju obraditi u najkraćem mogućem roku - korisnici ne vole da čekaju rezultat nekoliko dana. Ne postoji način da se takvi rokovi postignu putem Postgresa - često smo dobijali zaključavanja, a dok smo obrađivali sve zahtjeve, korisnici nisu mogli provjeriti da li su dobili nagrade ili ne. Ovo nije baš ugodno za posao, pa smo obradu prebacili na Elasticsearch.

Periodičnost

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

  1. Prodajna mesta. Čim dobijemo podatke iz vanjskog izvora, odmah započinjemo ažuriranje.
  2. Vijesti. Čim se bilo koja vijest uredi na stranici, ona se automatski šalje na Elastic.

Ovdje još jednom 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 odmah početi s radom, bez čekanja da se zapisi distribuiraju po svim Shardovima. Naravno, neki Shard ili Replica možda neće odmah vidjeti podatke, ali će sve biti dostupno vrlo brzo.

Metode integracije

Postoje 2 načina za integraciju sa Elastic-om:

  1. Preko matičnog klijenta preko TCP-a. Izvorni drajver postepeno izumire: više nije podržan, ima vrlo nezgodnu sintaksu. Stoga ga praktički ne koristimo i pokušavamo ga potpuno napustiti.
  2. Kroz HTTP sučelje koje može koristiti i JSON zahtjeve i Lucene sintaksu. Posljednji je tekst engine koji koristi Elastic. U ovoj verziji dobijamo mogućnost skupnog 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 asinhroni API, što rezultira visokim performansama, što je puno pomoglo u danima velike promocije (više o tome u nastavku)

Nekoliko brojeva za poređenje:

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

Sada smo napisali upravitelj HTTP zahtjeva koji gradi JSON kao Batch / ne Batch i šalje ga kroz bilo koji HTTP klijent, bez obzira na biblioteku. Također možete odabrati da zahtjeve šaljete sinhrono ili asinhrono.

U nekim integracijama i dalje koristimo službeni transportni klijent, ali ovo je samo pitanje sljedećeg refaktora. U ovom slučaju za obradu se koristi prilagođeni klijent izgrađen na bazi Spring WebClient-a.

Optimizacija učitavanja na Highload projektu sa ElasticSearch

velika promocija

Jednom godišnje, projekat je domaćin velike promocije za korisnike - ovo je isti Highload, jer u ovom trenutku radimo sa desetinama miliona korisnika istovremeno.

Obično se vrhunci opterećenja dešavaju tokom praznika, ali ova promocija je na sasvim drugom nivou. Pretprošle godine, na dan promocije, prodali smo 27 jedinica robe. Podaci su obrađeni više od pola sata, što je izazvalo neugodnosti za korisnike. Korisnici su dobili nagrade za učešće, ali je postalo jasno da proces treba ubrzati.

Početkom 2019. odlučili smo da nam je potreban ElasticSearch. Cijelu godinu smo organizirali obradu primljenih podataka u Elastic-u i njihovo izdavanje u API-ju mobilne aplikacije i web stranice. Kao rezultat toga, sljedeće godine tokom kampanje, mi smo obradili 15 unosa za 131 minuta.

S obzirom da imamo dosta ljudi koji žele da kupe robu i učestvuju u izvlačenju nagrada u promocijama, ovo je privremena mjera. Sada šaljemo najnovije informacije u Elastic, ali u budućnosti planiramo da arhivirane informacije za protekle mjesece prenesemo u Postgres kao trajno skladište. 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 prenijeli na Elastic i za sada smo pauzirali na tome. Sada gradimo indeks u Elastic-u na vrhu glavne trajne memorije u Postgresu, koji preuzima opterećenje korisnika.

U budućnosti planiramo prijenos usluga ako shvatimo da zahtjev za podacima postaje previše raznolik i da se traži u neograničenom broju kolona. Ovo više nije zadatak za Postgres.

Ako nam je potrebno pretraživanje po cijelom tekstu u funkcionalnosti ili ako imamo mnogo različitih kriterija pretraživanja, onda već znamo da to treba prevesti u Elastic.

⌘⌘⌘

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

izvor: www.habr.com

Dodajte komentar