27. 4. 2026 | Řešení
evitaDB dostala zásadní vylepšení
Koncem roku 2024 jsme psali o prvních zkušenostech z nasazení naší inovativní e-commerce databáze evitaDB na produkci projektu Milagro.cz. Pro našeho zákazníka to byl mimořádně úspěšný rok a dodnes pokračuje ve stejném duchu. Databázový stroj od té doby značně vyspěl a v tomto článku se o tyto novinky s vámi rádi podělíme.

evitaDB je standardní součástí všech našich nově spouštěných e-commerce projektů – běží na pozadí projektů jako Moser, GiftUp či Ryor. Je také plně připravena u několika dalších velkých projektů, o kterých vám jim brzy dáme vědět.
Kontejnerizace a provoz v Kubernetes
Jedním z hlavních milníků je postupná migrace projektů na platformu Kubernetes, která umožňuje snadné škálování aplikačních služeb, jejich orchestraci a správu životního cyklu. Provoz databázového řešení v Kubernetes (dále jen K8S) clusteru má svá specifika. Ačkoliv je databáze publikovaná ve formě Docker image od svého počátku, s nasazením a provozem v K8S nás čekalo dořešení řady úloh:
- správné nastavení Stateful Sets a parametrizace databáze,
- napojení a sbírání metrik a logů do centrálního logovacího systému,
- vyladění zálohovacího mechanismu,
- spolehlivý mechanismus aktualizací.
Vše jsme úspěšně dotáhli do konce a výsledkem je skutečně bezvýpadkový provoz a aktualizace databází u našich klientů.
Paralelizace operací a streaming
Přibližně před rokem jsme všechna webová API poskytovaná evitaDB, přenesli na webový server Armeria. Tento server staví na reaktivním přístupu a velmi přísně hlídá časové limity odpovědi, jak na straně serveru, tak i klienta. Některé operace jsou z podstaty déletrvající (např. záloha databáze, načtení databáze do paměti, případně commit větších bloků dat), což znamenalo komplikace právě v kombinaci s časovými limity.
Abychom se těchto obtíží zbavili jednou provždy, všechny takové operace jsou nyní na straně serveru prováděny asynchronně, často také paralelizovány pomocí work-stealing techniky, a na klienta se streamuje (tj. průběžně odesílá) informace o podílu odvedené práce v procentech.
Streamování částečných odpovědí v gRPC a dalších protokolech efektivně zabraňuje předčasným ukončením spojení kvůli časovým limitům. Na úrovni Java klienta je veškerá související komplexita zakryta jednoduchým rozhraním, které nabízí i jednoduché (blokující) metody s jednoduchou návratovou hodnotou, které vrátí odpověď až ve chvíli, kdy celý tento paralelizovaný, streamující mechanismus plně dokončí svou práci. Vývojáři používající naše API tak nemusí zabředávat do komplexit, které jsou na pozadí, pokud o to vyloženě nebudou stát.
Kromě praktických potřeb na úrovni API mají tyto změny i na dobu zpracování jednotlivých operací. Díky správné dekompozici práce došlo na strojích s více CPU ke zrychlení startu evitaDB, jelikož indexy se do paměti načítají paralelně a databáze dokáže při svém startu chvilkově využít veškeré dostupné hardwarové prostředky a nastartovat v nejkratším možném čase.
Paměťové optimalizace
evitaDB udržuje všechny indexy v paměti, proto jejich správu průběžně optimalizujeme. Výsledkem je stále efektivnější využití RAM pamětí.
Rozlišení úrovní indexace pomocí schématu
Nově umožňujeme na úrovni schématu určit množství indexů, které jsou pro jednotlivé vazby mezi entitami uchovávány. Odlišujeme 2 typy indexů:
- pro prosté filtrování
- pro filtrování a partitioning
Druhý typ udržuje separátní index pro každou entitní vazbu a můžeme si ho popsat jednoduše: představme si, že potřebujeme nalézt všechny produkty zařazené do konkrétní kategorie, které zároveň splňují desítku dalších podmínek (jsou zveřejněné, aktuálně platné, mají dostupnou cenu v ceníku uživatele a měně CZK atd.). Takový dotaz můžeme vyhodnotit nad jedním velkým indexem, kde jsou tyto informace pro všechny známé produkty v databázi, a nebo (pokud použijeme partitioning) využijeme mnohem menšího indexu, ve kterém nalezneme všechny tyto potřebné informace jen pro produkty, které mají platnou vazbu právě na kategorii, pro kterou tento dotaz vyhodnocujeme. Zcela logicky bude odpověď na dotaz výrazně rychlejší, protože prohledávané množství dat je výrazně menší.
Starší verze evitaDB implicitně používaly pro všechny indexované vazby druhou možnost, což ale realizované aplikace v mnoha případech vůbec nepotřebovaly. Rozdělením tohoto přístupu a umožněním nastavit požadovanou úroveň indexace pomocí schématu jsme v řadě případů ušetřili i více jak 50 % původně požadované RAM.
Archivace entit
Další úpravou umožňující snížit spotřebu paměti je rozdělení entit do různých “prostorů” (scopes). V e-commerce je běžné, že produkty zůstávají v katalogu dostupné i mnoho let potom, co se přestaly prodávat (ať už jsou důvody SEO nebo třeba dohledatelnost návodů či technických specifikací). Postupně může být takových produktů v databázi netriviální množství.
Tyto produkty se obvykle nevyskytují ve výpisech produktů, ale jsou dostupné pouze pomocí odkazů z objednávek, fulltextového vyhledávání nebo přístupem na konkrétní URL adresu. Je proto zbytečné, aby tyto produkty zabíraly místo v indexech spolu s ostatními aktivními produkty.
Pro tyto účely evitaDB poskytuje tzv. “archivní prostor”, do kterého umožňuje přesunout libovolnou ze spravovaných entit. Archivnímu prostoru je možné nastavit odlišné parametry indexace a tím ušetřit nemalou část paměti. Archivované entity mají navíc zcela separátní indexy, takže pokud nás v rámci dotazu zajímají pouze aktivní entity, nezdržuje se databázový stroj vůbec prohledáváním archivních dat. Pokud vás zajímá více praktických informací použití těchto “prostorů” v dotazovacím jazyce, přečtěte si tento článek.
Komprese dat na disku
Ačkoliv prostor na persistentním úložišti (disku) je mnohem levnější než kapacita RAM, snažíme se optimalizovat spotřebu i zde. Zároveň nejde jen o spotřebu prostoru jako takovou – čím méně dat je třeba přečíst z disku, který stále zůstává nejpomalejším článkem v řetězci, tím rychlejší je zpracování odpovědí na dotazy a tím lépe je i utilizována souborová cache operačního systému.
Nově je možné zapnout datovou kompresi, která komprimuje data každého jednotlivého záznamu ukládaného na disk. Zapnutím komprese dochází v průměru k 50% úspoře dat diskového prostoru. V současnosti používáme jednoduchý kompresní algoritmus ZIP, ale do budoucna zvažujeme vyzkoušení dalších algoritmů, jako například ZSTD, LZ4 nebo Snappy.
Zálohování
Kromě zálohy aktuálních dat (snapshot) a zálohy dat z konkrétního časového okamžiku v dostupné historii (point-in-time), je nyní možné vytvořit i kompletní zálohu, která obsahuje celou historii dat a po jejíž obnově je možné na ní provádět další point-in-time analýzy a obnovení. Všechny typy záloh jsou jednoduše dostupné z grafického rozhraní evitaLab.

