Përshëndetje, Habr! Emri im është Maksim Vasilev, punoj si analist dhe menaxher projektesh në FINCH. Sot do të flas për how we were able to process 15 million requests in just 6 minutes and optimize daily loads on the website of one of our clients. Fatkeqësisht, do të duhet të kalojmë pa emra, sepse kemi një NDA, shpresojmë që përmbajtja e artikullit të mos ndikohet nga kjo. Le të fillojmë.
Si është organizuar projekti
Në backendin tonë ne krijojmë shërbime që sigurojnë funksionalitetin e faqeve të internetit dhe aplikacionit mobil të klientit tonë. Strukturën e përgjithshme mund ta shihni në diagram:

Gjatë punës, ne përpunojmë një sasi të madhe transaksionesh: blerjeve, pagesave, operacioneve me bilancet e përdoruesve, për të cilat ruajmë shumë skeda, si dhe importojmë dhe eksportojmë këto të dhëna në sisteme të jashtme.
Gjithashtu ndodhin procese të kundërta, kur ne marrim të dhëna nga klienti dhe i transferojmë ato tek përdoruesit. Përveç kësaj, ekzistojnë gjithashtu procese që lidhen me pagesat dhe programet e bonusit.
Një histori e shkurtër
Fillimi me një sistem të vetëm ruajtjeje të dhënash ishte PostgreSQL. Përfitimet e tij të zakonshme për DBMS: ekzistenca e transaksioneve, një gjuhë e zhvilluar për të zgjedhur të dhënat, një gamë e gjerë mjetesh për integrim; së bashku me një performancë të mirë, ata për një kohë të gjatë përmbushën nevojat tona.
Ne ruajtëm në Postgres të gjitha të dhënat: nga transaksionet te lajmet. Por numri i përdoruesve u rrit, siç u rrit edhe numri i kërkesave.
PĂ«r tĂ« kuptuar, numri vjetor i seancave nĂ« vitin 2017 vetĂ«m nĂ« sitin desktop â 131 milion. NĂ« vitin 2018 â 125 milion. NĂ« vitin 2019 pĂ«rsĂ«ri 130 milion. Shtoni atje edhe 100-200 milion nga versioni mobil i sitit dhe aplikacioni mobil dhe do tĂ« merrni njĂ« numĂ«r kolosal kĂ«rkesash.
Me rritjen e projektit, Postgres nuk mund tĂ« pĂ«rballonte ngarkesĂ«n, ne nuk po arrinim â pati njĂ« numĂ«r tĂ« madh kĂ«rkesash tĂ« ndryshme pĂ«r tĂ« cilat nuk arritĂ«m tĂ« krijonim njĂ« numĂ«r tĂ« mjaftueshĂ«m indekse.
E kuptuam se kishte një nevojë për depo të tjera të dhënash që do të përmbushnin nevojat tona dhe do të lehtësonin ngarkesën nga PostgreSQL. Si mundësi shqyrtuam Elasticsearch dhe MongoDB. E fundit humbte në disa pika:
- Shpejtësi e ngadaltë indeksoni me rritjen e volumit të të dhënave në indekset. Me Elastic, shpejtësia nuk varet nga volumi i të dhënave.
- Nuk ka kërkim me tekst të plotë
Kështu që ne zgjodhëm Elastic për veten tonë dhe u përgatitëm për kalim.
Kalimi në Elastic
1. Ne filluam kalimin nga shërbimi i kërkimit të pikave të shitjes. Klienti ynë ka gjithsej rreth 70,000 pika shitjeje dhe kërkohen disa lloje kërkimesh në sit dhe në aplikacion:
- Kërkimi tekstual sipas emrit të vendit
- Kërkimi gjeografik brenda një rrethi të caktuar nga një pikë. Për shembull, nëse përdoruesi dëshiron të shohë se cilat pika shitjeje janë më afër shtëpisë së tij.
- KĂ«rkimi nĂ« njĂ« katror tĂ« caktuar â pĂ«rdoruesi tĂ«rhiqet njĂ« katror mbi hartĂ« dhe ai shfaqet tĂ« gjitha pikat nĂ« kĂ«tĂ« rreth.
- Kërkimi sipas filtrave shtesë. Pikat e shitjes ndryshojnë nga njëra-tjetra sipas asortimentit.
Kur flasim pĂ«r organizimin, nĂ« Postgres kemi burimin e tĂ« dhĂ«nave si pĂ«r hartĂ«n, ashtu edhe pĂ«r lajmet, ndĂ«rsa nĂ« Elastic bĂ«hen SnapshotâĂ« nga tĂ« dhĂ«nat origjinale. ĂĂ«shtja Ă«shtĂ« se fillimisht Postgres nuk pĂ«rballonte me kĂ«rkimin sipas tĂ« gjithĂ« kritereve. Jo vetĂ«m qĂ« kishte shumĂ« indekse, ato mund tĂ« pĂ«rputheshin gjithashtu, prandaj planifikuesi i Postgres humbiste dhe nuk kuptonte se cili indeks duhet tĂ« pĂ«rdorte.
2. Tjetra në rend ishte seksioni i lajmeve. Në faqe, çdo ditë publikohen artikuj, për të siguruar që përdoruesi të mos humbasë në rrjedhën e informacionit, të dhënat duhet të renditen para se të jepen. Për këtë është e nevojshme kërkimi: në faqe mund të kërkoni sipas përputhjes tekstuale, dhe për më tepër të lidhni filtre shtesë, pasi ato gjithashtu janë bërë përmes Elastic.
3. Më pas ne transferuam përpunimin e transaksioneve. Përdoruesit mund të blejnë një produkt të caktuar në faqe dhe të marrë pjesë në një tërheqje shpërblimesh. Pas këtyre blerjeve, ne përpunojmë një sasi të madhe të dhënash, veçanërisht gjatë fundjavave dhe festave. Për krahasim, në ditët e zakonshme numri i blerjeve është diku rreth 1.5-2 milion, ndërsa gjatë festave numri mund të arrijë deri në 53 milion.
Në këtë rast, të dhënat duhet të përpunohen në një kohë minimale - përdoruesit nuk e duan të presin disa ditë për rezultate. Me Postgres, nuk arrin dot një afat të tillë - shpesh kemi përjetuar bllokime, dhe përsa kohë përpunonim të gjitha kërkesat, përdoruesit nuk mund të kontrollonin nëse kishin marrë çmime apo jo. Kjo nuk është shumë e këndshme për biznesin, prandaj ne e kemi transferuar përpunimin në Elasticsearch.
Periudha
Tani, përditësimet janë të konfiguruara me ngjarje, sipas kushteve të mëposhtme:
- Pikat e Shkëmbimit. Sa herë që marrim të dhëna nga një burim të jashtëm, ne menjëherë fillojmë përditësimin.
- Lajmet. Sa herë që në sit redaktohet një lajm, ai automatikisht dërgohet në Elastic.
Këtu vlen të përmendim përsëri përfitimet e Elastic. Në Postgres, gjatë dërgimit të kërkesës, duhet të presësh ndërsa ai përpunon të gjitha regjistrimet. Në Elastic, mund të dërgosh 10,000 regjistrime dhe menjëherë të fillosh punën, pa pritur që regjistrimet të shpërndahen në të gjitha Shard-ët. Sigurisht, ndonjë Shard ose Replica mund të mos shohin të dhënat menjëherë, por shumë shpejt gjithçka do të jetë e disponueshme.
Metodat e integrimit
Ka 2 metoda integrimi me Elastic:
- Përmes klientit natyror për TCP. Drejtori natyror gradualisht po zhduket: nuk po mbështetet më, ka një sintaksë shumë të vështirë. Prandaj ne praktikisht nuk e përdorim dhe përpiqemi të heqim dorë nga ai.
- Përmes ndërfaqes HTTP, ku mund të përdorim si kërkesa JSON ashtu edhe sintaksën Lucene. E fundit është një motor tekstual që përdor Elastic. Në këtë variant, ne kemi mundësinë e Batch përmes kërkesave JSON për HTTP. Ky është variant që përpiqemi ta përdorim.
Falë ndërfaqes HTTP ne mund të përdorim biblioteka që ofrojnë një implementim asinkron të HTTP klientit. Ne mund të shfrytëzojmë avantazhin e Batch dhe API-së asinkrone, që në fund ofron performancë të lartë, e cila na ndihmoi shumë në ditët e aksioneve të mëdha (për këtë më poshtë).
Pak numra për krahasim:
- Ruajtja e përdoruesve që morën çmime në Postgres në 20 thread pa grumbullime: 460713 regjistrime për 42 sekonda.
- Elastic + klient reaktiv në 10 thread + batch në 1000 elemente: 596749 regjistrime për 11 sekonda.
- Elastic + klient reaktiv në 10 thread + batch në 1000 elemente: 23801684 regjistrime për 4 minuta.
Tani kemi shkruar një menaxher kërkesash HTTP, i cili ndalon JSON, si Batch/nuk Batch dhe dërgon përmes çdo klienti HTTP pavarësisht nga biblioteka. Po ashtu, mund të zgjidhet dërgimi sinhron ose asinkron i kërkesave.
Në disa integrime ne ende përdorim klientin zyrtar të transportit, por kjo është një çështje e ristrukturimit të afërt. Megjithatë, për përpunimin përdoret klienti ynë, i ndërtuar mbi bazën e Spring WebClient.

