Terhelésoptimalizálás egy Highload projektnél az ElasticSearch segítségével

Szia Habr! A nevem Maxim Vasziljev, elemzőként és projektmenedzserként dolgozom a FINCH-nál. Ma szeretném elmondani, hogy az ElasticSearch segítségével hogyan tudtunk 15 millió kérést feldolgozni 6 perc alatt, és optimalizálni az egyik ügyfelünk oldalának napi terhelését. Sajnos nevek nélkül kell majd bennünk, mivel NFÜ-nk van, reméljük, a cikk tartalma ezt nem fogja szenvedni. Gyerünk.

Hogyan működik a projekt

Háttérrendszerünkön olyan szolgáltatásokat hozunk létre, amelyek biztosítják ügyfeleink weboldalainak és mobilalkalmazásainak teljesítményét. Az általános felépítés a diagramon látható:

Terhelésoptimalizálás egy Highload projektnél az ElasticSearch segítségével

A munka során nagyszámú tranzakciót dolgozunk fel: vásárlásokat, fizetéseket, felhasználói egyenlegekkel végzett műveleteket, amelyekhez rengeteg naplót tárolunk, valamint ezeket az adatokat importáljuk és exportáljuk külső rendszerekbe.

Vannak fordított folyamatok is, amikor adatokat kapunk a klienstől és továbbítunk a felhasználónak. Ezenkívül továbbra is léteznek folyamatok a kifizetésekkel és a bónuszprogramokkal való munkavégzéshez.

Rövid háttér

Kezdetben a PostgreSQL-t használtuk egyetlen adattárként. Standard előnyei egy DBMS számára: tranzakciók jelenléte, fejlett adatmintavételi nyelv, az integrációs eszközök széles skálája; jó teljesítménnyel kombinálva elég sokáig kielégítette igényeinket.

Abszolút minden adatot a Postgresben tároltunk: a tranzakcióktól a hírekig. De nőtt a felhasználók száma, és ezzel együtt a kérések száma is.

A megértés érdekében a munkamenetek éves száma 2017-ben csak az asztali oldalon 131 millió. 2018-ban - 125 millió. 2019-ben ismét 130 millió. Adjon hozzá további 100-200 milliót az oldal mobil verziójából és a mobilalkalmazásból, és Ön rengeteg kérést fog kapni.

A projekt növekedésével a Postgres leállt a terheléssel való megbirkózásról, nem volt időnk - nagyszámú különféle lekérdezés jelent meg, amelyekhez nem tudtunk elegendő számú indexet létrehozni.

Megértettük, hogy szükség van más adattárolókra, amelyek kielégítik az igényeinket, és leveszik a terhelést a PostgreSQL-ről. Az Elasticsearch-ot és a MongoDB-t tekintették lehetséges opcióknak. Utóbbi a következő pontokban veszített:

  1. Lassú indexelési sebesség, ahogy az indexekben lévő adatok mennyisége nő. Az Elastic esetében a sebesség nem függ az adatmennyiségtől.
  2. Nincs teljes szöveges keresés

Így hát az Elastic-ot választottuk magunknak, és felkészültünk az átállásra.

Átállás elasztikusra

1. Megkezdtük az átállást az értékesítési pont kereső szolgáltatásból. Ügyfelünk összesen mintegy 70 értékesítési ponttal rendelkezik, ehhez többféle keresésre van szükség az oldalon és az alkalmazásban:

  • Szöveges keresés városnév alapján
  • GeoSearch egy adott sugáron belül egy bizonyos pontból. Például, ha a felhasználó azt szeretné látni, hogy mely értékesítési pontok vannak a legközelebb az otthonához.
  • Keresés egy adott négyzet alapján - a felhasználó rajzol egy négyzetet a térképre, és ennek a sugárnak az összes pontja megjelenik számára.
  • Keresés további szűrőkkel. Az értékesítési pontok választékban különböznek egymástól

Ha már a szervezésről beszélünk, akkor a Postgres-ben van adatforrásunk a térképhez és a hírekhez is, az Elastic Snapshot-ok pedig az eredeti adatokból származnak. A helyzet az, hogy a Postgres kezdetben nem tudott minden kritérium alapján megbirkózni a kereséssel. Nemcsak sok index volt, de átfedhettek is, így a Postgres ütemező elveszett, és nem értette, melyik indexet használja.

2. A sorban a hírek rovat következett. A publikációk minden nap megjelennek az oldalon, hogy a felhasználó ne vesszen el az információáramlásban, az adatokat a kiadás előtt rendezni kell. Erre való a keresés: kereshetsz az oldalon szöveges egyezés alapján, és ezzel egyidejűleg további szűrőket is csatlakoztathatsz, hiszen ezek is az Elasticon keresztül készülnek.

3. Ezután áthelyeztük a tranzakció feldolgozását. A felhasználók megvásárolhatnak egy bizonyos terméket az oldalon, és részt vehetnek egy nyereményjátékban. Az ilyen vásárlások után nagy mennyiségű adatot dolgozunk fel, különösen hétvégén és ünnepnapokon. Összehasonlításképpen, ha hétköznapokon a vásárlások száma valahol 1,5-2 millió között mozog, akkor ünnepnapokon ez a szám elérheti az 53 milliót is.

Ugyanakkor az adatokat a lehető legrövidebb időn belül fel kell dolgozni - a felhasználók nem szeretnek több napot várni az eredményre. A Postgres-en keresztül nincs mód ilyen határidők elérésére – gyakran kaptunk zárolást, és miközben minden kérést feldolgoztunk, a felhasználók nem tudták ellenőrizni, hogy megkapták-e a nyereményeket vagy sem. Ez nem túl kellemes üzletnek, ezért áthelyeztük a feldolgozást az Elasticsearchba.

