[HUN] Üzleti adatok vizualizációja egyszerűen és gyorsan

Zalán Tóth
10 min readMay 26, 2023

--

Számos szervezet számára szükséges az üzleti adatok grafikus megjelenítése. Ennek megvalósítása az esetek többségében nem egyszerű feladat. A mikroszolgáltatás architektúra népszerűségének köszönhetően az adatok általában több adatbázisaiban tárolva érhetők el. A megjelenítéshez szükséges lekérdezések végrehajtása sok időt vehet igénybe, mely terheli az üzleti adatbázist, - főleg ha nem használunk read replica db-t - ezáltal lassítva a alkalmazást. Nehézkes a különböző adatbázisokban található adatok összekapcsolása, a szükséges adatok szennyezettek lehetnek, illetve a struktúrájuk és formátumuk nem biztos, hogy megfelelő.

A probléma megoldására több lehetőség áll rendelkezésre. Ezek, a teljesség igénye nélkül:

  • Egyedi analitikai rendszer fejlesztése
    Ehhez létre kell hoznunk egy új szolgáltatást, mely elkéri a szükséges adatokat a megfelelő mikroszolgáltatásoktól - vagy közvetlenül az adatbázisukból - majd ezeket az adatokat normalizálva létrehozza a diagramok megjelenítéséhez szükséges adatstruktúrákat. Az adatok mennyiségétől és minőségétől függően ez bonyolult lehet.
    Emellett létre kell hozni a megjelenítésért felelős szoftvert is, amely képes az adatokból a megfelelő diagramok kirajzolására.
    Előnye hogy bármi személyre szabható, cserébe sok fejlesztést igényel.
  • Felhő alapú analitikai rendszer
    A legtöbb felhőszolgáltató biztosít saját megoldást is adatelemzésre és vizualizációra. Ilyen például az Azure Analysis Services, vagy az AWS szolgáltatás csomagja, az AWS Analytics. Ezek használatával -szolgáltatótól függően - gyorsan és kényelmesen elkészíthetjük a megoldásunkat. Hátránya, hogy hosszú távon drágább lehet, illetve nehézkes az egyedi igények megvalósítása.
  • Komponens alapú analitikai rendszer
    Számos szolgáltatás létezik, melyek kombinálásával gyorsan felépíthetjük az analitikai megoldásunkat. Ez gyakorlatilag a fenti kettő kombinációja. A felhő alapúnál olcsóbb és az egyedi fejlesztésnél gyorsabb. Az egyes rétegeket akár saját megoldásra is cserélhetjük. Ennek segítségével érhetjük el a legjobb ‘ár - befektetett munka -elkészülési idő’ arányt. Természetesen ezek között kompromisszumot kell kötnünk.

Ebben a bejegyzésben egy komponens alapú analitikai rendszert fogunk építeni. Minden komponens futtatható lokálisan, on-premise, vagy felhő alapú platformon is, emellett SAAS formában bérelhetők is.

Komponensek

Az alábbi lista a felhasznált szoftvereket tartalmazza:

  • PostgreSQL, üzleti-, és BI adatbázis
  • MongoDB, üzleti adatbázis
  • Docker, konténerizációs platform
  • Metabase, adat vizualizációs eszköz
  • Airbyte, ELT rendszer az adatok mozgatásához
  • Data Injector, teszt adatokat beszúró ütemezett job

Áttekintés

Az adatok két adatbázisba kerülnek tárolásra, melyeket egy adatbeszúró job tölt folyamatosan - két mikroszolgáltatást szimulálva. Az első egy PostgreSQL adatbázis, mely a felhasználók adatait tárolja. A másik pedig MongoDB, melyben a felhasználók megrendelései, valamint - az egyszerűség kedvéért - a termékek adatai találhatók.

Szolgáltatások

Célunk egy egyszerű dashboardon megjeleníteni az eladásokból származó összbevételt, a termékekből eladott darabszámot, a termékek aktuális árát, valamint árának változását vonaldiagramon, illetve a felhasználók által termékenként elköltött összeget.

A teszt rendszer tíz felhasználót és harminc terméket tartalmaz.
Az adatokat töltő ütemezett job percenként újabb megrendeléseket szúr be az adatbázisba véletlenszerű felhasználóhoz, véletlenszerű termékre.
Ezenkívül minden futánál pár termék árát módosítja egy szintén véletlen generált értékre. A job forráskódja elérhető a linkre kattintva.

A végeredmény az alábbi képen látható:

Metabase Dashboard

A Platform felépítése

Első lépésben a szükséges adatokat az üzleti adatbázisból átmásoljuk az elemzésre szolgáló BI adatbázisba. Ehhez egy ETL/ELT - jelen esetben AirByte - rendszert fogunk használni, ami a megadott szabályok alapján a forrás adatbázisokból az adatokat átmozgatja a cél adatbázisba. Valós környezetben több alternatíva közül is választhatunk - pl Fivetran, Dataddo - bérelt platformként.

