Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik

Hello, a nevem Evgeniy. A Yandex.Market keresési infrastruktúrájában dolgozom. Szeretnék mesélni a Habr közösségnek a Piac belső konyhájáról – és sok mesélnivalóm van. Mindenekelőtt a Piaci keresés működése, folyamatai és architektúrája. Hogyan kezeljük a vészhelyzeteket: mi történik, ha egy szerver leáll? Mi van, ha 100 ilyen szerver van?

Azt is megtudhatja, hogyan valósítunk meg új funkciókat egyszerre több szerveren. És hogyan teszteljük a komplex szolgáltatásokat közvetlenül a termelésben anélkül, hogy kellemetlenséget okoznánk a felhasználóknak. Általában hogyan működik a Market kereső, hogy mindenki jól érezze magát.

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik

Egy kicsit rólunk: milyen problémát oldunk meg

Amikor szöveget ír be, paraméterek szerint keres egy terméket, vagy összehasonlítja a különböző üzletekben található árakat, minden kérés elküldésre kerül a keresőszolgáltatásnak. A keresés a piac legnagyobb szolgáltatása.

Minden keresési kérést feldolgozunk: a market.yandex.ru, beru.ru webhelyekről, a Supercheck szolgáltatásból, a Yandex.Advisorból, mobilalkalmazásokból. A termékajánlatokat a yandex.ru keresési eredményei között is feltüntetjük.

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik

Keresőszolgáltatás alatt nem csak magát a keresést értem, hanem egy adatbázist is, amely a Piac összes ajánlatát tartalmazza. A lépték a következő: naponta több mint egymilliárd keresési kérést dolgoznak fel. És mindennek gyorsan, megszakítások nélkül kell működnie, és mindig a kívánt eredményt kell elérnie.

Mi az, ami: Piaci architektúra

Röviden ismertetem a Piac jelenlegi architektúráját. Nagyjából az alábbi diagrammal írható le:
Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik
Tegyük fel, hogy bejön hozzánk egy partnerbolt. Azt mondja, el akarok adni egy játékot: ezt a gonosz macskát csikorgással. És még egy dühös macska nyikorgó nélkül. És csak egy macska. Ezután az üzletnek ajánlatokat kell készítenie, amelyekre a Piac keres. Az áruház egy speciális xml-t generál ajánlatokkal, és közli az elérési utat ehhez az xml-hez az affiliate felületen keresztül. Az indexelő ezután rendszeresen letölti ezt az xml-t, ellenőrzi a hibákat, és az összes információt egy hatalmas adatbázisba menti.

Sok ilyen mentett xml van. Ebből az adatbázisból keresési index jön létre. Az index tárolása belső formátumban történik. Az index létrehozása után a Layout szolgáltatás feltölti azt a keresőkiszolgálókra.

Ennek eredményeként megjelenik az adatbázisban egy dühös macska csikorgással, és a macska indexe megjelenik a szerveren.

Elmondom, hogyan keresünk macskát a keresési architektúráról szóló részben.

Piaci keresési architektúra

A mikroszolgáltatások világában élünk: minden bejövő kérés market.yandex.ru sok részlekérdezést okoz, és ezek feldolgozásában több tucat szolgáltatás vesz részt. A diagram csak néhányat mutat be:

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik
Egyszerűsített kérésfeldolgozási séma

Minden szolgáltatásnak van egy csodálatos dolga - saját kiegyensúlyozója egyedi névvel:

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik

A kiegyenlítő nagyobb rugalmasságot biztosít a szolgáltatás kezelésében: például kikapcsolhatja a szervereket, ami gyakran szükséges a frissítésekhez. A kiegyenlítő látja, hogy a szerver nem elérhető, és automatikusan átirányítja a kéréseket más szerverekre vagy adatközpontokra. Szerver hozzáadásakor vagy eltávolításakor a terhelés automatikusan újraelosztásra kerül a szerverek között.

