Adatbázis-tervezés: Konzisztencia és a CAP-tétel

Befejeződött

Replikáció nélkül a konzisztencia nem jelent problémát. A replikáció keretében több gép is több példányát (replikáit) is megőrzi az adatoknak, míg a konzisztencia rendszerszintű áttekintést és állapotadatokat nyújt a replikákról több ügyfélen/folyamaton is. Ahogyan korábban már említettük, az adatreplikációnak két elsődleges oka van: a teljesítmény és a megbízhatóság. A replikáció elengedhetetlen a teljesítményhez, ha a rendszernek a mennyiség (például a privát és nyilvános felhők tárolói) és a földrajzi hely (például a nyilvános felhők tárolói) tekintetében is nőnie kell. Ha például egyre több folyamatnak kell hozzáférnie az egyetlen tárolási kiszolgáló által kezelt adatokhoz, a teljesítmény növelhető az adatok több kiszolgálón való replikálásával (egyetlen kiszolgáló helyett), majd kiszolgálók közti munkamegosztással. Ezzel a felosztással a kérések egyidejűleg kiszolgálhatók, ami növeli a rendszer sebességét. Ezzel szemben a különböző földrajzi területeken való replikálás (amelyet az Azure is alkalmaz) az adatok a kérési folyamat közelében való replikációjával valósítható meg, ami minimalizálja az adatelérési időt. A replikációval jobb hibatűrést nyújthat sérült és elveszett adatok esetén, ami kulcsfontosságú követelmény felhőkörnyezetekben. Ha egy replika elvész vagy megsérül, egy másik replika a helyébe léphet (amennyiben rendelkezésre áll ilyen).

A replikáció több adatreplikát hoz létre, a konzisztencia pedig gondoskodik arról, hogy ezek a replikák egységesek maradjanak, így különböző folyamatok (például az olvasás és az írás) is elérhetik őket. Egy gyűjtemény replikáit akkor tekintjük konzisztensnek, ha az egyidejűleg hozzájuk férő folyamatok azonosnak tekintik őket. A replikákon elvégzett egyidejű műveletek kezelésének képessége a konzisztencia megtartásával alapvető fontosságú az elosztott tároláshoz és a felhőalapú tároláshoz. Ebben az egységben a konzisztenciát egy elosztott adattár megosztott replikáin végzett olvasási és írási műveletek kontextusában kell értelmezni (lásd a 13. ábrát). Az elosztott adattár lehet DFS, párhuzamos fájlrendszer vagy elosztott adatbázis. A konzisztencia egy konzisztenciamodell alkalmazásával valósítható meg. A konzisztenciamodellre a folyamatok és az elosztott adattár közti szerződésként tekintünk. Ez a definíció azt is magával vonja, hogy ha a folyamatok betartanak bizonyos szabályokat, az elosztott adattár kényszeríti azokat. Az alábbi videó több konzisztenciamodellt is bemutat.

Ebben az egységben három konzisztenciamodellt ismertetünk részletesen: szekvenciális konzisztencia, okozati konzisztencia és végleges konzisztencia.

A distributed data store that can be a distributed file system, a parallel file system, or a distributed database with replicas maintained across distributed storage disks.

13. ábra: Elosztott adattár, amely lehet elosztott fájlrendszer, párhuzamos fájlrendszer vagy elosztott adatbázis az elosztott tárolólemezeken fenntartott replikákkal

Szekvenciális konzisztencia

