In-memory computing – Apache Ignite

László Zoltán

2022. május 16.

Dolgoznék ezen a projekten

Napjainkban egyre gyakoribb a hardveres memóriára (RAM-ra) épülő technológiák használata, de még sokszor felmerülhet bennünk a kérdés, hogy egyáltalán mi ez, vagy hogy mikor, miért és hogyan használjuk ezeket. Üzleti alkalmazások fejlesztése során a bevett megoldás az, hogy fogunk egy megbízható adatbáziskezelő rendszert (DBMS), legyen az akár relációs vagy NoSQL, majd a szolgáltatásainkat erre csatlakoztatva építjük fel. Az esetek többségében ez elegendő is, de érdemes tisztában lennünk milyen egyéb lehetőségeink vannak.

 

https://www.gridgain.com/resources/blog/in-memory-computing-in-plain-english

 

Mi micsoda

 

In-memory computing

 

Az „In-memory computing” egy olyan technológia használatát jelenti, ami lehetővé teszi, hogy az adatokat szerver klaszterekben elosztva, a RAM-ban tároljuk, illetve azokat párhuzamosan feldolgozhassuk.

 

In-memory data grid (IMDG)

 

A memória alapú technológiák alapja. Ez az a váz, ami biztosítja, hogy adataink elosztottan legyenek tárolva több gép között, amelyek együttesen alkotják magát a grid-et. Biztosítja a magas rendelkezésreállást és a horizontális skálázhatóságot az adatok particionálásával, replikálásával, továbbá garantál bizonyos mértékű adatkonzisztenciát (eszköztől és konfigurációtól függő mértékben). Egyszerű objektumorientált nem relációs adatmodellt alkalmaz.

 

https://www.gridgain.com/resources/blog/in-memory-data-grid-explained

 

 

In-memory compute grid (IMCG)

 

Az adattárolás egy dolog, az adatfeldolgozás pedig egy másik. Az in-memory compute grid az utóbbit biztosítja számunkra. Ez egy integráció a számítási feladatok és az adattár között. Segítségével számítási feladatokat ütemezhetünk és oszthatunk szét az in-memory data grid-en, ami lehetővé teszi, hogy azok a gépek, amelyek az adattárolást végzik, azok végezhessenek adatfeldolgozást is az általuk tárolt adatokon.

 

https://www.gridgain.com/resources/blog/in-memory-compute-grid-explained

 

In-memory data base (IMDB)

 

Az IMDG egy addicionális rétege, amely a megszokott adatbázis funkcionalitásokkal és interfészekkel egészíti ki a rendszert. Míg az IMDG adatmodellje objektumorientált (kulcs-érték párokat kezelő) és nem relációs, addig az IMDB adatmodellje táblákat és oszlopokat kezel. Adathozzáférés szempontjából biztosít SQL, vagy az SQL funkcionalitását helyettesítő API-t. Technológiától és konfigurációtól függően támogatja a relációk és tranzakciók kezelését.

 

Apache Ignite

 

Az Apache Ignite egy a sok eszköz közül, amely IMDG, IMCG és IMDB szolgáltatásokat nyújt. Ezeken felül további egzotikus képeségekkel is bír, amelyek miatt ugyancsak fókuszba kerülhet pl.: machine learning, streaming, distributed messaging.

 

 

Miért épp az Ignite

 

Ami miatt kiemelném ezt az eszközt a többi közül, az az hogy ez egy megszokott gyorsan fejlődő open source apache projekt produktuma, amely így a szokásos, közösségi támogatással és Apache License 2.0-val rendelkezik. Ez ugye azt is jelenti, hogy üzleti célra is ingyen felhasználható. Természetesen ahogy ez lenni szokott, ebből is elérhető egy enterprise verzió (GridGain Enterprise Edition), de más termékekkel ellentétben, itt az eszköz ingyenes verziója is szinte minden igényt kielégítő, nem vagyunk feltétlen rákényszerülve egy licencdíjköteles verzióra.

 

A jelenleg piacvezető Hazelcast egy kiváló alternatívája. Bizonyos területeken felül is múlja azt (rugalmasabb, könnyebben integrálható más eszközökkel/technológiákkal), de mivel az Ignite egy viszonylag új eszköz, így még nem tett akkora népszerűségre. Mindenesetre egy mélyebbre ható összehasonlítást érdemes elvégezni a felhasználási igények figyelembevételével, mielőtt hasonló eszközt választunk.

 

 