Export Load Transform system

Üzleti intelligencia - BI - adatbázisként a példában PostgreSQL-t használunk, mely megfelelő kisebb mennyiségű, - max pár száz GB - egyszerűbb adathalmaz elemzéséhez. Léteznek üzleti elemzésre kifejlesztett adattárházak, mint például Google BigQuery vagy Amazon Redshift. Amennyiben a relációs adatbázis szűk keresztmetszet, érdemes ezekre áttérni.

Következő lépésként az átmásolt nyers adatokból létre kell hoznunk a vizualizációhoz szükséges megfelelő adatstruktúrákat és transzformálni az adatokat a megfelelő formátumra. Ebben segít a DBT modellező és transzformációs program, mely a legtöbb ELT rendszerbe becsatornázható.

Data transformation using ETL

Miután az adatok a helyükre kerültek, már csak meg kell jelenítenünk őket. Ehhez hívjuk segítségül a Metabase alkalmazást. A diagramokat a no-code szerkesztő, vagy egyszerű SQL, illetve pár beállítás segítségével létrehozhatjuk, majd ezekből összeállíthatjuk a szükséges dashboardot. Bonyolultabb lekérdezéseket is megfogalmazhatunk egy-egy diagramhoz, bár az esetek többségében érdemes inkább DBT transzformáció segítségével a megfelelő formátumra hozni az adatokat, hisz a sok táblakapcsolattal rendelkező lekérdezések esetén a dashboard betöltési ideje jóval lassabb lehet, mint egy egytáblás lekérdezés esetén, ahol esetleg szűrőfeltétel megadása sem szükséges. A Metabase támogatja a dashboardok beágyazását weboldalakba. Az alkalmazás futtatható konténerizáltan, de elérhető online szolgáltatásként is.

Data analytics platform

Mielőtt felépítjük a platformot, tekintsük át az üzleti adatbázisok tartalmát.

Üzleti táblák

A felhasználók tábla Postgres adatbázisban foglal helyet. Tartalmazza a felhasználó azonosítóját, nevét és email címét. A megrendeléseket és termékeket MongoDB-ben tároljuk. A megrendelések gyűjteményben található minden dokumentum magába foglalja a megrendelt termék, valamint a megrendelő azonosítóját, a megrendelés dátumát, illetve a megrendelés részleteit tartalmazó aldokumentumot. Hogy egy kicsit érdekessebbé tegyük a platformot, a termékeket nem egyszerű dokumentumként - adatbázis bejegyzés - tároljuk, hanem egy Event Sourcing - belinkelem, de nem vagyok hajlandó magyarul leírni - alapú adattáblát emulálunk. A gyűjteménybe minden egyes módosításhoz egy új dokumentum kerül beszúrásra. Ezen módosításokat időrendben összesítve kapjuk meg az adott termék aktuális állapotát. A példában eltekintünk a snapshotok létrehozásától.

Most hogy már ismerjük az architectúrát, kezdjük el a platform összeszerelését.

A Platform indítása

A komponensek elindításához futó Docker szükséges. A telepítést leíró compose fájlok és a job forráskódja letölthető innen. Az airbyte-compose.yml és platform-compose.yml által definiált komponensek telepítése a következő parancs kiadásával indítható:

A telepítés pár percet igénybe vehet, mivel le kell tölteni az alkalmazáshoz használt konténereket, valamint fel kell építeni egy új konténert a Job forráskódjából.

Airbyte konfigurálása

Miután elindult a platform, fel kell konfigurálni az adatbázis kapcsolatokat.
Az AirByte a localhost:8000 url címen érhető el. A felhasználónév és jelszó pedig airbyte/password. Belépés után lehetőség van új forrás felvételére. Kössük be először a Postgres, majd a MongoDB üzleti adatbázist, cél adatbázisként pedig a másik Postgres adatbázist. Ezek paraméterei:

Postgres Business:

  • Source adatbázis
  • Port: 10010
  • DB Name: postgres

MongoDB Business:

  • Source adatbázis
  • Port: 10020
  • DB Name: admin

Postgres Business:

  • Destination adatbázis
  • Port: 10030
  • DB Name: postgres

A felhasználónév és jelszó minden adatbázisnál admin/admin123. Az alábbi képen látható egy űrlap kitöltés minta. A Set up source/destination gombbal hozhatjuk létre a kapcsolatot. A destination adatbázist elég egyszer létrehozni, utána újra felhasználhatjuk.

Adatbázis beállítása