A más néven erős vagy szigorú konzisztenciának nevezett szekvenciális konzisztencia azonnal továbbítja a frissítéseket az összes replikához. Ehhez általában egyetlen elemi műveletben vagy tranzakcióban kell alkalmazni a frissítéseket a kapcsolódó replikákon. Az atomitás megvalósítása egy nagyméretű, elosztott adattár széles körben elosztott replikáin a gyakorlatban rendkívül nehéz, különösen, ha a frissítéseket gyorsan kell elvégezni. A nehézség abból fakad, hogy a mögöttes tárhálózat kiszámíthatatlan hozzáférési késéseket idéz elő, illetve a rendszer nem rendelkezik globális órával, amellyel gyorsan és pontosan rendezhetők a műveletek. A probléma megoldása érdekében lazíthatunk a frissítések elemi műveletként való végrehajtásának követelményén. A konzisztenciakövetelmények lazítása miatt nem kell mindig azonosnak lenniük a replikáknak minden helyen. Az, hogy a konzisztencia lazítása elfogadható-e, az elosztott adattáron futó alkalmazástól függ. A konzisztenciakövetelmények lazítása az alkalmazás olvasási és írási hozzáférési mintáitól függ, valamint a replikák felhasználási céljától. Például a böngészők és webproxyk gyakran úgy vannak konfigurálva, hogy weblapokat tároljanak a helyi gyorsítótárakban (ez egy replikációs típus, mivel a rendszer több példányt megőriz egyetlen weblaphoz), így csökkentve az elérési időt. Bizonyos esetekben elfogadható, ha a felhasználók nem naprakész weblapokat látnak, mindaddig, amíg azok a webkiszolgálókon rövidesen a legfrissebb verzióra lesznek frissítve. A végleges konzisztencia példaként szolgál az ilyen forgatókönyveknek megfelelő modellekhez.

(a) A sequentially consistent distributed data store, and (b) a nonsequentially consistent distributed data store.

14. ábra: (a) Egy szekvenciálisan konzisztens elosztott adattár, és (b) egy nem szekvenciálisan konzisztens elosztott adattár

Egy elosztott adattárat akkor tekintünk szekvenciálisan konzisztensnek, ha minden folyamat ugyanazokat az olvasási és írási műveleteket látja a replikák egyidejű elérésekor. A 14. ábrán két elosztott adattár látható: egy szekvenciálisan konzisztens elosztott adattár (14.(a) ábra) és egy nem szekvenciálisan konzisztens elosztott adattár (14.(b) ábra). A W(x)a és az R(x)b szimbólumok egy a írási értéket jeleznek az x replikához, és egy b olvasási értéket az x replikától. Az ábrán négy folyamat látható, amelyek az x adatelem replikáinak műveleteit jelzik. A 14.(a) ábrán a P1 folyamat az a értéket írja az x-be, majd később (abszolút időben mérve) a P2 folyamat a b értéket írja az x-be. Ezt követően a P3 és a P4 folyamat először a b, majd később az a értéket kapja meg az x beolvasásakor. A P2 folyamat által elvégzett írási művelet így látszólag a P1, P3 és P4 műveletek előtt ment végbe. A 14.(a) ábrán ettől függetlenül továbbra is egy szekvenciálisan konzisztens elosztott adattár látható, mivel a P3 és P4 folyamat ugyanazokat az összefűzött műveleteket alkalmazza (tehát először a b, majd az a értéket olvassa be). Ezzel szemben a 14.(b) ábra P3 és P4 folyamata eltérő összefűzött műveleteket alkalmaz, így megszegik a szekvenciális konzisztencia feltételét.

Okozati konzisztencia