Mikor miért és hogyan

 

Alapvetően a RAM a legdrágább adattároló. Ebből kifolyólag az in-memory technológiák használata jóval költségesebb a perzisztens adattárolókra épülő megoldásokhoz képest, mint pl. a hagyományos adatbázis rendszerek. Így hát legyünk körültekintőek, mielőtt fejest ugranánk ebbe.

 

Miért akkor hát ez a felhajtás? Nem meglepő módon a többi megoldáshoz képest a tisztán, vagy túlnyomórészt memória alapú megoldások a leggyorsabbak. Ebből adódóan, akkor érdemes ezeket választanunk, ha rendszerünk különösen érzékeny a késleltetésre, szigorú válaszidő követelményei vannak, továbbá ha szeretnénk elérni a lehető legnagyobb áteresztőképességet. Kiváló választás lehet tisztán cache célra is. Akár önmagában (perzisztens réteg nélkül, csak memóriában tárolt adatokkal), vagy egy perzisztens adatbázis gyorsítótáraként.

 

Nem célszerű azonban tartós adattárként használni egy klasszikus adatbázis (pl.: Oracle/SQL Server, MongoDB/Cassandra, stb.) helyett, mert ugyan egy IMDG-be bekötött újabb node-okkal gond nélkül növelhető a tárkapacitás, de nyilván ezzel az üzemeltetési költségek is durván elszaladnak. Tehát összességében ez akkor ideális választás, ha ezt az eszközt arra használjuk, hogy az adatokat átmenetileg tároljuk, illetve ha ezeken valamilyen adatfeldolgozást szeretnénk végezni.

 

 

Felhasználási területek

 

  • Investment banking
  • Insurance claim processing & modeling
  • Real-time ad platforms
  • Real-time sentiment analysis
  • Merchant platform for online games
  • Hyper-local advertising
  • Geospatial/GIS processing
  • Medical imaging processing
  • Natural language processing & cognitive computing
  • Real-time machine learning
  • Complex event processing of streaming sensor data

 

Beágyazott működés

 

Rátérve egy kicsit a technológiai részletekre, illetve magára az Ignite-ra, két féle működésről beszélhetünk. Egyrészt használhatjuk mint egy standalone szolgáltatás. Ebben az esetben az Ignite úgy működik, mint egy szokásos adatbáziskezelő rendszer, amelyhez az alkalmazások csak kliensként csatlakoznak (thin client). Ilyenkor egy sima DB-hez hasonlóan az Ignite API-ján keresztül (akár JDBC-vel is), definiálhatjuk az adatstruktúráinkat (DDL), illetve módosításokat hajthatunk végre a tárolt adatokon (DML). A standalone megoldás nehézsége, hogy csak olyan számítási feladatokat (ComputeTask) és szolgáltatásokat (IgniteService) tudunk a kliens oldalról futtatni, amelyek előre telepítettek az Ignite cluster-ben. Ez azt jelenti, hogy ilyenkor ezeket a kódokat lib-ekbe szervezve kell odaadni az Ignite szolgáltatásnak, amely induláskor betölti azokat. Kliens ezeket név alapján hivatkozva képes elindítani. Ezt a kialakítást akkor célszerű alkalmaznunk, ha több különböző szolgáltatásunkból is elérhetővé kívánjuk tenni az Ignite adta in-memory platformot, vagy ha egyéb rendszerekkel kívánjuk integrálni, mint pl. Kafka streaming, Hadoop, stb.

 