A kiegyenlítő egyedi neve nem függ az adatközponttól. Amikor az A szolgáltatás kérést küld B-nek, akkor a B kiegyenlítő alapértelmezés szerint átirányítja a kérést az aktuális adatközpontba. Ha a szolgáltatás nem érhető el, vagy nem létezik az aktuális adatközpontban, akkor a kérést átirányítja más adatközpontokhoz.

Az összes adatközpont egyetlen FQDN-je lehetővé teszi, hogy az A szolgáltatás teljesen elvonatkozzon a helyszínektől. A B szolgáltatáshoz intézett kérelmét mindig feldolgozzuk. Kivételt képez az az eset, amikor a szolgáltatás az összes adatközpontban található.

De nem minden olyan rózsás ennél a kiegyensúlyozónál: van egy további köztes komponensünk is. Előfordulhat, hogy a kiegyenlítő instabil, és ezt a problémát redundáns szerverek oldják meg. További késleltetés is van az A és B szolgáltatások között. A gyakorlatban azonban ez kevesebb, mint 1 ms, és a legtöbb szolgáltatás esetében ez nem kritikus.

A váratlan helyzet kezelése: keresési szolgáltatások kiegyensúlyozása és rugalmassága

Képzeld el, hogy összeomlás történik: találnod kell egy macskát, akinek csikorgója van, de a szerver összeomlik. Vagy 100 szerver. Hogyan lehet kijutni? Tényleg macska nélkül hagyjuk a felhasználót?

A helyzet ijesztő, de készen állunk rá. Megmondom sorban.

A keresési infrastruktúra több adatközpontban található:

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik

A tervezésnél egy adatközpont leállításának lehetőségét is belefoglaljuk. Az élet tele van meglepetésekkel – például egy kotrógép el tud vágni egy földkábelt (igen, ez megtörtént). A fennmaradó adatközpontok kapacitásának elegendőnek kell lennie ahhoz, hogy ellenálljon a csúcsterhelésnek.

Vegyünk egy egyetlen adatközpontot. Minden adatközpontnak ugyanaz a kiegyenlítő működési sémája:

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik
Egy egyensúlyozó legalább három fizikai szerver. Ez a redundancia a megbízhatóság érdekében készült. A kiegyenlítők HAProxon futnak.

A HAProxot nagy teljesítménye, alacsony erőforrásigénye és széleskörű funkcionalitása miatt választottuk. Keresőszoftverünk minden szerveren belül fut.

Kicsi annak a valószínűsége, hogy egy szerver meghibásodik. De ha sok szervered van, megnő annak a valószínűsége, hogy legalább egy leáll.

Ez történik a valóságban: a szerverek összeomlanak. Ezért folyamatosan figyelni kell az összes szerver állapotát. Ha a szerver nem válaszol, automatikusan megszakad a forgalomtól. Erre a célra a HAProxy beépített állapotfelméréssel rendelkezik. Másodpercenként egyszer eljut minden szerverhez egy „/ping” HTTP-kéréssel.

A HAProxy másik funkciója: az agent-check lehetővé teszi az összes kiszolgáló egyenletes betöltését. Ehhez a HAProxy csatlakozik az összes szerverhez, és azok az aktuális terheléstől függően 1-től 100-ig adják vissza súlyukat. A súly számítása a feldolgozási sorban lévő kérések száma és a processzor terhelése alapján történik.

Most a macska megtalálásáról. A keresés eredménye a következő kérésekben: /search?text=dühös+macska. A gyors kereséshez a teljes macskaindexnek bele kell férnie a RAM-ba. Még az SSD-ről való olvasás sem elég gyors.

Valamikor kicsi volt az ajánlati adatbázis, és egy szerver RAM-ja is elég volt hozzá. Ahogy nőtt az ajánlati bázis, már nem fért bele minden ebbe a RAM-ba, és az adatok két részre oszlottak: a shard 1-re és a shard 2-re.

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik
De ez mindig megtörténik: bármilyen megoldás, még a jó is, más problémákat szül.

