2009. február 9., hétfő

Memóriarezidens adatbázis-kezelő

A memóriarezidens adatbázis-kezelők (Main Memory Database System - MMDS) bemutatására a legjobb módszer, ha a tulajdonságait a diszk rezidens, „hagyományos” adatbázis-kezelőkéhez (Disk Resident Database System - DRDB) hasonlítjuk, mert így válnak egyértelművé azok a képességek, melyek jellemzik ezeket a rendszereket.

Első közelítésben azt gondolhatnánk, hogy egy memória-adatbázis és egy diszk rezidens adatbázis között csak annyi a különbség, hogy az előbbi az adatokat a memóriában tartja, míg utóbbi a háttértáron. Ahhoz azonban, hogy a különbséget a kettő működése között ténylegesen megértsük, mélyebbre kell ásnunk. A két rendszer sajátosságait alapvetően a kétféle adattároló médium tulajdonságai határozzák meg, ezért ezek ismerete elengedhetetlen a működés megértéséhez.

A memória és a merevlemez különböző tulajdonságokkal rendelkezik mind az adattárolás, mind az adatok hozzáférése terén.

· A memória kikapcsolás után elfelejti tartalmát, a lemez nem.

· A memóriához való hozzáférési idő legalább egy nagyságrenddel rövidebb, mint a merevlemezé, ami teljesítmény kritikus rendszerek esetében fontos tulajdonság.

· A háttértár blokkszervezésű, ami a működéséből adódik, míg a memória direkt hozzáférésű. Éppen ezért a memória minden egyes megcímezhető egységnyi tartományát ugyan annyi idő alatt érhetjük el, míg a lemez alapú tárolás esetében ez az idő változó, ráadásul még egyazon blokk esetében sem tekinthető állandónak.

· A merevlemezen tárolt adatok szervezése fontos, mivel a lemez szekvenciális hozzáférés esetén jobb átlagos teljesítményre képes, mint véletlen hozzáférés esetén. A memóriában nem annyira fontos az adatok elrendezése a teljesítmény szempontjából.

· A processzor a memóriában lévő adatokhoz közvetlenül hozzá tud férni, míg a merevlemezen tárolt adatokhoz nem. Emiatt a memória-adatbázisban lévő adatok sérülékenyebbek ebből a szempontból.

Ezek a tulajdonságok alakították ki a memóriarezidens adatbázis-kezelő rendszer felépítését és működését. [1]

Az alábbiakban bemutatom, hogy egy memóriarezidens adatbázis-kezelő hogyan teljesíti egy adatbázis-kezelő jellemző funkcionális feladatait:

Konkurens adathozzáférés - Zárkezelés ugyanúgy megvalósítható, mint a diszkrezidens adatbázis-kezelő rendszerek esetében, azonban erre nem minden esetben van szükség. Mivel a memóriában sokkal gyorsabban férhetünk az adatokhoz mintha merevlemezen tárolnánk őket, ezért az egyes műveletek is rövidebb ideig tartanak . Ez pedig azt jelenti, hogy a konkurens műveleteknek a valószínűsége is kisebb. Ebben az esetben megfontolandó a műveletek szekvenciális végrehajtása, mert a zárkezelés megvalósítása egy ilyen rendszerben jelentős overhead-et jelent.

Commit kezelés, tranzakciós naplózás - Mivel a memória sérülékeny, rendszerhiba esetén az adatok elveszhetnek. Ennek elkerülésére a tranzakciós műveleteket naplózni (tranzakciós log) kell és ezt a naplót olyan helyen tárolni, ahol védve van egy kritikus rendszerleállástól. A tároló média elsősorban merevlemez lehet, ami azt jelenti, hogy a költséges I/O műveletek teljes egészében nem eliminálhatóak egy memóriarezidens adatbázis rendszerből. Minden egyes commit előtt a változásokat ki kell írni a log (napló) fájlba.
Alternatív megoldásként szóba jöhet egy olyan architektúra, ahol a napló legfrissebb részét egy nem felejtő, kis kapacitású memóriában tároljuk. Onnan pedig egy független folyamat rendszeresen átmozgatja a bejegyzéseket a merevlemezen tárolt végleges log fájlba. A funkcionalitás mit sem változott, a tranzakciónak azonban sokkal kevesebbet kell a naplózás miatt várnia.