Az okozati konzisztenciamodell a szekvenciális konzisztenciamodell egy gyengébb változata. Az okozat elsőként feltételezi, hogy ha a b műveletet egy korábbi a művelet okozta vagy befolyásolta, akkor az elosztott adattárhoz hozzáférő összes folyamatnak először az a, majd a b műveletet kell látnia. Egy okozati konzisztenciával rendelkező elosztott adattár csak a potenciálisan okozati kapcsolattal rendelkező műveleteken kényszeríti a konzisztenciát. A nem potenciálisan okozati kapcsolatban lévő műveletek bármilyen összefűzési műveletben megjelenhetnek, és egyidejű műveletként vannak számon tartva. A 15. ábrán két okozati konzisztenciával rendelkező elosztott adattár látható (15.(a) és 15.(c)), valamint egy nem okozati konzisztenciával rendelkező elosztott adattár (15.(b)). A 15.(a) ábrán a P2 folyamat által elvégzett W(x)b potenciálisan a P1 folyamat által elvégzett W(x)a művelettől függ, mivel lehetséges, hogy b egy a-t tartalmazó, a P2 folyamat által beolvasott számítás eredménye (azaz R(x)a) a b írása előtt (azaz W(x)b). A P1 és P2 által végrehajtott W(x)a és W(x)b írási műveletek eredményeinek így az olvasási folyamattal megegyező sorrendben kell megjelenniük. Mivel a P3 és P4 folyamat először az a, majd a b értéket olvassák be, megfelelnek az okozati feltételnek, a mögöttes elosztott adattár így okozati konzisztenciával bír. Ezzel szemben a 15.(b) ábra P3 folyamata nem felel meg az okozati feltételnek (amely szerint először a b, majd az a értéket kellene beolvasnia), a mögöttes elosztott adattár így nem rendelkezik okozati konzisztenciával. A 15.(c) ábrán egy okozati konzisztenciával bíró elosztott adattár látható, mivel a W(x)a és a W(x)b egyidejű műveletek, az eredményeik (azaz R(x)a és R(x)b) így bármilyen sorrendben megjelenhetnek az olvasási folyamatokban, ami a P3 és P4 folyamatban meg is történik.

(a) A causally consistent distributed data store, (b) a noncausally consistent distributed data store, and (c) a causally consistent distributed data store.

15. ábra: (a) Egy okozati konzisztenciával rendelkező elosztott adattár, (b) egy okozati konzisztenciával nem rendelkező elosztott adattár, és (c) egy okozati konzisztenciával rendelkező elosztott adattár

Végleges konzisztencia

A végleges konzisztenciamodell a szekvenciális és az okozati konzisztenciamodellek egy gyengébb formája. A végleges konzisztencia feltételezi, hogy egy replikán végzett írásnak nem kell azonnal minden más replikára propagálva lennie, és akár késleltethető is (vagy teljesen elhagyható), ha ezt az alkalmazások lehetővé teszik. Pontosabban, ha egy folyamat P egy bizonyos replikához fér hozzá, az R, $N$ percenként, és az R percenként $M$ alkalommal frissül, akkor ha egy alkalmazás alacsony olvasási-írási arányt mutat (például $N << M$), a replika számos frissítését soha nem éri el A P, így az összes frissítést és a szükséges hálózati kommunikációt értelmetlenné teszi. Ebben az esetben hatékonyabb lehet egy gyenge konzisztenciamodellt alkalmazni, amelyben az R csak akkor frissül, ha P hozzáfér. Hatékonyabb tehát lazán propagálni a frissítést, így az olvasási folyamat csak jóval annak végbemenése után látja a frissítést (nem pedig azonnal, ahogy egy szigorú konzisztenciamodellben történne). Ha ritkán vagy soha nem fordul elő ütközés két olyan művelet miatt, amely azonos adatokra próbál írni (írás-írás ütközés), a frissítések propagálása nyugodtan késleltethető. A végleges konzisztenciát alkalmazó adatbázisrendszerekben ritkán fordulnak elő ütközések. Az adatbázisrendszerekkel részletesen a következő szakaszban foglalkozunk. A konzisztenciamodelleket itt nem ismertettük teljes mértékben. Az implementálásukkal egy másik szakasz foglalkozik. Ebben az egységben csak a modellek tulajdonságaival, illetve azok felhőbeli tárrendszerekben való alkalmazhatóságával foglalkozunk. Röviden megjegyezzük azonban, hogy a szekvenciális konzisztencia nehezen megvalósítható a gyakorlatban, mivel csak kis mértékben méretezhető. A szekvenciális konzisztenciához általában szinkronizálási mechanizmusokra van szükség, például tranzakciókra és zárolásokra. Ezzel szemben az okozati konzisztencia megvalósításához egy függőségi gráf létrehozása szükséges, amely rögzíti az okozati viszonyban lévő műveleteket, és kikényszeríti őket a hozzáférési folyamatokban. Egy ilyen modell vektoros időbélyegekkel valósítható meg. A végleges konzisztencia olvasási és írási műveletek munkamenetekbe való csoportosításával és vektoros időbélyegek használatával valósítható meg.