A kiegyenlítő továbbra is bármelyik szerverre ment. De azon a gépen, ahol a kérés érkezett, csak az index fele volt. A többi más szervereken volt. Ezért a szervernek valamelyik szomszédos gépre kellett mennie. Miután mindkét szervertől megkaptuk az adatokat, az eredményeket egyesítettük és átsoroltuk.

Mivel a kiegyenlítő egyenletesen osztja el a kéréseket, minden szerver átsorolást végzett, és nem csak adatokat küld.

A probléma akkor fordult elő, ha egy szomszédos szerver nem volt elérhető. A megoldás az volt, hogy több, eltérő prioritású szervert „szomszédos” szerverként adtunk meg. Először a kérést elküldték az aktuális rack szervereinek. Ha nem érkezett válasz, a kérést elküldték az adatközpont összes szerverére. És végül a kérés más adatközpontokhoz is eljutott.
A javaslatok számának növekedésével az adatokat négy részre osztották. De nem ez volt a határ.

Jelenleg nyolc szilánkból álló konfigurációt használnak. Ezenkívül a még több memória megtakarítása érdekében az indexet felosztottuk egy keresési részre (amely a keresésre szolgál) és egy kivonat részre (amely nem vesz részt a keresésben).

Egy szerver csak egy szilánk információit tartalmazza. Ezért a teljes indexben való kereséshez nyolc, különböző szilánkokat tartalmazó szerveren kell keresnie.

A szerverek fürtökbe vannak csoportosítva. Minden fürt nyolc keresőmotort és egy kódrészletszervert tartalmaz.

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik
A kódrészletszerver statikus adatokat tartalmazó kulcsérték adatbázist futtat. Szükségesek dokumentumok kiállításához, például egy nyikorgó macska leírásához. Az adatokat speciálisan egy külön szerverre továbbítják, hogy ne terheljék a keresőszerverek memóriáját.

Mivel a dokumentumazonosítók csak egy indexen belül egyediek, előfordulhat, hogy nincsenek dokumentumok a részletekben. Nos, vagy hogy egy azonosítóhoz más tartalom lesz. Ezért ahhoz, hogy a keresés működjön, és az eredményeket visszaadhassuk, konzisztenciára volt szükség az egész klaszterben. Az alábbiakban elmondom, hogyan figyeljük a konzisztenciát.

Maga a keresés a következőképpen épül fel: a nyolc szerver bármelyikére érkezhet keresési kérés. Tegyük fel, hogy az 1. szerverhez érkezett. Ez a szerver minden érvet feldolgoz, és megérti, mit és hogyan kell keresni. A bejövő kéréstől függően a szerver további kéréseket intézhet a külső szolgáltatásokhoz a szükséges információkért. Egy kérést legfeljebb tíz külső szolgáltatásokhoz intézett kérés követhet.

A szükséges információk összegyűjtése után megkezdődik a keresés az ajánlati adatbázisban. Ehhez a fürt mind a nyolc kiszolgálójára lekérdezések készülnek.

A válaszok beérkezése után az eredményeket összevonják. Végül több további segédlekérdezésre lehet szükség a kódrészletszervernek az eredmények generálásához.

A klaszteren belüli keresési lekérdezések így néznek ki: /shard1?text=dühös+macska. Ezenkívül az űrlap segédlekérdezései folyamatosan, másodpercenként egyszer készülnek el a fürtön belüli összes szerver között: /állapot.

érdeklődés /állapot olyan helyzetet észlel, amikor a szerver nem elérhető.

Azt is szabályozza, hogy a keresőmotor és az index verziója azonos legyen minden szerveren, különben ellentmondásos adatok lesznek a fürtön belül.

Annak ellenére, hogy egy kódrészletszerver nyolc keresőmotor kéréseit dolgozza fel, processzora nagyon enyhén terhelt. Ezért a töredékadatokat most egy külön szolgáltatásba visszük át.

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik

Az adatok átviteléhez univerzális kulcsokat vezettünk be a dokumentumokhoz. Most már lehetetlen olyan helyzetekben, amikor egy másik dokumentumból származó tartalom egy kulcs használatával kerül visszaadásra.

De az átállás egy másik architektúrára még nem fejeződött be. Most szeretnénk megszabadulni a dedikált kódrészletszervertől. Ezután teljesen távolodjon el a klaszterstruktúrától. Ez lehetővé teszi számunkra, hogy továbbra is könnyen méretezhessünk. További bónusz a jelentős vasmegtakarítás.

És most ijesztő történetek boldog véggel. Tekintsünk néhány esetet a szerver elérhetetlenségére.

Valami szörnyű történt: egy szerver nem érhető el

Tegyük fel, hogy egy szerver nem elérhető. Ezután a fürt többi kiszolgálója továbbra is válaszolhat, de a keresési eredmények hiányosak lesznek.

Állapotellenőrzésen keresztül /állapot a szomszédos szerverek megértik, hogy az egyik nem elérhető. Ezért a teljesség megőrzése érdekében a fürt összes kiszolgálója kérésenként /ping kezdenek válaszolni az egyensúlyozónak, hogy ők is elérhetetlenek. Kiderült, hogy a fürt összes szervere meghalt (ami nem igaz). Ez a fürtsémánk fő hátránya – ezért szeretnénk megszabadulni tőle.

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik

A hibával meghiúsult kéréseket a kiegyenlítő újraküldi más szervereken.
A kiegyenlítő szintén leállítja a felhasználói forgalom küldését a kimerült szerverekre, de továbbra is ellenőrzi azok állapotát.

Amikor a szerver elérhetővé válik, elkezd válaszolni /ping. Amint normális válaszok érkeznek a halott szerverekről érkező pingekre, a kiegyenlítők elkezdik továbbítani a felhasználói forgalmat oda. A klaszter működése helyreállt, hurrá.

Még rosszabb: sok szerver nem elérhető

Az adatközpontban található szerverek jelentős része leépül. Mit kell csinálni, hova futni? Ismét a kiegyensúlyozó jön a segítségre. Mindegyik kiegyenlítő folyamatosan tárolja a memóriájában az élő szerverek aktuális számát. Folyamatosan számolja, hogy az aktuális adatközpont mekkora forgalmat képes maximálisan feldolgozni.

Amikor egy adatközpontban sok szerver leáll, a kiegyenlítő rájön, hogy ez az adatközpont nem tudja feldolgozni a teljes forgalmat.

Ezután a többletforgalom véletlenszerűen elkezdődik más adatközpontok felé. Minden működik, mindenki boldog.

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik

Hogyan csináljuk: kiadványok kiadása

Most beszéljünk arról, hogyan tesszük közzé a szolgáltatáson végrehajtott módosításokat. Itt a folyamatok egyszerűsítésének útját választottuk: egy új kiadás bevezetése szinte teljesen automatizált.
Ha bizonyos számú változtatás halmozódik fel a projektben, automatikusan létrejön egy új kiadás, és elindul a felépítése.

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik

Ezután a szolgáltatás tesztelésre kerül, ahol a működés stabilitását ellenőrizzük.

Ezzel egy időben elindul az automatikus teljesítményteszt. Ezt egy speciális szolgálat intézi. Most nem beszélek róla - leírása külön cikkre érdemes.

Ha a tesztben való közzététel sikeres, a kiadás prestabilban történő közzététele automatikusan elindul. A Prestable egy speciális fürt, ahol a normál felhasználói forgalmat irányítják. Ha hibát ad vissza, a kiegyenlítő újrakérést küld a termeléshez.

A prestabilban a válaszidőket mérik, és összehasonlítják az előző gyártási kiadással. Ha minden rendben van, akkor az ember csatlakozik: ellenőrzi a terhelési tesztek grafikonjait és eredményeit, majd elkezdi a gyártást.

