Olvasási idő: 4 perc
Egy korábbi posztban írtam arról, hogy hogyan lehet az adattárházat – napon belül – folyamatosan frissen tartani. Most az adattárház másik oldaláról lesz szó: hogyan lehet megoldani, hogy az adattárház gyorsan válaszoljon a kiaknázó felületek és a felhasználók lekérdezéseire?
Sok olyan adattárházi felhasználás van, ahol a válaszidő nem kritikus: ilyenek pl. a felügyeleti jelentések, vagy a havonta egyszer, tömegesen elkészülő ügynöki elszámolások. De ahogy az üzleti élet egyre gyorsul, egyre több olyan igény van, ahol az adattárháznak nem csak pontosan, hanem (vagy akár elsősorban) nagyon rövid idő alatt kell válaszolnia.
A „nagyon rövid idő” itt is egy relatív fogalom, hasonlóan a betöltési oldalhoz. Egy bankkártyás fizetésnél legfeljebb 0.1-0.2 mp-e van az adattárháznak, hogy a csalás-ellenőrzéshez szükséges adatokat átadja a kártyarendszernek, különben a fizetési élmény nagyon rossz lesz. Egy adattárház által kiszolgált üzleti folyamatlépés lekérdezései nem tarthatnak tovább, mint pár másodperc, és a felhasználók jogosan válnak türelmetlenné, ha kétszámjegyű másodpercig „homokórázik” a rendszer egy-egy interaktív dashboard frissítésekor – bármilyen bonyolult is az.
Ezen felül fontos szempont, hogy a válaszidő csak egyes lekérdezések szempontjából kritikus, vagy az adattárház általános gyorsítását tűzzük ki célul. Általában igaz, hogy specifikus felhasználásokat sokkal könnyebb és olcsóbb optimalizálni, mint „mindent”.
A válaszidővel kapcsolatos kihívások kezelésére sokféle eszköz létezik – és sajnos nincs „mindenre is” működő közöttük. A lentiekben összegyűjtöttem néhány gyakran használt megoldást.
Az egyik legnyilvánvalóbb irány, hogy ha lassú, akkor tegyünk alá több „vasat”. Néha a hardver erőforrások valóban nagyon nincsenek arányban az elvárt teljesítménnyel, és a reális méretezés megoldja a kérdést. Nagyon nagy mennyiségű adat esetén előfordulhat, hogy több (sok) szerver egyidejű, párhuzamos használatával jelentősen csökkenteni lehet a válaszidőt. Ez azonban elsősorban a felhős és Hadoop megoldások területe, hagyományos adattárházakban igen ritka, és ezért itt nem is tárgyaljuk. Általában azonban a vas növelése önmagában legfeljebb rövid távon segít, rossz esetben csak átmenetileg elfed egy, a mélyben egyre növekvő, problémát.
Ezzel együtt a hardver irányú vizsgálat fontos a szoftveres optimalizációk számára is: tudni kell, hogy a rendszer melyik eleme van túlterhelve (pl. diszk olvasás, memória, processzor). Néha ennek az információnak a birtokában nagyon rövid idő alatt, kevés munkával, jelentős javulást lehet elérni. Emellett a szoftveres megoldások sokszor kifejezetten építenek arra, hogy a rendszer valamelyik elemét arányaiban jelentősen „túlhasználják” a sebesség érdekében.
A szoftveres sebesség optimalizációk szinte mindegyike az adatpiaci rétegben vagy arra épülve működik. (Hiszen az adatpiaci réteg éppen a közvetlen adatkiszolgálás céljaira készül.) Esetenként kifejezetten a gyors kiszolgálás igényeire külön, optimalizált megoldás-elem is készül, amire néha „speed layer”-ként hivatkozunk.
A legegyszerűbb szoftveres megoldás az, ha „nem csinálunk semmit”, vagy ahogy a szoftver világ egyik „bon mot”-ja szól: „a leggyorsabb kód a nem létező kód”. Igazából persze csinálunk – csak nem akkor, amikor a lekérdezés történik, hanem a betöltés során: bizonyos dolgokat kiszámítunk és eltárolunk előre. Emögött az a gondolat, hogy szinte mindig sokkal gyorsabb egy kész eredményt elővenni, mint előállítani azt. Ez kifejezetten jól működik, ha kevés, de bonyolult számítás eredményéről van szó, de egyre nehezebbé válik, amikor a kérdés paramétereinek száma nő. Ilyenkor egy darabig még segít(het), hogy részeredményeket tárolunk el, és a lekérdezés kiszolgálásakor már csak ezeket „adjuk össze”. Ennek a megoldási iránynak a királyai az OLAP rendszerek, de sokszor megjelennek „kicsiben” közvetlenül a relációs adatpiaci megoldásokban is. Érdemes tudni, hogy vannak olyan esetek, amikre ez a megoldás nem alkalmazható; talán a leggyakrabban előforduló ilyen az egyedi (különböző) elemek megszámlálása.
Egy másik gyorsítási eljárás, ha nem kell ugyanazt a dolgot többször kiszámítani (mert pl. sejteni lehet, hogy ha valamire valaki kíváncsi volt, akkor hamarosan arra más is kíváncsi lesz, vagy önmaga fogja lekérdezni újra). Ezt a cache-elésnek nevezett mechanizmussal lehet támogatni, ami úgy működik, hogy nem betöltési időben, előre számolunk ki dolgokat, hanem amikor „amúgy is” kiszámítunk valamit, akkor eltesszük, hogy mi volt a kérdés és mennyi az eredmény; amikor pedig kérdeznek valamit, akkor első lépésként megnézzük, hogy korábban nem számítottuk-e már ki. Így az első lekérdezés viszonylag lassú lesz, de a továbbiak már nagyon gyorsak – viszont nem kell tervezéskor meghatározni, hogy mit számoljunk ki előre. Bár ennek a megoldásnak van egy-két informatikailag kifejezetten nehezen kezelhető aspektusa, és csak a második azonos lekérdezéstől kezdve térül meg, sokszor mégis megéri kialakítani.
A gyorsítás következő lépcsője, hogy ha már muszáj sokat számolni, akkor legalább csináljuk gyorsan. A mai adattárház technológiák relatíve messze leglassabb eleme az adatok háttértárról olvasása (és írása). Bár az SSD-k nagyon sokat javítottak ezen a helyzeten, még mindig sokkal lassabb diszkről olvasni, mint memóriából, ezért próbáljuk meg ezt elkerülni, amennyire lehet. Ennek rég bevett módja az indexelés, ami mellé az utóbbi időben felzárkózott az adatok memóriában tartása, és az ún. oszlop alapú tárolás, vagy közhasználatú angol kifejezéssel “column store”.
A memóriában történő adattárolás ötlete triviális, de jellemzően még akár 5 évvel ezelőtt sem lehetett adattárháznyi adatmennyiségeket gazdaságilag racionálisan memóriában tartani. Mára ez – a memória árak csökkenése, és az ilyen célú szoftveres megoldások jelentős fejlődésének hatására – teljesen megváltozott: minden jelentős adattárház-építő eszköz széleskörűen támogatja ezt, sőt vannak olyanok is, amelyeknek ez a működési alapmodellje.
Egy ettől tulajdonképpen független, de ezzel párhuzamosan népszerűvé vált megoldás az oszlop alapú tárolás. Ennek lényege, hogy az adatokat nem soronként („rekordokban”) tároljuk, ahogy a tradicionális adatbázis-kezelőkben, hanem oszlopokban (mintha elfordítanánk a hagyományos adattáblát 90 fokkal). Azaz az egyes rekordok azonos mezőit tesszük fizikailag egymás után. Ennek a megoldásnak különösen adattárházi felhasználás esetén van sok előnye. Egyrészt így sokkal jobban lehet tömöríteni az adatokat (és ezért több fér a memóriába). Másrészt szinte minden adattárházi művelet (pl. szűrés, egy adott oszlop értékeinek összeadása stb.) amúgy is oszlopok szerint történik, tehát ez bizonyos fokig még természetesebb is így. Ráadásul a fizikailag egymás mellett lévő elemekhez gyorsabban is lehet hozzáférni, mint az össze-vissza elhelyezettekhez. Még egy előny, hogy ezzel a struktúrával könnyen ki lehet használni a korszerű sokmagos processzorok belső felépítését, ami további nagyon jelentős teljesítmény-növekedést eredményez.
Ezt a két technikát a régebbi adattárház kódok szinte egyáltalán nem használták; ezeknek az átalakításával például rendszerint komoly gyorsítás érhető el.
Ahogy látható, a legtöbb helyzetben sokféle lehetőség van az adattárházi válaszidő javítására, ami azért is szerencse, mert számos esetben tapasztaljuk, hogy a válaszidők jelentősen befolyásolják magának az adattárháznak a megítélését is. Ezért érdemes az adattárház bevezetési projektek végére egy ezzel foglalkozó szakaszt beilleszteni, vagy kész adattárházak esetén külön projektet indítani erre. Bár a sebesség-optimalizálás komplex feladat és erőforrás-igényes tud lenni, a fenti eszközök – szakértő kezekben – „csodákra” képesek, és így ez a ráfordítás felhasználási élményben és várakozási időben rendszerint jócskán megtérül.
Zimmer András – CTO