Történetek Korábbi munka, 2020–2022
Kerékcsere menet közben
Egy több tíz terabájtot archiváló monolit migrálása microservice architektúrára, miközben a rendszer zavartalanul üzemelt
Írta: Fejér Attila Megjelent:
Egy rendszer több tíz terabájtnyi érzékeny személyes adatot archivált és tett kereshetővé. A backend egy monolit volt, mellette néhány biztonsági résekkel teli service, egy elavult webes frontend és egy asztali vastagkliens, amelynek szüksége volt a titkosítási kulcsra a működéséhez. Egy tízfős csapatot vezettem, amely nagyjából másfél év alatt, darabonként írta át a rendszert microservice-ekre. A rendszer közben végig élesben futott, és új funkciókat is kapott. A régi rendszer havonta nagyjából 2 TB-nál elérte a határát. Az új havonta 11 TB-ot archivált, és a határait sosem értük el.
- Havi archiválás
- előtte kb. 2 TB, utána 11 TB, a határt nem értük el
- Rendelkezésre állás
- 99,99% az átállás alatt, az ügyfél-SLA-k monitorozása szerint
- Csapat és idő
- tíz fő, nagyjából másfél év
Előzmények
A rendszer nagy, néha egyenként több terabájtos adatfájlokat fogadott, archivált és tett kereshetővé. Az adatok személyes információkat is tartalmaztak, ezért titkosítani kellett őket. A backend egy monolit volt, mellette néhány biztonsági résekkel teli service. A felhasználók egy elavult single-page webes frontendet és egy Swingben írt asztali alkalmazást használtak. Az asztali kliensnek a működéshez szüksége volt a titkosítási kulcsra, pedig annak soha nem szabadna elhagynia a szervert.
A rendszer egyáltalán nem skálázódott horizontálisan, az üzletnek pedig olyan új funkciókra volt szüksége, amelyeket a régi felépítés mellett nehéz volt hozzáadni. Néhány kicsi, jól körülhatárolt feladatnak több száz példányban kellett volna egyszerre futnia, a rendszer többi részének nem, és előre nem tudhattuk, melyik feladatokról lesz szó, mert ez a terheléstől függött. Néhány adatstruktúra ráadásul rosszul volt megtervezve.
A fejlesztők nem szerettek a régi kódbázisban dolgozni. Az átállás az én javaslatom volt és a csapat döntése, a vezetőség pedig azért támogatta, mert nem egy lépésben írtuk újra az egészet. A strangler fig mintát követve darabonként cseréltük le a rendszert, amely közben végig élesben maradt.
A megoldás
A frontenddel kezdtük, mert a felhasználói élmény volt a leggyengébb pont. Az új frontenddel együtt egy API-réteget is készítettünk: egy contractot, amelyre a frontend támaszkodott, és amely mögé elrejthettük a szervert és minden változtatást. Ahogy a service-ek egyenként kikerültek a monolitból, a frontend ebből semmit sem vett észre. A frontend újraírása közben feltérképeztük a felhasználói utakat is, így a service-ek határait aszerint húztuk meg, amit a felhasználók ténylegesen csináltak.
Amint az új frontend élesbe került, az asztali kliensre nem volt többé szükség, és a titkosítási kulcs a szerveren maradt. A frontend már visszafejtve kapta az adatot. A régi rendszer teljesen szinkron volt, az új pedig, ahol csak lehetett, eseményvezérelt, Kafka alapokon. Minden service függetlenül tudott horizontálisan skálázódni, így egy service akár több száz példányban is futhatott anélkül, hogy a rendszer többi részét is skálázni kellett volna.
A korábbi egyetlen dokumentum-adatbázis mellett Postgrest, Redist és object storage-ot is elkezdtünk használni. A rosszul megtervezett adatstruktúrák adatait optimalizált struktúrákba költöztettük át. Minden adattípusért egyetlen service volt felelős, és minden olvasás és írás ezen keresztül történt. A határt nem adatbázisonként húztuk meg, hanem adatonként: egy collection tartozhatott egyetlen service-hez, egy közös collectionben pedig a dokumentumtípusok egy része az egyik service-hez tartozhatott, a többi egy másikhoz.
Az asztali kliens korábban egyetlen szálon töltötte fel az adatot. Az új rendszerben külön service-ek darabolták fel a fájlokat, irányították a feltöltést, és végezték el szerver-szerver kommunikációval egy object storage-ba.
Eredmények
A régi rendszer havonta nagyjából 2 TB-nál elérte a határait. Az új havonta 11 TB-ot archivált, és a határát sosem értük el. A rendelkezésre állás 99,99% volt, amíg a rendszeren dolgoztam, az ügyfél-SLA-k mögötti monitorozás szerint. A korábban percekig futó lekérdezések másodpercek alatt lefutottak, az órákig készülő riportok pedig a háttérben készültek el, miközben az alkalmazás végig használható maradt. A cloud-költségek is csökkentek.
A fejlesztői élmény is javult. Minden adattípus szabályait központosítottuk az érte felelős service-ben. Emiatt inkonzisztens állapotot is nehéz lett előidézni. A deployok gyorsabbak és biztonságosabbak lettek, a fejlesztők anélkül dolgozhattak párhuzamosan különböző funkciókon, hogy egymás lábára lépnének, egy új funkcióról pedig általában egyértelmű volt, melyik service-be kerül. Ha nem, a tervezésen eldöntöttük, hová tartozik.
A tanulság
A service-ek határait bizonyítékok alapján húzom meg. Itt rengeteg valós használatból tanulhattunk, és a rendszer részeinek nagyon eltérő volt a skálázási igénye, így a határok könnyen kirajzolódtak. Egy új rendszert inkább moduláris monolitként kezdek, mert még nem tudom, melyik vágás éri meg a hálózati kommunikáció költségét. A microservice-ek az elosztott rendszerek problémáit magukkal hozzák, ezért csak jó okkal választom őket: például ha sok csapat dolgozik egy rendszeren, vagy ha bizonyos részeknek eltérő skálázási követelményeik vannak.
A modularitás a lényeg. Az eredeti monolit kaotikus volt, kiemelhető modulok nélkül. Egy moduláris monolitban, ahol minden modul egy adapter mögött van, egy modul később átköltözhet a saját service-ébe anélkül, hogy a többiek észrevennék.
További történetek
Minden korábbi munka Minden történet
Továbbiak fejlesztőcsapatoknak
Korábbi munka 2026
Feltétel nélkül
Feature flagek interfészként és osztályként, hogy a hívás helyén látszódjon, mit csinál a kód, a többit pedig a fordító ellenőrizze
Miért kezdtem el fejleszteni a FlagZent, egy nyílt forráskódú dispatch réteget Java feature flagekhez: mi a szétszórt feltételek ára, mit ellenőrizhet helyettük a fordító, és hol tart ma a projekt.
ElolvasomEsettanulmány 2024–2026
XP coaching 300+ Fortune 100-es csapatnál
Két év, nagyjából 1 000 coacholt ember, és körülbelül 10%-kal jobb átfutási idő (lead time) és hibás változtatások aránya (change failure rate)
Hogyan vitte el egy Fortune 100-as pénzügyi cég a csapatait az extreme programming felé: mit változtatott két hét tanteremben és hat hét a csapatok mellett, és mely szokások élték túl a coachok távozását.
ElolvasomKorábbi munka 2017–2019
Oszd meg és cache-elj
Egy kezdőoldal, amely 300 felhasználónál 10 másodperc alatt töltődött be, majd egy lekérdezés négyre bontása után 2000 felhasználónál 20 ms alatt
Közvetlenül egy közszféra-platform első élesítése előtt a kezdőoldal nem bírta a terhelést. Hogyan találtuk meg a profilozással az okot, miért nem segített az indexelés, és mi lett a megoldás.
ElolvasomHol válna szét az Önök rendszere?
Egy rövid beszélgetés az architektúrájukról, és arról, mi lassítja a változtatást. Javaslattal távoznak, ami akár az is lehet, hogy maradjon a monolit.