ACID-tulajdonságok az adatbázisokban

Az adatbázisok tranzakciós tulajdonságokat nyújthatnak. Egy tranzakció egy adatbázis-kezelő (vagy hasonló) rendszerben elvégzett munkaegységből áll. A tranzakciók kezelése következetes és megbízható módon történik, a többi tranzakciótól függetlenül. Egy adatbázis-környezet tranzakcióinak két fő célja van:

  • Olyan megbízható munkaegységeket nyújtani, amelyek lehetővé teszik a hibákból való helyreállást, és megőrzik az adatbázis konzisztenciáját rendszerhibák és (részleges vagy teljes) végrehajtási leállások, valamint nem egyértelmű állapottal, elvégzetlenül maradt adatbázis-műveletek esetén is.
  • Elkülönítést biztosítani egy adatbázishoz egyidejűleg hozzáférő programoknak. Ha az elkülönítés nem valósul meg, a program eredményei valószínűleg hibásak lesznek.

Az adatbázis tranzakcióinak szükségességének jobb megértéséhez vegye figyelembe a következő pénzügyi tranzakciót, amelyet két bankszámlán hajtottak végre: A és B. Tegyük fel, hogy egy felhasználó 100 usd-t szeretne átutalni az A fiókból a B számlára. Ez az átvitel két lépésben jeleníthető meg:

  1. 100 USD levonása az A fiókból.
  2. 100 usd jóváírás a B fiókhoz.

Tegyük fel, hogy az adatbázis hibája az 1. és a 2. művelet között következik be: 100 usd lett volna levonva az A fiókból, de a B fiók jóváírása nem történt volna meg. Ekkor a számlák és maga az adatbázis is inkonzisztens állapotban van.

A probléma megoldásához a műveletek tranzakcióként definiálhatók az alábbi módon:

  1. Tranzakció elindítása.
  2. 100 USD levonása az A fiókból.
  3. 100 usd jóváírás a B fiókhoz.
  4. Tranzakció befejezése.

Innentől az adatbázis feladata, hogy biztosítsa a tranzakció atomitását, azaz hogy az vagy teljes mértékben sikeres (véglegesített) legyen, vagy egyáltalán ne menjen végbe (visszaállítás). A tranzakció befejezése után az adatbázisnak konzisztensnek kell lennie. Ez azt jelenti, hogy az adatbázis állapotának érvényesnek kell lennie a tranzakció véglegesítése után, és az adatbázisban lévő rekordokhoz meghatározott szabályok nincsenek megszegve (egy megtakarítási számla például nem rendelkezhet negatív egyenleggel). A számlákon egyidejűleg elvégzett tranzakciók nem befolyásolhatják egymást; ez biztosítja az elkülönítést. A tranzakciónak végezetük tartósnakkell lennie, ami azt jelenti, hogy a tranzakcióban végrehajtott műveleteknek meg kell maradniuk a tranzakció az adatbázisban való véglegesítése után. Az atomitás, konzisztencia, elkülönítés és tartósság tulajdonságait együttesen a tranzakciók ACID-tulajdonságainak nevezzük, amelyeket a legtöbb tranzakciófeldolgozási RDBMS-nek be kell tartania. Az alábbi videó áttekintést nyújt az adatbázisok ACID-tulajdonságairól:

  • Atomi: A tranzakció oszthatatlan – vagy a tranzakció összes utasítása az adatbázisra lesz alkalmazva, vagy egyik sem.
  • Konzisztens: Az adatbázis konzisztens állapotban marad a tranzakció végrehajtása előtt és után.
  • Izolált: Bár egy vagy több felhasználó egyszerre több tranzakciót is végrehajthat, az egyik tranzakció nem látja a többi egyidejű tranzakció hatását.
  • Tartós: Ha a tranzakciót az adatbázisba menti (az adatbázis-programozási parlance-ban véglegesítésként említett művelet), a módosítások várhatóan megmaradnak.

