Útmutató az adatbázis méretezésének megértéséhez

Számos online cikk írja le az adatbázis méretezhetőségi mintáit, de ezek többnyire szétszórt cikkek - csak olyan technikák, amelyeket véletlenszerűen, sok összefüggés nélkül határoznak meg. Megállapítottam, hogy nincsenek meghatározva lépésről lépésre, és nem vitatják meg, hogy mikor melyik méretezési lehetőséget, melyik méretezési opciót lehet megvalósítani a gyakorlatban, és miért.

Ezért tervezek néhány technikát részletesen megvitatni a következő cikkekben. Kezdésként jobbnak érzem, ha lépésről lépésre tárgyalok technikákat valamilyen kontextussal a magam módján. Ez a cikk magas szintű cikk - itt nem részletezem a méretezési technikákat, de áttekintést nyújtok. Tehát kezdjük.

Egy esettanulmány

Tegyük fel, hogy létrehozott egy startupot, amely olcsó költséggel kínál autós megosztást. Kezdetben amikor elindul, megcéloz egy várost, és alig van több tíz vásárlója az első hirdetés után.

Az összes ügyfelet, utazást, helyet, foglalási adatot és az utazási előzményeket ugyanabba az adatbázisba vagy nagy valószínűséggel egyetlen fizikai gépbe menti. Nincs elegáns gyorsítótár vagy nagy adatátviteli rendszer a problémák megoldására, mivel az alkalmazás nagyon új. Ez ebben a pillanatban tökéletes az Ön esetére, mivel nagyon kevés ügyfél van, és a rendszere alig foglal le például 1 utat 5 perc alatt.

Az idő múlásával azonban egyre többen jelentkeznek be a rendszerbe, mivel Ön a piacon a legolcsóbb szolgáltatás, és a promóciójának és a hirdetéseknek köszönhetően. Elkezdi mondjuk 10 foglalás percenként lefoglalását, és lassan 20, 30 foglalás / percre nő.

Ebben a pillanatban rájössz, hogy a rendszer rosszul kezdett teljesíteni: az API késleltetése nagyon megnőtt, és egyes tranzakciók holtpontra jutnak vagy éheznek, és végül kudarcot vallanak. Alkalmazása több időt vesz igénybe, hogy reagáljon, ami az ügyfelek elégedetlenségét okozza. Mit tehet a probléma megoldása érdekében?

1. minta - Lekérdezés optimalizálása és a Connection Pool megvalósítása:

Az első megoldás, amely eszembe jut, hogy a gyorsítótár gyakran használ nem dinamikus adatokat, például foglalási előzményeket, fizetési előzményeket, felhasználói profilokat és így tovább. De az alkalmazásréteg gyorsítótárazása után nem oldhatja meg az API-k késési problémáját, amelyek az utazás megkezdése után egy adott pillanatban olyan dinamikus adatokat tárnak fel, mint az aktuális vezető helye vagy a legközelebbi fülkék egy adott ügyfél számára, vagy az aktuális útiköltség.

Azonosítja, hogy az adatbázis valószínűleg erősen normalizált, ezért a feleslegessé tétel érdekében néhány redundáns oszlopot (ezek az oszlopok gyakran jelennek meg lekérdezésekben WHEREvagy ezekben JOIN ONzáradékok szerepelnek) bevetik a gyakran használt táblákban. Ez csökkenti a csatlakozási lekérdezéseket, egy nagy lekérdezést több kisebb lekérdezésre bont, és eredményeiket felveszi az alkalmazásrétegbe.

Egy másik párhuzamos optimalizálás, amelyet megtehet, az adatbázis-kapcsolatok módosítása. Az adatbázis kliens könyvtárai és a külső könyvtárak szinte az összes programozási nyelven elérhetők. A kapcsolatkészlet-könyvtárak segítségével tárolhatja az adatbázis-kapcsolatokat, vagy beállíthatja a kapcsolatkészlet méretét magában az adatbázis-kezelő rendszerben.