időszakosság

A frissítések mostantól eseményalapúak, a következő feltételeknek megfelelően:

  1. Értékesítési pontok. Amint külső forrásból adatot kapunk, azonnal elindítjuk a frissítést.
  2. Hírek. Amint bármilyen hír szerkesztésre kerül az oldalon, az automatikusan elküldésre kerül az Elastic-nak.

Itt is érdemes megemlíteni az Elastic előnyeit. A Postgres-ben kérés elküldésekor meg kell várni, amíg őszintén feldolgozza az összes rekordot. 10 XNUMX rekordot küldhet az Elasticnak, és azonnal elkezdheti a munkát, anélkül, hogy meg kellene várnia a rekordok szétosztását az összes szilánk között. Persze előfordulhat, hogy egyes Shard vagy Replica nem látja azonnal az adatokat, de hamarosan minden elérhető lesz.

Integrációs módszerek

Kétféleképpen lehet integrálni az Elastic-szal:

  1. Natív kliensen keresztül TCP-n keresztül. A natív meghajtó fokozatosan kihal: már nem támogatott, nagyon kényelmetlen a szintaxisa. Ezért gyakorlatilag nem használjuk, és megpróbáljuk teljesen elhagyni.
  2. HTTP-interfészen keresztül, amely mind a JSON-kéréseket, mind a Lucene szintaxist használhatja. Az utolsó egy szövegmotor, amely Elastic-ot használ. Ebben a verzióban lehetőségünk van HTTP-n keresztül kötegelni JSON-kérelmeket. Ezt a lehetőséget próbáljuk használni.

A HTTP interfésznek köszönhetően olyan könyvtárakat használhatunk, amelyek a HTTP kliens aszinkron megvalósítását biztosítják. Kihasználhatjuk a Batch-et és a nagy teljesítményt eredményező aszinkron API-t, ami sokat segített a nagy promóció napjaiban (erről lentebb bővebben)

Néhány szám összehasonlításképpen:

  • Postgres bounty felhasználók mentése 20 szálon csoportosítás nélkül: 460713 rekord 42 másodperc alatt
  • Elasztikus + reaktív kliens 10 szálhoz + köteg 1000 elemhez: 596749 rekord 11 másodperc alatt
  • Rugalmas + reaktív kliens 10 szálhoz + köteg 1000 elemhez: 23801684 bejegyzés 4 perc alatt

Most írtunk egy HTTP-kéréskezelőt, amely a JSON-t Batch-ként / nem kötegként építi fel, és bármely HTTP-kliensen keresztül elküldi, függetlenül a könyvtártól. Azt is választhatja, hogy a kéréseket szinkron vagy aszinkron módon küldi-e el.

Egyes integrációkban továbbra is a hivatalos közlekedési klienst használjuk, de ez már csak a következő átalakítás kérdése. Ebben az esetben a Spring WebClient alapján készült egyedi kliens kerül felhasználásra a feldolgozáshoz.

Terhelésoptimalizálás egy Highload projektnél az ElasticSearch segítségével

nagy promóció

Évente egyszer a projekt nagy promóciót szervez a felhasználók számára - ez ugyanaz a Highload, mivel ebben az időben több tízmillió felhasználóval dolgozunk egyszerre.

Általában az ünnepek alatt jelentkeznek a terhelési csúcsok, de ez a promóció teljesen más szinten van. Tavaly az akció napján 27 darab árut adtunk el. Az adatok feldolgozása több mint fél órán keresztül zajlott, ami kellemetlenséget okozott a felhasználóknak. A felhasználók díjakat kaptak a részvételért, de világossá vált, hogy a folyamatot fel kell gyorsítani.

2019 elején úgy döntöttünk, hogy szükségünk van az ElasticSearch-re. A beérkezett adatok Elasticban történő feldolgozását és kiadását a mobilalkalmazás és a weboldal api-jában egész éven keresztül szerveztük. Ennek eredményeként a következő évben a kampány során feldolgoztuk 15 131 783 bejegyzés 6 perc alatt.

Mivel nagyon sokan szeretnének vásárolni és akciókban részt venni a nyeremények sorsolásában, ez egy átmeneti intézkedés. Most naprakész információkat küldünk az Elasticnak, de a jövőben tervezzük, hogy az elmúlt hónapok archivált adatait állandó tárhelyként a Postgres-be továbbítjuk. Annak érdekében, hogy ne tömítse el az Elastic indexet, amelynek szintén megvannak a korlátai.

Következtetés/Következtetések

Jelenleg az összes kívánt szolgáltatást átruháztuk az Elasticra, és ezt egyelőre szüneteltettük. Most egy indexet építünk az Elasticban a Postgres fő állandó tárhelyére, amely átveszi a felhasználói terhelést.

A jövőben a szolgáltatások átadását tervezzük, ha megértjük, hogy az adatkérés túlságosan sokrétűvé válik, és korlátlan számú oszlopra keresik. Ez már nem a Postgres feladata.

Ha teljes szöveges keresésre van szükségünk a funkcionalitásban, vagy ha sok különböző keresési feltételünk van, akkor már tudjuk, hogy ezt le kell fordítani Elastic-ra.

⌘⌘⌘

Köszönöm, hogy elolvasta. Ha az Ön cége is használja az ElasticSearch-t, és vannak saját megvalósítási esetei, akkor jelezze nekünk. Érdekes lesz tudni, hogy mások hogy vannak 🙂

Forrás: will.com

Hozzászólás