Miért nem lehet minden: A CAP tétel

1999-ben Brewer1 megfogalmazott egy tételt, amely az elosztott adattárolás korlátozásait ismerteti: ez a CAP-tétel. A CAP-tétel szerint minden, megosztott adatokat tartalmazó elosztott tárrendszer legfeljebb kettő vagy három kívánt tulajdonsággal rendelkezhet:

  • Konzisztencia: A konzisztencia olyan állapot, amelyben minden csomópont mindig ugyanazokat az adatokat látja egy adott pillanatban (szigorú konzisztencia).
  • Rendelkezésre állás: Az a garancia, hogy minden kérés választ kap arról, hogy sikeres vagy sikertelen volt-e, rendelkezésre állási garancia.
  • Partíciótűrés: A hálózati partíció olyan feltétel, amelyben egy elosztott rendszer csomópontjai nem tudnak egymással kapcsolatba lépni. A partíciótolerancia azt jelenti, hogy a rendszer egy üzenetvesztés vagy részleges rendszerhiba esetén is folytatja a normál működést.

Az alábbi videó áttekintést nyújt a CAP-tételről:

A CAP megértésének legkönnyebb módja, ha elképzeli egy elosztott tárrendszer két csomópontját, amelyek egy hálózati partíció két ellentétes oldalán helyezkednek el. Ha engedélyezi legalább egy csomópontnak, hogy frissítse az állapotot, a csomópontok inkonzisztenssé válnak, így megszegik a C feltételt. Hasonlóképp, ha meg szeretné őrizni a konzisztenciát, a partíció egyik oldalának elérhetetlenként kell megjelennie, ami az A feltétel megszegése. Csak a csomópontok kommunikációjával őrizhető meg együtt a konzisztencia és a rendelkezésre állás, ami a P feltétel megszegését jelenti.

Vegyük az alábbi hagyományos, egycsomópontos RDBMS esetét példaként. Ebben a forgatókönyvben garantálható a konzisztencia és a rendelkezésre állás, a partíciótolerancia fogalma pedig nem alkalmazható, mivel az adatbázis egyetlen csomóponton található.

Amikor az olyan cégek, mint a Microsoft, nagyméretű adatbázisokat terveztek több millió ügyfél kiszolgálásához, kulcsfontosságú volt a folyamatos rendelkezésre állás, és még néhány percnyi leállás is bevételvesztést jelentett. Elosztott, megosztott adatokat tartalmazó adatrendszerek több száz vagy több ezer géphez való méretezésekor jelentősen megnő annak az esélye, hogy egy vagy több csomóponton (így létrehozva egy hálózati partíciót) hiba történik. A CAP-tétel szerint tehát ha erős garanciát szeretnénk a rendelkezésre állás és a partíciótolerancia terén, a nagyméretű, nagy teljesítményű elosztott adatbázisok esetén le kell mondanunk a szigorú konzisztenciáról.

CAP theorem illustrated.

16. ábra: A CAP-tétel illusztrált


Hivatkozások

  1. Eric Brewer (2000). Az elosztott számítástechnika alapelveiről szóló éves ACM-szimpózium robusztus elosztott rendszerekre vonatkozó eljárása felé

Tesztelje tudását

1.

Tegyük fel, hogy egy banki ügyfele 1000 USD-t utal át egy másik ügyfél számlájára, és a műveletről egy sikeres tranzakciót jelző üzenetet kap. Öt perccel később a másik ügyfél megtekinti az online számláját, ahol nem jelenik meg a tranzakció. Az ACID-tulajdonságok közül melyiket sérti a legnyilvánvalóbban ez a tranzakció?