Adathozzáférés - A keresett rekordok megtalálásához az adatbázis-kezelő rendszerek indexelési technikát használnak. Diszkrezidens adatbázisokban B-fa indexet használnak, mert ez az indexelési eljárás a legmegfelelőbb a merevlemez adattárolási struktúrájához. Ez azonban a memóriában való kereséshez nem a legoptimálisabb. A T-fa kifejezetten a memória-adatbáziskezelők részére lett kifejlesztve. A legjobb megoldás azonban arra, hogy egy rekordot megtaláljunk a memóriában, hash táblák használata. Ezzel azonban intervallumkeresés nem hajtható végre. [2]

Adatkezelés - Minden egyes adatnak az adatbázisban van egy memóriacíme, mely a memória egy területére mutat. Ezzel könnyen lehet kezelni akár változó méretű mezőket is, mert egy rekordot a memóriában egy pointer gyűjtemény reprezentál. Ha egy táblának kicsi a kardinalitása, akkor az azonos értékeket csak egyszer kell tárolnunk, és elegendő csak erre a címre hivatkozni az érintett rekordoknak. Ez nagy adatméret esetén rendkívül hatékony adattárolást jelent.

Lekérdezés optimalizálás - A diszkrezidens adatbázis-kezelők lekérdezés optimalizálója a költséges I/O műveletek minimalizálását tartja elsődlegesen szem előtt. Ehhez költség alapú elemzéseket végez, mielőtt kiválasztani azt a végrehajtási tervet, mely a legrövidebb végrehajtási idővel kecsegtet. A memória-adatbáziskezelőkben ez a stratégia nem biztos, hogy a legjobb megoldást adja, mivel a legnagyobb költséget nem feltétlenül az adatok elérése jelenti. Sokkal inkább az egyes műveletek számítási ideje. Éppen ezért érdemes ezeket a műveleteket a lehető legjobban csökkenteni, úgymint indexek építése, felesleges adatmásolatok készítése. A lekérdezések optimalizálása ezért memória-adatbázisokban javarészt rendszerfüggő.

Helyreállítás kezelés - A biztonsági mentés és helyreállítás ugyanúgy működik, mint egy hagyományos adatbázis-kezelő rendszer esetében. A rendszer működéséről teljes mentést készíthetünk, amit a merevlemezen tárolunk. Ha ezt a tranzakciós naplózással kombináljuk, akkor egy teljesen megbízható rendszert kapunk, mert kritikus rendszerhiba esetén a memória tartalma törlődhet ugyan, de a biztonsági menésként tárolt checkpoint fájlból és az azóta eltelt tranzakciós naplóból a hiba előtti állapot teljes mértékben visszaállítható. Egy memóriarezidens adatbázis-kezelőnek a háttértárat kezelni csak naplózáskor és biztonsági mentés készítésekor kell, valamint helyreállításkor.

Teljesítmény - A hagyományos adatbázisrendszerek a teljesítményt elsősorban az I/O műveletek alapján becslik meg. Memória-adatbáziskezelő esetén alapvetően a műveletek processzorideje számít, tehát más metrika alapján számítható a teljesítmény, ennek ellenére a háttértárműveletek is befolyásolják azt. Ha a teljesítmény előbbre való, mint az adatok integritása, akkor nem kell tranzakciós naplózás. Ekkor azonban rendkívül sérülékeny a rendszer, és adatok veszhetnek el. Ha a legfőbb szempont az adatok biztonsága, akkor ezeket a háttértárigényes folyamatokat be kell kapcsolni, ami viszont a teljesítmény rovására megy. Természetesen a biztonsági mentés gyakoriságának állításával az átlagos teljesítmény mértéke befolyásolható, de a maximális teljesítményt a tranzakciós naplózás miatt biztosan nem érheti el.

API és védelem - Egy memória-adatbázisnak meg van az az előnye a diszkrezidenssel szemben, hogy a még nagyobb teljesítmény érdekében direkt kapcsolódási módot biztosítson a programozónak. Ez azt jelenti, hogy az adatbázis-kezelő a program rendelkezésére bocsátja az általa használt memóriaterületet, és objektumok helyett memóriacímeket küld ad át, így a program közvetlenül olvashatja ki a rekordokat. Ennek a módszernek az előnye, hogy nincs szükség felesleges objektummásolatokra a küldő pufferbe, hanem egyből kiolvasható az eredmény. Ez azonban a hátránya is, mivel csak körülményesen garantálható a többi adat biztonsága a memóriában. Ráadásul ez csak akkor használható, ha a program és az adatbázis-szerver egyazon hoszton helyezkedik el, mert közös memóriaterületet használnak. Természetesen a programok kapcsolódhatnak az adatbázishoz az egységes programozói interfészen (ODBC - Open Database Connenctivity) is.