Bármely hálózati kapcsolat létrehozása költséges, mivel némi oda-vissza kommunikációt igényel az ügyfél és a szerver között. A kapcsolatok egyesítése segíthet a kapcsolatok számának optimalizálásában. A kapcsolatkészlet-könyvtárak segíthetnek a kapcsolatok multiplexelésében - több alkalmazásszál is használhatja ugyanazt az adatbázis-kapcsolatot. Meglátom, hogy később külön cikkben részletesen meg tudom-e magyarázni a kapcsolat-poololást.

Mérje meg az API-k késési idejét, és találjon valószínűleg 20–50% vagy annál kevesebb csökkentett késleltetést. Ez jó optimalizálás ebben a pillanatban.

Most még egy városra bővítette vállalkozását, több ügyfél regisztrál, lassan 80–100 foglalást kezd el végezni percenként. Rendszere nem képes kezelni ezt a skálát. Ismét látja, hogy az API késleltetése megnőtt, az adatbázis-réteg feladta, de ezúttal egyetlen lekérdezés-optimalizálás sem jelent számottevő teljesítménynövekedést. Ellenőrizze a rendszer metrikáját, azt találja, hogy a lemezterület szinte megtelt, a CPU az idő 80% -ában foglalt, a RAM nagyon gyorsan megtöltődik.

2. minta - függőleges méretezés vagy nagyítás:

Miután megvizsgálta az összes rendszermutatót, tudja, hogy a rendszer hardverének frissítése helyett nincs más egyszerű megoldás. A RAM méretét kétszer, a lemezterületet mondjuk 3-szor vagy annál nagyobb mértékben frissíti. Ezt nevezzük függőleges méretezésnek vagy a rendszer felnagyításának. Értesíti az infrastruktúra csapatát, vagy a fejlesztői csapatot, vagy harmadik fél adatközpont ügynökeit a gép frissítéséről.

De hogyan állítja be a gépet a függőleges méretezéshez?

Kioszt egy nagyobb gépet. Az egyik megközelítés nem az adatok manuális migrálása a régi gépről, hanem az új gép beállítása replicaa meglévő gépre ( primary) - ideiglenes primary replicakonfigurációt kell készíteni . Hagyja, hogy a replikáció természetesen megtörténjen. Miután elkészült a replikáció, népszerűsítse az új gépet elsődlegesként, és tegye offline állapotba a régebbi gépet. Mivel a nagyobb gép várhatóan minden kérést kiszolgál, az összes olvasás / írás ezen a gépen fog történni.

Menő. Rendszere ismét növekvő teljesítmény mellett működik és működik.

Vállalkozása nagyon jól megy, és úgy dönt, hogy további 3 városra méretez - összesen 5 városban működik. A forgalom háromszorosa a korábbinak, várhatóan percenként körülbelül 300 foglalást fog végrehajtani. Mielőtt még el is érné ezt a célfoglalást, ismét eltalálja a teljesítménycsökkenést, az adatbázis index mérete nagymértékben növekszik a memóriában, állandó karbantartást igényel, a táblázatok beolvasása az indexszel lassabb, mint valaha. Kiszámítja a gép további növelésének költségeit, de nem győzött meg a költségekkel. Mit csinálsz most?

3. minta - Parancslekérdezés-felelősség szegregáció (CQRS):

Azonosítja, hogy a nagy gép nem képes kezelni az összes read/writekérést. Az esetek többségében bármelyik vállalatnak szüksége van tranzakciós képességre a műveletek során, writede nem a readműveletek során. Egy kicsit inkonzisztens vagy késleltetett readműveletekkel is jól állsz, és a vállalkozásodnak sincs ezzel problémája. Lát egy lehetőséget, ahol jó lehetőség lehet a fizikai gép readés a writeműveletek elválasztása . Lehetőséget teremt az egyes gépek számára, hogy több read/writeműveletet kezeljenek .

Most még két nagy gépet veszel és állítasz replicabe a jelenlegi géphez hasonlóan . Az adatbázis replikációja gondoskodik az adatok primarygépről gépre történő terjesztéséről replica. Az összes olvasott lekérdezést (Query ( Q) be CQRS) a replikákba replicanavigálja - bármelyik bármilyen olvasási kérelmet kiszolgálhat, az összes írási kérdést (Command ( C) in CQRS) a primary. Lehet, hogy kevés a késés a replikációban, de az üzleti felhasználási esete szerint ez rendben van.