Rozšířené možnosti 1:N vazeb
Vícenásobné vazby mezi entitami přinášejí mnoho zajímavých komplexních problémů. Na ně v tomto článku není prostor, a proto zájemce odkážeme na separátní článek přímo na blogu evitaDB.
Jedním z takových problémů je například korektní řazení v rámci hierarchické struktury (např. kategorií), do které je entita přiřazena vícenásobně (např. produkt ve více různých kategoriích). V rámci evitaDB dokážeme nyní kontrolovat chování řazení a výpisu takových entit, ať už specifikací procházecího algoritmu (do hloubky, do šířky), či dvouúrovňovým řazením – tj. specifikací pořadí procházení na úrovni stromu (např. kategorií) a zároveň specifikací řazení položek v uzlu (např. produktů v dané kategorii).
Další výraznou novinkou jsou duplicitní vazby. Původní návrh evitaDB nepočítal s tím, že by jedna entita mohla mít 2 a více vazeb na stejnou jinou entitu. Původním předpokladem bylo, že takové vazby by se odlišily pomocí samostatného druhu vazeb. Bohužel se ukázalo, že to komplikuje portabilitu dotazů v aplikacích.
Konkrétním příkladem je třeba vazba mezi produktem a souborem – u produktu máme typicky jeden z obrázků jako hlavní motiv produktu, další sada je v galerii produktu, můžeme mít zákaznickou galerii fotografií, technické listy, certifikáty produktu atp. Ukázalo se nepraktické mít pro každou takovou skupinu souborů separátní vazbu, a cílem je mít ve schématu vazbu pouze jedinou: produkt → soubor.
Nicméně v praxi se často stává, že ten stejný soubor je k produktu přiřazen vícenásobně – jednou jako hlavní motiv a zároveň je i jako jeden z obrázků v galerii. Podobných situací se v reálných nasazeních vyskytuje více. Proto jsme v posledních verzích evitaDB umožnili definici duplicitních vazeb ve schématu, které se odlišují unikátností kombinace konkrétních vazebních atributů.
To umožní celkem praktické použití například v GraphQL dotazech:

Praktické dopady těchto nových možností však sahají za rámec tohoto článku a budou pravděpodobně rozebrány v některém z dalších článku na blogu evitaDB.
Change data capture
Klíčovým milníkem k replikovanému běhu databáze v rámci clusteru je zpřístupnění záznamů ve Write-Ahead-Log (dále WAL) pomocí tzv. change data capture (dále CDC) okolnímu světu a zároveň zavedení žurnálování operací na všech úrovních systému. Historicky jsme používali WAL na úrovni jednotlivých katalogů, ale nově byl zaveden i na úroveň celého systému databáze – tzv. engine level WAL. Ten zachycuje základní práci s databází, jako je vytvoření katalogu, jeho odstranění, přejmenování atp.
Tato data jsou nyní kompletně zpřístupněna jak pro historické procházení, tak i formou streamovaného posílání všem zaregistrovaným zájemcům (aplikacím) téměř v reálném čase. Tento způsob spočívá v tom, že klient si zaregistruje odběr změn v databázi, které odpovídají sadě jím stanovených podmínek (např. informuj mě o tom, že se změnila cena u produktu s primárním klíčem 475). Databáze následně pošle klientovi informaci o tom, že tato konkrétní změna proběhla ve chvíli, kdy ji zapracovala do sdíleného pohledu na data (tj. změna vešla v platnost).
Odběr těchto změn je možné přes všechny podporované webové protokoly i nativní API. V protokolu gRPC používáme jeho podporu streaming volání, v GraphQL protokolu využíváme principu subscriptions přes tzv. web-socket. REST API žádnou standardizaci pro tyto účely nemá, a proto jsme u něj použili podobný mechanismus jako v případě GraphQL. Implementační detaily jsme shrnuli v obšírnějším článku na našem blogu.
Princip CDC nám dává do budoucna základní platformu pro replikaci změn v cluster prostředí, ale zároveň dává i silný nástroj klientským aplikacím, které pro něj mají řadu praktických využití – ať už se jedná o invalidaci keší, realizaci holandských aukcí nebo prostou aktualizaci stavu skladů pro extrémně senzitivní produkty.
Developer experience
Zážitek vývojáře při používání evitaDB je pro nás jedním z klíčových parametrů. Proto investujeme stovky hodin do revizí a rozvoje API, i naší webové konzole evitaLab.
evitaLab Desktop
Databázovou konzoli si můžete nově stáhnout i jako desktopovou aplikaci pro nejčastější operační systémy (Linux, MacOS, Windows). Výhodou desktopové aplikace je možnost centralizovaného napojení na různé instance evitaDB v různých verzích. Z jednoho prostředí tak máte na pár kliknutí možnost připojit se do libovolné instance, kterou provozujete. O desktopové verzi pojednává další z článků na blogu evitaDB.
Nahrávání provozu
Do databázové konzole jsme za poslední rok přidali spoustu nových funkcí. Jednou z nich je nástroj pro “nahrávání provozu” databáze. Ten na pozadí nahrává buď všechny, nebo vzorek dotazů do databáze, který je následně možné analyzovat v interaktivním rozhraní a jednotlivé dotazy opakovaně spouštět. Pro snadnější identifikaci dotazů dotazovací jazyk nově podporuje koncept štítků.
Nahrávku provozu lze i exportovat a do budoucna bychom chtěli připravit nástroj pro přehrávání tohoto provozu, kterým by bylo možné odhadovat zatížení serveru na různých konfiguracích, či znásobovat provoz a odhalovat výkonnostní limity řešení. Kromě jiného toto umožní i lepší ladění výkonnosti databázového stroje jako takového.
Žurnál změn
Díky mechanismu CDC chystáme v blízké budoucnosti do databázové konzole interaktivní prohlížečku žurnálu změn v databázi. Díky ní si bude moci nejen vývojář, ale i běžný uživatel snadno vyfiltrovat poslední změny spojené s určitou entitou v databázi, či nějakou její součástkou – tj. konkrétním atributem, cenou apod. Díky úplnému přístupu k dané změně, vazbě na konkrétní transakci a časové značce, si bude moci znalý uživatel lépe poskládat obrázek toho, co a kdy se s daty v databázi dělo.
Spolehlivost
Automatických testů není nikdy dost a jen díky nim jsme schopni stále dělat zásadní změny v implementaci evitaDB, aniž by se degradovala její kvalita. Za rok narostl počet jednotkových a integračních testů z 5400 na 7500 a spolu s dalšími 1200 testy v dokumentační části věříme, že příští rok se přehoupneme přes magickou hranici 10 tisíc při zachování pokrytí kódu testy téměř na úrovni 75 %. Celá sada testů díky paralelnímu běhu i na pomalejších strojích běží nízké jednotky minut, a tudíž si můžeme dovolit ten luxus spouštět celou sadu testů s každou změnou v databázi.
Nově jsme do konfigurace evitaDB přidali možnost vypnutí fSync, které cílí na zvýšení rychlosti databáze při použití v automatických testech. V případě námi využívané e-commerce platformy Edee.one jsme tím dosáhli 25% zrychlení.
Závěrem
Vývoj evitaDB jde stále kupředu a umožňuje našim zákazníkům realizovat požadavky, které by byly s použitím standardních databázových řešení nemožné a značně by komplikovaly implementaci aplikací jako takových.
Tím, že řadu komplexních problémů řeší databáze na té nejnižší úrovni, umožňujeme aplikačním vývojářům věnovat energii byznysovým problémům a těžkou práci delegovat na spolehlivého parťáka, či v tomto případě spíše parťačku – evituDB.