Adatcsoportosítás – klaszterezés - Memóriarezidens adatbázis esetén nincsen szükség az adatok csoportosítására, mert a rekordokat egy-egy memóriacím azonosít a memóriában. Mindegy, hogy hol helyezkedik el, mert az nem befolyásolja az adathozzáférési időt. Ez azonban egy problémát is felvet, amikor diszkrezidens adatbázisba szeretnénk migrálni a memória-adatbázist, mert nem egyszerű eldönteni, hogy mely rekordok kerüljenek egy klaszterbe. [1]

Felmerülhet a kérdés, hogy ha egy memóriarezidens adatbázis-kezelőnek nem kell megküzdenie a rendkívül költséges háttértárműveletekkel, akkor miért nem használjuk őket a diszk alapúak helyett? Erre egyszerű a válasz. Azért nem, mert egy adatbázis sok esetben olyan nagymennyiségű adatot kezel, ami nem fér el a memóriában. Ez azonban nem azt jelenti, hogy ez a megvalósítás teljesen működésképtelen és használhatatlan. A memória előállításának költsége napjainkra drasztikusan lecsökkent, ezért a kereskedelmi forgalomban kapható modulok ára egyre alacsonyabbak lettek. A mai rendszerekben már nem ritka a 128GB, 256GB vagy akár az 512GB memória sem (ezek nagyon szerény becslések, mert vannak olyan top konfigurációk, melyekben akár 4096GB memória is lehet). Éppen ezért megfontolandó, hogy egy adatbázist memóriarezidens adatbázis-kezelőre bízzunk, vagy sem. Mivel a tárolási kapacitás egyre kevésbé jelent problémát, a minél jobb teljesítmény érdekében egyre több memória-adatbázis fog megjelenni.

Jelenleg sok esetben fordul elő, hogy egy hagyományos adatbázis ugyan nagy méretű, de szükség lenne a felgyorsítására memória-adatbázis segítségével. Ekkor az adatokat csoportosítani kell, hogy melyek azok az adatok, amelyeket sűrűn, rendszeresen használnak, és melyek azok, amelyeket csak ritkán. Ezek közül a gyakoribb adatokat érdemes a memória-adatbázisba tölteni, hogy azokat gyorsan el lehessen érni. Ha az adatbázisunk nem csak olvasható, akkor szinkronizációs problémák léphetnek fel a két adatbázis között, melyeket meg kell oldani (ez azonban implementációs kérdés). Az így létrejött architektúra tekinthető a hagyományos adatbázis kiterjesztésének egy memória-cache segítségével.


Mi a különbség egy memória-adatbázis és egy nagy pufferel rendelkező diszkrezidens adatbázis között?

Ha egy hagyományos adatbázisnak elegendő memória áll a rendelkezésére, hogy minden adatot a memóriában tartson, akkor gondolhatnánk, hogy így elérhetjük egy memória-adatbázis teljesítményét. Ez azonban tévedés, mert ekkor még mindig egy diszkrezidens adatbázis-kezelő kezeli az adatokat. Ahhoz, hogy egy alkalmazás hozzáférjen egy rekordhoz először a kezelő kiszámítja a diszken lévő helyét, utána a pufferkezelő lekérdezni, hogy esetleg a memóriában van-e? Mivel ott van, onnan átmásolja a küldő pufferbe, ahonnan az alkalmazás már elérheti a kívánt rekordot. Ehhez természetesen a blokkszervezésű, lemezre optimalizált B-fa indexet is fel kellett használni.

Ezzel szemben a memóriarezidens adatbázis-kezelő miután megkapta, hogy melyik rekordra van szükség, a hash táblával meghatározza a memóriacímet és ezt átadja az alkalmazásnak (direkt hozzáférés esetén). Ebből is látszik, hogy ez mennyi felesleges számítást spórol meg.


Forrás

[1]. Main Memory Database Systems: An Overview. Garcia-Molina, Hector és Salem, Kenneth. 1992., IEEE Transactions on Knowledge and Data Engineering, old.: 509-516.

[2]. Oracle Corporation. Oracle TimesTen Products and Technologies. Redwood Shores, California, U.S.A. : Oracle Corporation, 2007.