Miután összekapcsoltuk az adatbázisokat, meg kell adnunk, milyen időközönként szeretnénk futtatni a szinkronizálást. A demóhoz válasszuk a Cron típust és az értéke legyen */1 * * * * ?- innen kimásolva néha hibát okoz. A teszteléshez jó a minél gyakoribb szinkronizálás, valós környezetben ez az igényeknek megfelelően módosítható. A forrásoknál kijelölhetjük, mely táblákat szeretnénk szinkronizálni, illetve kiválaszthatjuk a szinkronizálás módját is. Állítsuk ezt Incremantal Append értékre, így minden szinkronizációs ciklusban csak az új adatok kerülnek másolásra. A Cursor field értéke az elsődleges azonosító legyen — id. Végül a Normalization & Transformation kártyán lehetőségünk van megadni, mi történjen az adatokkal a másolás után. Egyelőre állítsuk nyers adatra. A Normalized tabular data opció megpróbálja visszaállítani az eredeti tábla szerketetét. Ez relációs adatbázisok esetén egész jól működik, dokumentum alapúaknál nem annyira. Később DBT segítségével oldjuk meg a problémát.

Miután összekötöttük az adatbázisokat, a BI adatbázisban megjelennek az nyers adatokat tartalmazó táblák.

Nyers adatokat tartalmazó táblák

A metaadatok mellett az üzleti tábla tartalma JSON objektumként kerül reprezentálásra.

Exported user data

Minden szinkronizációs tábla három oszlopot tartalmaz, egy egyedi azonosítót, az adatokat tartalmazó JSONB oszlopot, valamint a szinkronizáció időpontját.

Airbyte táblaszerkezet

DBT transzformáció

Ahhoz, hogy az adatokkal gyorsan és kényelmesen dolgozhassunk, a megfelelő formátumra kell hoznunk őket. Ehhez DBT-t használunk, mellyel a folyamatot automatizálni tudjuk. A szkriptek minden szinkronizáció után lefutnak és transzformálják az adatokat a megadott módon. A demóhoz használt fájlokat itt lehet böngészni.

A demónak nem célja teljes körű adatbázist felépíteni, illeve a DBT részletes bemutatása sem, de álljon itt pár példa, hogy is néz ki egy transzformáció a gyakorlatban.

A példában a termékeket árának változását nyers adatként tartalmazó _airbyte_raw_* táblából állítjuk elő a termékek hisztorikus adatait tartalmazó táblát, majd ebből a termékek aktuális állapotát tartalmazó újabb táblát. Végül pedig egy viewt, mely a termékek nevét és a hozzájuk kapcsolódó megrendelések számát tartalmazza.

A JSONB objektumból kinyerjük a tábla felépítéséhez szükséges adatokat és a megfelelő formátumra alakítjuk azokat. A Postgres rendelkezik beépített funkciókkal JSON objektumok kezeléséhez.
A DBT által biztosított is_incremental() makró segítségével megoldhatjuk, hogy csak az újonnan szinkronizált adatok kerüljenek feldolgozásra. A konfigurációs fejlécben pedig felvehetjük a létrehozandó tábla indexeit, megadhatjuk az elsődleges kulcsot, mely segítségével a már létező rekordok nem beszúrásra, hanem frissítésre kerülnek.

Termékek hisztorikus adatainak előállítása

A következő lépésben a hisztorikus táblából előállítjuk a termékek táblát. Ez a tábla minden termékhez mindig a legfrissebb árat tartalmazza. Mivel a job az adatok inicializálása után - ahol a név is bekerül - csak az azonosítót és az aktuális árat szúrja be, így a nevet meg kell őriznünk, az árból viszont a legutolsó módosításban szereplőt vesszük.

Termékek tábla létrehozása

A termékek és a rendelések - ez a korábban említett csomagban található - táblák után létrehozzuk az eladott termékszámot tartalmazó nézetet is.

Eladott darabszám termékenként

A modellek elkészítése után nincs más dolgunk, mint hozzárendelni a transzformációkat valamelyik kapcsolathoz. Az Airbyte képes publikus Git repositoryból letölteni a DBT projectet és futtatni. A konfiguráció az alábbi példán látható.

DBT transzformáció beállítása

Mentés után a következő szinkronizálásnál létrejönnek a leírókban megadott táblák.

Metabase

Az utolsó lépésben a diagramokat készítjük el. A Metabase a 10000-es porton érhető el. A regisztráció után az adatbázis kapcsolat felépítése következik. Mivel a Metabase és a BI adatbázis közös Docker hálózatba van kapcsolva, így használhatjuk a konténer nevét hálózati címként.

BI adatbázis kapcsolat paraméterei:

  • host: bi-db-pg
  • port: 5432
  • db name: postgres
  • user/pw: admin/admin123