Másik opció, hogy az Ignite-ot a saját szolgáltatásunk részévé tesszük. Ilyenkor, mint bármely más függőséget, az Ignite-ot is behúzzuk mint egy plusz lib-et. A lib által adott Ignite szolgáltatást megfelelően felkonfigurálva és elindítva máris egy Ignite szerver node-dá varázsoltuk az alkalmazásunkat. (példa Spring integrációra: https://ignite.apache.org/docs/latest/extensions-and-integrations/spring/spring-boot#apache-ignite-with-spring-boot) Ennek a megoldásnak az az előnye, hogy az egyedi adatfeldolgozási logikákat, amelyek egyébként a sajátfejlesztésű szolgáltatásunk részét kéne hogy képezzék, nem kell kiemelnünk a szolgáltatásból, hogy azt az Ignite-on, mint infrastruktúrális elemen futtassuk, mivel ilyenkor az üzleti alkalmazásunk és az in-memory platformunk teljesen egybeintegrált. Ezt a kialakítást akkor célszerű alkalmaznunk, ha a Ignite platform felhasználása nagyon üzleti logikához kötött, viszont fontos figyelembe venni, hogy ebben az esetben a szolgáltatás és az Ignite platfrom verzióváltása összekötött, azaz nem tudunk úgy új verziót kiadni, hogy az ne érintse mind az üzleti szolgáltatást, mindpedig az Ignite IMDG-t. Ennek nehézségeire még visszatérünk.

 

https://ignite.apache.org/docs/latest/clustering/clustering

 

 

Projekt tapasztalat

 

Nemrégiben volt szerencsém egy banki szolgáltatás részeként kialakítani egy IMDG/IMCG megoldást. Az üzleti igény az volt, hogy pénzügyi tranzakciókat (pl.: utalás, betét lekötés/feltörés stb.) átmenetileg tároljunk, majd amikor ezek feldolgozásának feltételi adottak (nyitva a bank számlavezetőrendszere, ügyfél általi megerősítés megtörtént, stb.), akkor a rendszer hajtsa is végre ezen megbízásokat.

 

Miért ideális választás erre egy in-memory megoldás?

 

  • A tárolandó adatok száma korlátos. Egy tárolt pénzügyi tranzakció nem várhat a végrehajtásra az örökkévalóságik, ez ugye azt is jelenti, hogy nekünk sem kell a végtelenségik tárolni ezeket a memóriában. Ismert volt számunkra, hogy maximálisan hány ilyen tranzakciót végez a bank egy adott időszakon belül, így jól becsülhető volt, hogy mekkora a maximális memóriaigény.
  • Nem csak tárolnunk kellett a megbízások adatait, hanem azokat fel is kellett dolgoznunk. A feldolgozás esetünkben azt jelentette, hogy időről időre meg kellett vizsgálnunk, hogy teljesíthető-e egy adott tranzakció. Ha nem, akkor várakoztattuk a memóriában tovább, ha pedig igen, akkor továbbítottuk a megbízást az azokat kezelő egyéb banki szolgáltatásoknak.
  • Az áteresztő képesség különösen fontos. Célunk volt, hogy a lehető legrövidebb idő alatt teljesítse a rendszer a megbízásokat, amint adott hozzá minden feltétel. Pl.: az utalások azonnal teljesüljenek, amint elérhetővé válik a számlavezetőrendszer. Továbbá alapvető elvárásunk volt, hogy horizontálisan skálázható megoldást biztosítsunk (értsd: további gépek bekötésével, növelhessük a feldolgozó és/vagy tároló kapacitást).

 

A fentiekből következik, hogy már csak performancia megfontolásokból is célszerű ilyen esetekben a memória alapú technológiák használata, de mivel itt nem csak adattárolásról, hanem a tárolt adatokon végzett adatfeldolgozásról is beszélhetünk, így ez a tökéletes felhasználási területe az IMDG és IMCG technológiáknak.

 

Az általunk fejlesztett szolgáltatás komplex üzleti logikákkal tarkított, és mivel ügyfelünknél máshol még nem volt hasonló technológia platform (standalone) szinten alkalmazásban (Ignite, Hazelcast, Ehcache, stb.), ezért az embedded kialakítást, vagyis az Ignite saját szolgáltatásunkba való beágyazását választottuk. Ez azért praktikus megoldás ilyen esetekben, mert az említett feldolgozási feladatok, Ignite szinten compute task-okban nyilvánulnak meg, melyeket standalone üzem esetén a saját szolgáltatásunkból ki kellett volna emelnünk, és a lib-ekbe csomagolva az Ignite-ba telepíteni, így viszont a feldolgozás üzleti logikáját, és magát az in-memory platformot egy egységbe zárva tudtuk tartani.

 

Pozitívumok

 

Ami a beágyazást illeti, az Ignite dokumentációját végigfutva talán úgy tűnhet, hogy az eszköz csak a Spring keretrendszeren belül, annak kiegészítéseként használható, de ez nem igaz. Tulajdonképen bármilyen Java framework-kel összeilleszthető, vagy akár framework használata nélkül is alkalmazható. Azért nem véletlen a sok Spring-es példa az Ignite dokumentációjában. Sok minden egyszerűbben megoldható Spring-ből, (pl.: konfiguráció, tranzakciókezelés, dependecy injection), de mindenre van egy framework független natív Java megoldása az Ignite-nak, ami csak az Ignite lib-re épít. Mi a projekt kapcsán az Akka, Akka HTTP és Google Guice dependency injection eszközökkel integráltuk gond nélkül.

 

In-memory ugyan, de ha leáll a rendszer mi lesz az adatokkal? Jogos a kérdés… Az Ignite mindenekelőtt az adatok replikálásával igyekszik biztosítani a magas rendelkezésre állást, ami ugye azt jelenti, hogy konfigurációtól függően, egy-egy Ignite node elvesztése még nem jelent adatvesztést, de azért sosem árt, ha fel vagyunk készülve a legrosszabbra, mondjuk egy teljes leállásra. Ez persze nem is feltétlen csak katasztrófa helyzetben releváns, mert egyéb okokból is lehet, hogy újra szeretnénk indítani az Ignite cluster-ünket, például verzióváltás miatt. Ilyenkor ugye elveszik minden adat, amit csak memóriában tárolunk, ezért célszerű ha ezek egy tartós adattárban is elérhetőek. Erre az Ignite-nak különböző megoldásai vannak. Egyfelől van egy saját megoldása erre, az „Ignite persistence”, ami lehetővé teszi, hogy az adatokat ne csak a memóriában, de diszkre mentve is eltároljuk. Ilyenkor minden Ignite node a fájlrendszerbe írva, tulajdonképpen letárolja maga alá azokat az adatokat amiket a memóriában kezel. Mi nem ezt a megoldást választottuk, mert privát felhő környezetre szántuk a szolgáltatásunkat, ahol egy fokkal körülményesebb lett volna megoldani a megfelelő „persistent volume”-ok biztosítását. Sok esetben, így a miénkben is egyszerűbb megoldásnak bizonyult, egy már létező adatbázist használni a tárolásra. Szerencsére az Ignite alapból biztosít Cassandra, JPA, JDBC csatlakozási pontokat, de pár interfész implementálásával tulajdonképpen bármilyen adatbázist beköthetünk az Ignite-ba. Mi a JDBC alapú megoldást alkalmazva egy SQL Server adatbáziskapcsolatot építettünk ki.

 

 

Rengeteg ponton konfigurálható, hogy az Ignite in-memory adatbázisunk, milyen konzisztencia garanciák mentén működjön. Illetve az is, hogy a tartós és a memória alapú tárolóink között milyen konzisztenciát biztosítson. Ami számunkra releváns volt, hogy az adatok mikor kerülnek lementésre az adatbázisba. Lévén hogy a rendszerünk pénzügyi tranzakciókat kezel, így a legszigorúbb „write-through” üzemmódot választottuk, ami azt jelenti, hogy amint bekerül valami a memóriába, azonnal be kell hogy kerüljön a tartós adatbázisunkba is. Ez némiképp lassítja a működést a „write-behind” üzemmódhoz képest, ahol a memóriában tárolt adatok csak később aszinkron módon kötegelve kerülnek a perzisztens tárolóba, de a lényeg, hogy igénytől függően dönthetünk, hogy mi az amire a rendszerünknek nagyobb szüksége van (performancia vs konzisztencia). (https://apacheignite.readme.io/docs/3rd-party-store)

 

Maga a memória alapú tároló is ennek szellemében konfigurálható. Dönthetünk arról, hogy sima atomi, vagy tranzakcionális tárolót szeretnénk. Utóbbi esetében lehetőségünk van több atomi műveletet is egyszerre oszthatatlan módon végrehajtani, ezeket tranzakciókba csomagolva. (https://apacheignite.readme.io/docs/transactions#atomicity-mode) Számunkra a tranzakciónális cache konfiguráció biztosította a 100%-os garanciát arra, hogy akár több összefüggő megbízást is egyszerre kezeljünk. Ezzel a beállítással az Ignite egy teljes értékű ACID garanciákat biztosító adatbázissá vált számunkra. Ezen garanciák pénzügyi megbízások teljesítése során szükségesek voltak számunkra.

 

Nehézségek

 

A projektünk kapcsán a legtöbb problémát a verzióváltás nehézsége okozta. Ez két okból származtatható. Az egyik maga a beágyazott működés, a másik pedig a nyilvánvaló tény, hogy az alkalmazás nem stateless. A beágyazott működés problémája, hogy az üzleti logikán nem tudunk úgy módosítani, hogy az ne érintse a IMDG-t. Ez azt jelenti, hogy ha üzleti módosítások miatt egy új verziót akarunk telepíteni, akkor azt rolling deployment segítségével, szolgáltatás kiesés nélkül nem lehet egyszerűen megoldani, ugyanis ilyenkor a szolgáltatásunk minden futó példánya egyben egy Ignite node is. Ebből következik, hogy habár elviekben megoldható lenne, hogy az Ignite node-okat egyesével történő lecserélésével (régi verzió leállít, utána új elindít) szolgáltatás kiesés nélkül váltsunk verziót, ugyanakkor ez a valóságban mégsem könnyen kivitelezhető. Na de miért is? Az egyik fő gond az eltárolt tranzakciók. Mivel az adatvesztés elkerülése érdekében replikációt alkalmaztunk, az Ignite node-ok lecsatolásával, majd az új node-ok csatlakozásával folyamatos rebalancing-ra kényszerítjük a rendszert. Másik nagy probléma a számítási feladatok verzióváltása. Egyfelől lehetséges, hogy az új verzió más logikájú compute task-okat futtat, mint a régi, ami gondot okozhat egy rolling update-nél, mivel a régi és az új verzió ugyan annak a cluster-nek a tagja. Másik nehézség, hogy akár ignite service-ek is lehetnek a cluster-ben, amelyeket egy verzióváltás során újra kell telepítenünk. (https://ignite.apache.org/docs/latest/services/services#re-deploying-services) Ezek miatt mindenképp érdemes tisztában lennünk azzal, hogy egy verzióváltás milyen hatással is lesz a cluster működésére, vagy hogy egyáltalán kivitelezhető-e szolgáltatáskiesés mentesen.

Volt problémánk abból adódóan is, hogy magának az Ignite lib verziójának frissítésével vált lehetetlenné a rolling update, mivel az Ignite lib egy minor verzióval újabb kiadása nem volt képes csatlakozni azokhoz a node-okhoz, amelyek az Ignite egy minor verzióval korábbi kiadásával futottak.

Ezen okokból, mi azt a megoldást választottuk, hogy a szolgáltatáskiesés mentes verzióváltást úgy biztosítjuk, hogy az éppen futó, adott verziójú Ignite cluster mellé, indítunk egy másik, újabb verziójú független cluster-t, majd a régi cluster-ből átmigráljuk az adatokat az újba. Szerencsénkre ehhez is nyújt támogatást az Ignite, lásd Data Streamers (https://apacheignite.readme.io/docs/data-streamers) Ezáltal egy teljesen egyértelmű és stabilabb működést kapunk, azonban a megoldás hátránya, hogy a verzióváltás ideje alatt duplázódik az erőforrásfelhasználás. (2x annyi memória kell)

 

Az Ignite monitorozása ami még kisebb nehézséget okozott. Szerencsére rengetek különböző és hasznos metrika érhető el JMX-en keresztül, amelyeket az Ignite készít. Ez persze a bevett megoldás hasonló eszközök esetében, de fontos megemlíteni, hogy az Ignite enterprise (fizetős) verziója már biztosít egy ilyen célú teljeskörű megoldást: GridGain Control Center. (https://www.gridgain.com/products/control-center)

 

További hátránya az ingyenes verziónak, hogy nincs benne teljes értékű multi datacenter támogatás. Ez is csak az enterprise verzióban érhető el, de minden eszköz rendelkezésre áll az alap Ignite verzióban is, hogy egy ilyen funkciót mi magunk is implementáljunk. Persze érdemes mérlegelni, hogy mi a költségesebb. A saját implementáció nyilvánvaló előnye, hogy egyedi igényeket is ki lehet vele elégíteni.

 

Verdikt

 

A technológia költséges ugyan, de mégis kifizetődő. Az in-memory platformok által nyújtott képességek egyre inkább nélkülözhetetlenek, ebből kifolyólag nem is kerülhető meg a használatuk. Az Apache Ignite az egyik legjobban testreszabható, open source és ingyenes eszköz az in-memory computing világában, így szinte minden igényt kielégítő támogatást tud nyújtani céljainkhoz, minden szempontból az igényeinkhez alakítható. Az említett nehézségek nem az eszköz ellen, mintsem inkább mellette szólnak, mivel megoldásukhoz kellő rugalmasságot garantál.

Kapcsolódó állásajánlataink

Java fejlesztő Tovább

Backend (Java) fejlesztő Tovább

Full Stack fejlesztő Tovább

Itt találkozhatsz velünk

Rendezvény
Lezajlott

Ami egy senior fejlesztőt sem hagy aludni

2022. június 9. - 2022. június 9.

Budapest, Óbudai Egyetem, 18.00

Ezúttal egy rendkívüli nyárindító MeetUp-al jelentkezünk... Aki senior fejlesztőként dolgozik sokszor nehezen alszik el... De mi az ami ébren tart? És hogy tudod kezelni a senioritással járó kihívásokat.. és végre egy rendeset aludni.... A meglepetés nyitóelőadást / workshopot követően Szerémi Péter kommunikációs szakértő és Pál András a Radnóti Színház színésze ad elő és dolgoz fel agilis élethelyzeteket... olyanokat amelyekkel minden senior fejlesztő találkozik... Annyit ígérhetünk, hogy szórakoztató és tanulságos lesz. ...és a MeetUp után egész biztos jól fogsz aludni :)

Rendezvény
Lezajlott

Data Management 13.0

2022. május 12. - 2022. május 12.

Budapest, 18.00

Érdekel a Data Management? Akkor van egy jó programötletünk a számodra! Regisztrálj a május 12. -i Data Management 13.0 MeetUp-unkra. Előadóink sorát Gyöngyi fogja megkezdeni, aki Data Management megoldásokról fog beszélni - majd ezt követően egy panelbeszélgetést hallgathatunk meg Csite László, Kasler Lóránd Péter, Kelemen Márton és Szőke József részvételével. Végezetül pedig László Zoltán, az UpScale kollégája mutatja be a TiDB NewSQL POC-unkat.

Rendezvény
Lezajlott

AI, a megoldás!

2021. október 13. - 2021. október 13.

Budapest, 9.00

AI, a megoldás UpScale előadás Banking Technology 2021 / Portfolio konferencia 2021. október 13. Corinthia Hotel Budapest A prezentáció főbb üzenetei: A mesterséges intelligencia (AI) igazi versenyelőnyként tud szolgálni a nagyvállalatok / nagy pénzintézetek számára, amelyeknek rendkívüli mennyiségű adat áll a rendelkezésre. Az AI ugyanakkor több mint egy analitikai eszköz és a bevezetése megfelelő szemléletmódot igényel. A legacy rendszerek modernizációja, az új generációs adatbázisok, holisztikus use-casek és az AI jól definiált szerepe az üzleti folyamatokban egyaránt fontos elemei egy jól átgondolt stratégiának.

Rendezvény
Lezajlott

Modern technológiák Enterprise környezetben

2021. június 3. - 2021. június 3.

Budapest, 9.00

Modern technológiák Enterprise környezetben UpScale előadás Financial & Corporate IT 2021 Portfolio hybrid konferencia 2021. június 3. Kempinski Hotel Corvinus Budapest Az előadás az UpScale négy éves tapasztalatára építve, konkrét esettanulmányokon keresztül mutatja be, hogyan tehetők modern (akár open source) technológiai megoldások enterprise kompatibilissé.

Vedd fel velünk a kapcsolatot!

Profi megoldásokat nyújtunk minden felmerülő problémádra. Keress minket bizalommal!

Kapcsolatfelvétel

Legyél te is a csapat tagja!

Nézd meg nyitott pozícióinkat, és ha felkeltettük érdeklődésed, keress minket bizalommal!

Jelentkezz hozzánk!