Sziasztok. Vladislav Rodin felveszi a kapcsolatot. Jelenleg a Szoftverarchitektúra és a High-Stress Software Architecture témakörben tartok kurzusokat az OTUS-ban. Egy új tanfolyam kezdetére számítva
Bevezetés
Tekintettel arra, hogy a merevlemez másodpercenként csak körülbelül 400-700 műveletet tud végrehajtani (ami összehasonlíthatatlan a nagy terhelésű rendszerek tipikus rps-jével), a klasszikus lemezes adatbázis az architektúra szűk keresztmetszete. Ezért különös figyelmet kell fordítani ennek a tárolónak a méretezési mintáira.
Jelenleg 2 adatbázis-méretezési minta létezik: replikáció és felosztás. A megosztás lehetővé teszi az írási művelet méretezését, és ennek eredményeként a fürtben az írásonkénti rps csökkentését. A replikáció lehetővé teszi ugyanezt, de olvasási műveletekkel. Ennek a mintának szenteljük ezt a cikket.
Replikáció
Ha nagyon magas szinten nézzük a replikációt, akkor ez egy egyszerű dolog: volt egy szerverünk, azon voltak adatok, és akkor ez a szerver már nem tudta megbirkózni az adatok olvasásával járó terheléssel. Hozzáad még néhány kiszolgálót, szinkronizálja az adatokat az összes kiszolgálón, és a felhasználó a fürt bármely kiszolgálójáról olvashat.
Látszólagos egyszerűsége ellenére számos lehetőség kínálkozik a séma különféle megvalósításainak osztályozására:
- A fürtben betöltött szerepek szerint (mester-mester vagy mester-szolga)
- Elküldött objektumok szerint (soralapú, utasításalapú vagy vegyes)
- A csomópont-szinkronizációs mechanizmus szerint
Ma a 3. ponttal fogunk foglalkozni.
Hogyan történik a tranzakciós kötelezettségvállalás?
Ez a téma nem kapcsolódik közvetlenül a replikációhoz, külön cikk írható róla, de mivel a további olvasás hiábavaló a tranzakció véglegesítési mechanizmusának megértése nélkül, hadd emlékeztesselek a legalapvetőbb dolgokra. A tranzakciós kötelezettségvállalás 3 szakaszban történik:
- Tranzakció naplózása az adatbázisnaplóba.
- Tranzakció használata adatbázismotorban.
- A tranzakció sikeres alkalmazásáról szóló visszaigazolás visszaküldése az ügyfélnek.
Különböző adatbázisokban ennek az algoritmusnak árnyalatai lehetnek: például a MySQL adatbázis InnoDB motorjában 2 napló található: az egyik a replikációhoz (bináris napló), a másik az ACID karbantartásához (visszavonás/újrakészítés napló), míg a PostgreSQL-ben van egy napló, amely mindkét funkciót végrehajtja (napló írása előre = WAL). De amit fent bemutatunk, az pontosan az általános koncepció, amely lehetővé teszi az ilyen árnyalatok figyelmen kívül hagyását.
Szinkron (szinkron) replikáció
Adjunk hozzá logikát a tranzakció-végrehajtási algoritmus kapott módosításainak replikálásához:
- Tranzakció naplózása az adatbázisnaplóba.
- Tranzakció használata adatbázismotorban.
- Adatok küldése az összes replikához.
- Az összes replikától visszaigazolást kap arról, hogy egy tranzakció befejeződött rajtuk.
- A tranzakció sikeres alkalmazásáról szóló visszaigazolás visszaküldése az ügyfélnek.
Ezzel a megközelítéssel számos hátrányt kapunk:
- a kliens megvárja, amíg a változtatások alkalmazásra kerülnek az összes replikára.
- a csomópontok számának növekedésével a fürtben csökkentjük annak valószínűségét, hogy az írási művelet sikeres lesz.
Ha az 1. ponttal nagyjából minden világos, akkor a 2. pont okait érdemes elmagyarázni. Ha a szinkron replikáció során nem kapunk választ legalább egy csomóponttól, akkor visszagörgetjük a tranzakciót. Így a fürtben lévő csomópontok számának növelésével megnő annak a valószínűsége, hogy egy írási művelet meghiúsul.
Várhatunk-e megerősítést a csomópontok csak bizonyos százalékától, például 51%-tól (kvórum)? Igen, megtehetjük, de a klasszikus verzióban minden csomópontból megerősítés szükséges, mert így biztosíthatjuk a teljes adatkonzisztenciát a fürtben, ami kétségtelen előnye az ilyen típusú replikációnak.
Aszinkron (aszinkron) replikáció
Módosítsuk az előző algoritmust. A replikákhoz „valamikor később” küldünk adatokat, és „valamikor később” a módosítások a replikákra vonatkoznak:
- Tranzakció naplózása az adatbázisnaplóba.
- Tranzakció használata adatbázismotorban.
- A tranzakció sikeres alkalmazásáról szóló visszaigazolás visszaküldése az ügyfélnek.
- Adatok küldése replikákba és módosítások alkalmazása rajtuk.
Ez a megközelítés oda vezet, hogy a fürt gyorsan működik, mert nem várjuk meg a klienst, hogy az adatok elérjék a replikákat, és akár véglegesítsék is.
De az a feltétel, hogy az adatokat „valamikor később” másolják a replikákba, egy tranzakció elvesztéséhez, illetve a felhasználó által visszaigazolt tranzakció elvesztéséhez vezethet, mert ha az adatoknak nem volt ideje replikálni, visszaigazolást kap az ügyfélnek. a művelet sikerességéről elküldték, és a csomópont, amelyre a változtatások érkeztek, lefagyott a HDD, elveszítjük a tranzakciót, ami nagyon kellemetlen következményekkel járhat.
Félszinkron replikáció
Végül eljutunk a félszinkron replikációhoz. Ez a fajta replikáció nem túl ismert vagy nagyon elterjedt, de jelentős érdeklődésre tarthat számot, mivel kombinálhatja a szinkron és az aszinkron replikáció előnyeit.
Próbáljuk meg kombinálni az előző 2 megközelítést. Nem őrizzük meg sokáig az ügyfelet, de megköveteljük az adatok sokszorosítását:
- Tranzakció naplózása az adatbázisnaplóba.
- Tranzakció használata adatbázismotorban.
- Adatok küldése replikákba.
- Megerősítést kap a replikától, hogy a változtatások megérkeztek (a változtatásokat „valamikor később” alkalmazzák).
- A tranzakció sikeres alkalmazásáról szóló visszaigazolás visszaküldése az ügyfélnek.
Kérjük, vegye figyelembe, hogy ezzel az algoritmussal a tranzakciók elvesztése csak akkor következik be, ha a változásokat fogadó csomópont és a replika csomópont is meghiúsul. Az ilyen meghibásodás valószínűsége alacsonynak tekinthető, és ezeket a kockázatokat elfogadjuk.
Ezzel a megközelítéssel azonban fennáll a fantomolvasás veszélye. Képzeljük el a következő forgatókönyvet: a 4. lépésben egyetlen replikától sem kaptunk megerősítést. Vissza kell vonnunk ezt a tranzakciót, és nem kell visszaigazolást visszaküldenünk az ügyfélnek. Mivel az adatok a 2. lépésben kerültek alkalmazásra, a 2. lépés vége és a tranzakció visszagörgetése között van egy időrés, amely során a párhuzamos tranzakciók olyan változásokat láthatnak, amelyeknek nem kellene szerepelniük az adatbázisban.
Veszteségmentes félszinkron replikáció
Ha egy kicsit gondolkodik, megfordíthatja az algoritmus lépéseit, és kijavíthatja a fantomolvasás problémáját ebben a forgatókönyvben:
- Tranzakció naplózása az adatbázisnaplóba.
- Replikaadatok küldése.
- Megerősítést kap a replikától, hogy a változtatások megérkeztek (a változtatásokat „valamikor később” alkalmazzák).
- Tranzakció használata adatbázismotorban.
- A tranzakció sikeres alkalmazásáról szóló visszaigazolás visszaküldése az ügyfélnek.
Most már csak akkor hajtjuk végre a változtatásokat, ha azokat megismételtük.
Teljesítmény
Mint mindig, most sem léteznek ideális megoldások, vannak megoldások, amelyek mindegyikének megvannak a maga előnyei és hátrányai, és különböző típusú problémák megoldására alkalmas. Ez teljesen igaz a replikált adatbázisban lévő adatok szinkronizálására szolgáló mechanizmus kiválasztására. A félszinkron replikáció előnyei kellően szilárd és érdekesek ahhoz, hogy alacsony elterjedtsége ellenére is figyelmet érdemeljenek.