A kapcsolat felépítése után az adminisztrátor beállításoknál a Data Model tabfülön láthatjuk a használható adatmodeleket, illetve beállíthatjuk a mezők típusát - pl a Products tábla Price mezőjét Currency formátumra, kiválasztva a megfelelő pénznemet, így a diagramokon formázva jelennek meg ezek az adatok.
A séma változások automatikusan frissítésre kerülnek bizonyos időközönként, de amennyiben szeretnénk azonnal látni őket, a Databases tabfülön lehetőségünk van manuális szinkronizálásra indítására is.

Ebben a példában a DBT minden táblát a public sémába készít el. Valós környezetben érdemes csak a megjelenítésre szánt adatokat ide tenni és csak ehhez hozzáférést adni a Matabasenek.

Kilépve az adminisztrátor felületről, a New gomb segítségével hozhatunk létre új diagramot, vagy diagramokat tartalmazó dashboardot. A diagram létrehozásához használhatjuk a beépített no-code editort - questions - vagy akár SQL-t is.
Felmerülhet a kérdés, hogy mi szükség az adatok transzformációjára, ha a Metabase felületén is megírhatnánk a lekérdezéseket. Ennek több oka is van:

  • A tisztított, összemásolt adatokkal könnyebb dolgozni.
  • Gyorsabbak a lekérdezések, így a diagramok renderelési ideje is rövidebb.
  • A jól szervezett adatokkal akár az IT-hoz nem értő kollégák is elkészíthetik a megfelelő dashboardokat.

Érdemes ezért - amennyiben lehetséges - a szükséges adatokat egy-egy fact táblába összefűzni. Így minden diagram egy táblát használ. Figyelni kell azonban arra, hogy a túloptimalizált adatok is okozhatnak problémát.
Erre a korábban létrehozott, termékek eladott darabszámát tartalmazó tábla jó példa, mivel a táblában nem tudunk egy adott időszakra szűrni.

Hozzuk létre az első diagramot. A Question opcióra kattintva kiválaszthatjuk az adatforrást, majd táblát, amivel dolgozni szeretnénk. Ezután összekapcsolhatjuk a forrás táblát más táblákkal, csoportosíthatjuk az adatokat oszlopok szerint, melyen az SQL-ből ismert műveleteket is elvégezhetjük, ahogy az alábbi képen is látható.

Termékek árának válzotása

A Visualize gombra kattintva megjelenik az összeállított lekérdezés eredményét tartalmazó táblázat. Itt további beállításokat is eszközölhetünk.

Kiválaszthatjuk a diagram típust:

Diagram típusok

Beállíthatjuk a tengelyeken megjelenítendő oszlopokat, bonthatjuk az adatokat egy kiválasztott oszlop szerint és sok egyéb lehetőség közül választhatunk a diagram személyre szabáshoz. A mentés gombra kattintva pedig véglegesíthetjük őket.

Termék árának változása

Az elkészült diagramok felhasználásával létrehozhatjuk a dashboardjainkat. Itt beállíthatjuk a méretüket és elhelyezkedésüket.

Dashboard

Az SQL opcióra kattintva az SQL editort is használhatjuk diagram létrehozásához. De akár a no-code editorban létrehozott diagram kódját is módosíthatjuk a segítségével.

Felhasználók összes költése termékenként

A dashboardokhoz definiálhatunk szűrőket, mely segítségével a felhasználók tovább finomíthatják az megjelenő eredményeket. A diagramok a szűrőkben kiválasztott értékek szerint frissülnek.
Figyelni kell arra, hogy míg no-code esetében ezek automatikusan működnek, SQL-nél nekünk kell template változót hozzáadni a lekérdezéshez. Erről itt található részletes leírás.

Szűrő a terméknevekre

Az egyes chartokhoz tartozó adatokat akár le is tölthetjük a kiválasztott formátumban.

Adatok letöltése

A dashboardokat ezután beágyazhatjuk a saját alkalmazásunkba. Továbbá lehetőségünk van a Metabase API-n keresztül egyedi linkeket generálni a dashboardokhoz. Így például megoldható, hogy adott tenant, vagy felhasználó csak a saját adatait lássa - fix szűrőt beállítva például a felhasználó azonosítójára, melyet ő nem lát és nem módosíthat, de a dashboard szűrőjét ugyanúgy tudja használni, például dátum, vagy termék azonosítóra. Ennek részletes leírása itt található.

Láthattuk, hogy egész egyszerűen vizualizálhatjuk az üzleti adatokat. Természetesen a teljes környezetet nem szükséges kézzel felépíteni. Minden itt használt alkalmazás elérhető szolgáltatásként is, ahol néhány egyszerű kattintással beállíthatjuk a rendszerünket. Ez az opció gyorsabb, de természetesen költségesebb is.

--

--

Zalán Tóth
Zalán Tóth

Written by Zalán Tóth

2xAWS, Go, Cloud, Kubernetes, Spring&Kotlin

No responses yet