Promocion i madh
NjĂ« herĂ« nĂ« vit, nĂ« projekt zhvillohet njĂ« promovim i madh pĂ«r pĂ«rdoruesit â ky Ă«shtĂ« ai Highload, sepse nĂ« kĂ«tĂ« kohĂ« ne punojmĂ« me miliona pĂ«rdorues njĂ«kohĂ«sisht.
Zakonisht, peaks e ngarkesave ndodhin gjatë festave, por ky promovim është një nivel krejt tjetër. Dy vite më parë, në ditën e promovimit shitëm 27 580 890 njësi të mallrave. Të dhënat u përpunuan për më shumë se një gjysmë ore, duke shkaktuar shqetësim te përdoruesit. Përdoruesit morën çmime për pjesëmarrje, por u bë e qartë se procesi duhet të përshpejtohet.
Në fillim të vitit 2019, ne vendosëm që na duhej ElasticSearch. Për një vit organizuam përpunimin e të dhënave të marra në Elastic dhe shpërndarjen e tyre në API-në e aplikacionit mobil dhe në sit. Në fund, gjatë vitit të ardhshëm gjatë një fushate ne përpunuam 15 131 783 regjistrime brenda 6 minutash.
Duke qenë se kemi shumë të interesuar për të blerë produkte dhe për të marrë pjesë në shpërblime gjatë fushatave, kjo është një masë përkohësore. Tani ne dërgojmë informacionin e saktë në Elastic, por në të ardhmen planifikojmë të transferojmë informacionin arkivor nga muajt e kaluar në Postgres, si një depo të përhershme. Për të mos mbushur indeksin Elastic, i cili gjithashtu ka kufizimet e tij.
Përfundimi/konkluzionet
Derimë tani, ne kemi transferuar në Elastic të gjitha shërbimet që dëshironim dhe për këtë arsye kemi bërë një pauzë. Tani ne po ndërtojmë një indeks në Elastic mbi depozitimin kryesor të përhershëm në Postgres, i cili merr ngarkesën e përdoruesve.
Në të ardhmen planifikojmë të transferojmë shërbimet nëse kuptojmë që kërkesa për të dhëna bëhet shumë e ndryshme dhe kërkohet në një numër të papërcaktuar kolonash. Kjo tashmë është një detyrë jo për Postgres.
Nëse na nevojitet kërkimi i plotë në funksionalitet ose nëse kemi shumë kritere të ndryshme kërkese, tani e dimë që duhet ta përkthejmë në Elastic.
âââ
Faleminderit qĂ« e lexuat. NĂ«se nĂ« kompaninĂ« tuaj gjithashtu pĂ«rdoret ElasticSearch dhe keni raste tĂ« veçanta implementimi, na tregoni. Do tĂ« ishte interesante tĂ« mĂ«sojmĂ« si e bĂ«jnĂ« tĂ« tjerĂ«t đ
Burimi: habr.com