Minden jót a felhasználóé: A/B tesztelés

Nem mindig nyilvánvaló, hogy egy szolgáltatás változtatása valódi hasznot hoz-e. A változtatások hasznosságának mérésére az emberek A/B teszteléssel álltak elő. Elmondom egy kicsit, hogyan működik a Yandex.Market keresésben.

Minden egy új CGI paraméter hozzáadásával kezdődik, amely új funkciókat tesz lehetővé. Legyen a paraméterünk: market_new_functionality=1. Ezután a kódban engedélyezzük ezt a funkciót, ha a zászló jelen van:

If (cgi.experiments.market_new_functionality) {
// enable new functionality
}

Az új funkcionalitás bevezetése folyamatban van.

Az A/B tesztelés automatizálására külön szolgáltatás áll rendelkezésre, amely részletes információkat nyújt itt leírva. Kísérlet jön létre a szolgáltatásban. A forgalom aránya például 15%. A százalékok nem a lekérdezésekhez, hanem a felhasználókhoz vannak beállítva. A kísérlet időtartama is feltüntetésre kerül, például egy hét.

Egyszerre több kísérlet is futtatható. A beállításokban megadhatja, hogy lehetséges-e metszéspont más kísérletekkel.

Ennek eredményeként a szolgáltatás automatikusan hozzáad egy argumentumot market_new_functionality=1 a felhasználók 15%-ára. Ezenkívül automatikusan kiszámolja a kiválasztott mutatókat. A kísérlet befejezése után az elemzők megvizsgálják az eredményeket, és következtetéseket vonnak le. A megállapítások alapján döntés születik a gyártás vagy a finomítás bevezetéséről.

A piac ügyes keze: tesztelés a termelésben

Gyakran előfordul, hogy tesztelni kell egy új funkció működését a termelésben, de nem biztos benne, hogyan fog viselkedni „harci” körülmények között nagy terhelés mellett.

Van megoldás: a CGI-paraméterekben lévő flagek nem csak A/B tesztelésre, hanem új funkcionalitás tesztelésére is használhatók.

Készítettünk egy eszközt, amely lehetővé teszi, hogy azonnal módosítsa a konfigurációt több ezer szerveren anélkül, hogy a szolgáltatást kockázatoknak tenné ki. Stop Tapnak hívják. Az eredeti ötlet az volt, hogy gyorsan lehessen letiltani néhány funkciót elrendezés nélkül. Aztán az eszköz bővült és összetettebb lett.

A szolgáltatás folyamatábrája az alábbiakban látható:

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik

A jelzőértékek beállítása az API-n keresztül történik. A felügyeleti szolgáltatás ezeket az értékeket tárolja az adatbázisban. Minden szerver tíz másodpercenként egyszer megy az adatbázisba, kiszivattyúzza a jelzőértékeket, és alkalmazza ezeket az értékeket minden kérésre.

A Stop érintésnél kétféle értéket állíthat be:

1) Feltételes kifejezések. Akkor alkalmazza, ha az egyik érték igaz. Például:

{
	"condition":"IS_DC1",
	"value":"3",
}, 
{
	"condition": "CLUSTER==2 and IS_BERU", 
	"value": "4!" 
}

A „3” érték akkor kerül alkalmazásra, amikor a kérést a DC1 helyen feldolgozzák. Az érték pedig „4”, amikor a kérést a beru.ru webhely második fürtjén dolgozzák fel.

2) Feltétel nélküli értékek. Alapértelmezés szerint alkalmazza, ha egyik feltétel sem teljesül. Például:

érték, érték!

Ha egy érték felkiáltójellel végződik, akkor magasabb prioritást kap.

A CGI-paraméter-elemző elemzi az URL-t. Ezután alkalmazza a Stop Tap értékeit.

A következő prioritású értékek kerülnek alkalmazásra:

  1. A Stop Tap (felkiáltójel) által megnövelt prioritással.
  2. A kérésből származó érték.
  3. Alapértelmezett érték a Stop tap.
  4. Alapértelmezett érték a kódban.