A mindennapi néhány százezer kérést kiszolgáló közepes méretű startupok többsége életben maradhat az elsődleges replika beállításával, feltéve, hogy időnként archiválja a régebbi adatokat.

Most további 2 városra méretez, és látja, hogy primarynem képes kezelni az összes writekérést. Sok writekérés késleltetett. Sőt, a között eltelt primary& replicanéha hatása az ügyfelek és illesztőprogramok ex - ha utazás véget ér, az ügyfél fizet a vezető sikerült, de a vezető nem látja a fizetési óta ügyfél tevékenységének egy writekérés, hogy megy a primary, míg a vezető tevékenysége a readkérelem az az egyik replikához megy. A teljes rendszer olyan lassú, hogy a sofőr legalább fél percig nem tudja látni a fizetést - ez mind a sofőr, mind az ügyfél számára frusztráló. Hogyan oldja meg?

4. minta - Többszörös elsődleges replikáció

Nagyon jól méretezett a primary-replicakonfigurációval, de most nagyobb írási teljesítményre van szüksége. Lehet, hogy készen áll egy kis kompromisszumra a readkérés teljesítményével kapcsolatban. Miért ne terjesztené az írási kérelmet egy a-nak replicais?

A multi-primarykonfiguráció, az összes gép tud működni, mint a két primaryés replica. Gondolhat arra, multi-primaryahogy a gépek köre mondja A->B->C->D->A. Badatok replikálása onnan A, Cadatok replikálása onnan B, Dadatok replikálása onnan C, Aadatok replikálása onnan D. Bármelyik csomópontra írhat adatokat, az adatok olvasása közben az összes csomópontra továbbíthatja a lekérdezést, aki válaszol, azt visszaadja. Minden csomópontnak ugyanaz az adatbázis-sémája, ugyanaz a táblázata, indexe stb. Tehát meg kell győződnie arról, hogy nincs ütközés idaz ugyanazon táblázat csomópontjain, ellenkező esetben a sugárzás során több csomópont különböző adatokat ad vissza ugyanazért id.

Általában jobb használni, UUIDvagy GUIDazonosító. Ennek a technikának még egy hátránya - a readlekérdezések nem hatékonyak, mivel a lekérdezés sugárzását és a helyes eredmény elérését foglalják magukban - alapvetően a szórványgyűjtés megközelítés.

Most további 5 városra skálázol, és a rendszered újra fáj. Várhatóan másodpercenként nagyjából 50 kérést fog kezelni. Kétségbeesetten kell kezelnie a sok egyidejű kérést. Hogyan éred el ezt?

5. minta - particionálás:

Tudja, hogy a locationadatbázis valami, ami egyre magasabb writeés reada forgalom. Valószínűleg az write:readarány 7:3. Ez nagy nyomást gyakorol a meglévő adatbázisokra. A locationtáblázatok néhány elsődleges adatok, mint a longitude, latitude, timestamp, driver id, trip idstb nincs sok köze a felhasználói utak, a felhasználói adatok, a fizetési adatokat, stb Mi van elválasztva a locationtáblákat külön adatbázis séma? Mi a helyzet az adatbázis külön, megfelelő primary-replicavagy multi-primarykonfigurációjú gépekbe helyezésével ?

Ezt hívjuk az adatok funkcionalitás szerinti felosztásának. Különböző adatbázisok különböző funkciók szerint kategorizált adatokat tárolhatnak, ha szükséges, az eredmény összesíthető a háttérrétegben. Ezzel a technikával koncentrálhat azoknak a funkcióknak a méretezésére, amelyek nagy read/writeigényeket támasztanak . Bár a háttérnek vagy az alkalmazási rétegnek felelősséget kell vállalnia az eredmények egyesítéséért, ha szükséges, ez valószínűleg több kódváltozást eredményez.

Most képzelje el, hogy országának 20 városára bővítette vállalkozását, és hamarosan Ausztráliába kíván terjeszkedni. Az egyre növekvő alkalmazásigény egyre gyorsabb választ igényel. A fenti módszerek egyike sem segíthet a végletekig. A rendszert úgy kell méreteznie, hogy a más országokba / régiókba történő terjeszkedéshez ne mindig legyen szükség arra, hogy gyakran végezzen mérnöki vagy építészeti változtatásokat. Hogyan csinálod, hogy?