Sok zászló van, amelyek feltételes értékekben vannak feltüntetve - ezek elegendőek az összes általunk ismert forgatókönyvhöz:

  • Adatközpont.
  • Környezet: gyártás, tesztelés, árnyék.
  • Helyszín: piac, beru.
  • Klaszterszám.

Ezzel az eszközzel új funkcionalitást engedélyezhet a kiszolgálók egy bizonyos csoportján (például csak egy adatközpontban), és tesztelheti e funkció működését anélkül, hogy a teljes szolgáltatásra nézve különösebb kockázatot jelentene. Még akkor is, ha valahol súlyos hibát követett el, minden zuhanni kezdett, és az egész adatközpont leállt, a kiegyenlítők átirányítják a kéréseket más adatközpontokba. A végfelhasználók nem vesznek észre semmit.

Ha problémát észlel, azonnal visszaállíthatja a jelzőt az előző értékére, és a változtatások visszaállnak.

Ennek a szolgáltatásnak is megvannak a maga árnyoldalai: a fejlesztők nagyon szeretik, és gyakran minden változtatást a Stop Tap-ba próbálnak betolni. Megpróbáljuk leküzdeni a visszaéléseket.

A Stop Tap megközelítés akkor működik jól, ha már rendelkezik stabil kóddal, amely készen áll az éles kiadásra. Ugyanakkor továbbra is kétségei vannak, és „harci” körülmények között szeretné ellenőrizni a kódot.

A Stop Tap azonban nem alkalmas fejlesztés közbeni tesztelésre. A fejlesztők számára külön fürt található, az úgynevezett „árnyékfürt”.

Titkos tesztelés: Shadow Cluster

Az egyik fürttől érkező kérések duplikálódnak az árnyékfürtbe. De a kiegyenlítő teljesen figyelmen kívül hagyja a klaszter válaszait. Működésének diagramja az alábbiakban látható.

Hogyan működik a Yandex.Market keresés, és mi történik, ha az egyik szerver meghibásodik

Kapunk egy tesztklasztert, amely valódi „harci” körülmények között van. Normál felhasználói forgalom megy oda. A hardver mindkét fürtben ugyanaz, így a teljesítmény és a hibák összehasonlíthatók.

És mivel a kiegyenlítő teljesen figyelmen kívül hagyja a válaszokat, a végfelhasználók nem látják az árnyékfürtből érkező válaszokat. Ezért nem félelmetes hibázni.

Álláspontja

Szóval, hogyan építettük fel a Market keresést?

Annak érdekében, hogy minden gördülékenyen menjen, a funkcionalitást külön szolgáltatásokra különítjük el. Így csak azokat a komponenseket tudjuk skálázni, amelyekre szükségünk van, és egyszerűbbé tudjuk tenni a komponenseket. Könnyen hozzárendelhet egy külön komponenst egy másik csapathoz, és megoszthatja a rajta végzett munka felelősségét. És ezzel a megközelítéssel a vas jelentős megtakarítása nyilvánvaló plusz.

Az árnyékklaszter is segítségünkre van: szolgáltatásokat tudunk fejleszteni, közben tesztelni és nem zavarni a felhasználót.

Nos, természetesen a gyártásban történő tesztelés. Meg kell változtatnia a konfigurációt több ezer szerveren? Egyszerűen használja a Stop Tap. Így azonnal kiteregethet egy kész komplex megoldást, és probléma esetén visszaállíthatja a stabil verziót.

Remélem, sikerült megmutatnom, hogyan tesszük gyorssá és stabillá a Piacot az egyre növekvő ajánlati bázissal. Hogyan oldjuk meg a szerverproblémákat, kezeljük a rengeteg kérést, javítjuk a szolgáltatás rugalmasságát, és tesszük ezt a munkafolyamatok megszakítása nélkül.

Forrás: will.com

Hozzászólás