6. minta - Vízszintes méretezés:

Sokat guglizol, sokat olvasol arról, hogy más cégek hogyan oldották meg a problémát - és arra a következtetésre jutsz, hogy vízszintesen kell méretezned. Mondjon el 50 gépet - mindegyiknek ugyanaz az adatbázis-sémája, amely viszont ugyanazt a táblázatot tartalmazza. Az összes gép csak az adatok egy részét tárolja.

Mivel minden adatbázis ugyanazt a táblázatot tartalmazza, megtervezheti a rendszert úgy, hogy az adatok helye ott legyen, azaz; az összes kapcsolódó adat ugyanabban a gépben landol. Minden gépnek megvan a saját mása, a másolatok felhasználhatók a hiba helyreállításához. Mindegyik adatbázist meghívják shard. Egy fizikai gépnek lehet egy vagy több shards- a tervezésén múlik, ahogyan szeretné. Úgy kell döntenie, sharding keyhogy sharding keymindig egyetlen ugyanazon gépre utal. Tehát el lehet képzelni, hogy sok gép tárol kapcsolódó adatokat ugyanazokban a táblákban, read/writeugyanahhoz a sorhoz vagy ugyanahhoz az erőforráshoz tartozó földterülethez ugyanazon adatbázis-gépen.

A szilánkosítás általában nehéz - ezt legalábbis a különböző cégek mérnökei mondják. De amikor milliókat vagy milliárd kéréseket teljesít, akkor ilyen kemény döntést kell hoznia.

shardingA következő bejegyzésemben részletesebben tárgyalok , így visszafogva a kísértésemet, hogy többet beszéljek ebben a bejegyzésben.

Most, hogy szilánkok vannak a helyén, bízik abban, hogy számos országra képes méretezni. Vállalkozása annyira megnőtt, hogy a befektetők arra ösztönzik Önt, hogy az üzletet kontinenseken át terjessze. Itt megint lát valami problémát. Ismét API késés. Szolgáltatását az Egyesült Államokban üzemeltetik, és vietnami emberek nehezen utaznak könyvekkel. Miért? Mit csinál ez ellen?

7. minta - Adatközpont bölcs partíció:

Vállalkozása növekszik Amerikában, Dél-Ázsiában és kevés európai országban. Naponta több millió foglalást hajt végre, milliárdnyi kéréssel a szerverén. Gratulálunk - ez a vállalkozás csúcspontja.

De mivel az alkalmazás kéréseinek az internet több száz vagy ezer szerverén keresztül kell áthaladniuk a kontinenseken, felmerül a késés. Mi van a forgalom adatközpontok közötti elosztásával? Beállíthat egy adatközpontot Szingapúrban, amely kezeli az összes dél-ázsiai kérést, a németországi adatközpont képes kezelni az összes európai országból érkező kérést, egy kaliforniai adatközpont pedig az USA összes kérését.

Ezenkívül engedélyezi az adatközpontok közötti replikációt, amely segíti a katasztrófa utáni helyreállítást. Tehát, ha a kaliforniai adatközpont replikál a szingapúri adatközpontba, abban az esetben, ha a kaliforniai adatközpont áramütés vagy természetes csapás miatt összeomlik, az összes USA-kérelem visszaeshet a szingapúri adatközpontba és így tovább.

Ez a méretezési technika akkor hasznos, ha ügyfeleinek millióit kell kiszolgálnia országszerte, és nem tud eleget tenni az adatvesztésnek, mindig fenntartania kell a rendszer rendelkezésre állását.

Ezek néhány általános lépésenkénti technika az adatbázis méretezéséhez. Bár a mérnökök többségének nincs elegendő esélye ezeknek a technikáknak a megvalósítására, de összességében jobb, ha szélesebb körű képet kapunk egy ilyen rendszerről, amely a jövőben segíthet jobb rendszer- és architektúra-tervezésben.

Következő cikkeimben megpróbálok néhány fogalmat részletesen megvitatni. Kérjük, bátran adjon megfelelő visszajelzést ehhez a bejegyzéshez, ha van ilyen.

A cikk eredetileg a szerző közegében található: //medium.com/@kousiknath/understanding-database-scaling-patterns-ac24e5223522