Vlákno názorů k článku evitaDB: představení rychlé in-memory databáze pro e-commerce od cc - In-memory může být ale tak trochu problém, když...

  • Článek je starý, nové názory již nelze přidávat.
  • 25. 1. 2024 14:37

    cc

    In-memory může být ale tak trochu problém, když ty data začnou růst. Krásný příklad je třeba elastic search. Cute databáze až do doby, kdy člověk začne platit mega měsíčně jen za servery, které se většinu času stejně flákají...

    Chtěl by to benchmarky. Třeba zníměná QuestDB má JIT pro kompilaci dotazů, takže je hodně rychlá, ale JIT má třeba i Tableau, takže to není něco nového a v této oblasti jde momentálně o boom.

    Problém ale opravdu nastává, když ty data jsou obrovské, aneb když se začne čekat na data. Co pak... nejlepší je ty data kompresovat, a pak začíná úplně jiný boj...

    Tím chci říct, že navrhnout in-memory databázi není až takový problém, reálný engineering jde vidět až když ty data se do RAMky prostě nevlezou.

  • 25. 1. 2024 15:03

    Novoj

    U in-memory to riziko skutečně existuje, jak píšete a stejně tak s Vámi souhlasím, že velká data jsou skutečně mnohem náročnější na zkrocení. My se orientujeme ale na doménu, kde je situace trochu specifická. evitaDB je vyhledávací index nad aktuálními daty pro katalogová řešení - neřešíme fulltext index nad logy ani time-series data, které mají potenciál nabobtnat do obřích rozměrů. Zároveň databáze by se neměla "většinu času flákat" - pokud by to tak bylo, Vaše katalogové řešení nikdo moc nenavštěvuje a tím pádem tuhle databázi pravděpodobně nepotřebujete. evitaDB je OLTP, nikoliv OLAP a to ještě se zaměřením na "read-heavy" scénáře.

    My se snažíme vyřešit problém, kdy na omezené sadě dat, která je už ale dostatečně veliká, potřebujeme vyřizovat velké množství dotazů s nízkou latencí. Tj. řešíme náš problém, na který jsme nenašli uspokojivé řešení - a nejde pouze o výkonnost, ale řadu dalších aspektů (viz. další díly seriálu).

    Naše testovací sady obsahovaly cca 100 tisíc entit (prodejních produktů), což vyžadovalo cca 10GB dat paměti, ale to samozřejmě odpovídá použitému datovému schématu. Jiná schémata se 100 tisíci entitami mohou zabírat více i méně paměti podle počtu indexů a dat, podle kterých se dá vyhledávat.

  • 25. 1. 2024 16:23

    Pavel Stěhule

    Tahle databáze cílí na eshopy - a to ještě jednu konkrétní část, takže tam by problém s velikostí být neměl. 100-300GB servery nejsou už extra exotika, a pro vytížený shop se vyplatí. Občas jsem u svých zákazníků viděl, jak pracně navrhují určitá řešení nad Postgresem, a říkal jsem si, že jednoduchá vlastní inmemory databáze pro jejich daný use-case by byla řádově rychlejší. Pokud se vám potřebné struktury vejdou a udrží v RAM, tak nic nemůže být rychlejší. Trochu mám problém s tou Javou, ale i ta se nakonec zkompiluje. Výhodou inmemory databází je, že je možné je napsat poměrně snadno, a můžete si navrhnout speciál pro svůj specifický use case - speciální operace na grafech, stromech nebo maticích. A pokud jsou data immutable, tak nemusíte tolik řešit konzistenci, souběhy.

    Ve výsledku větší zatíženější řešení jsou mix technologií, a funguje je to nejlépe. Předpokladem je realistický pohled na každou technologii, znát výhody, nevýhody, limity.

  • 25. 1. 2024 21:36

    Novoj

    Aby nedošlo k mýlce - databáze je sice in-memory, ale data standardně ukládá na disk, takže při restartu o žádná data nepřicházíte. In-memory je v tom smyslu, že má v RAM všechny vyhledávací indexy - tj. k vyhodnocení dotazu není třeba seek na disku. Pokud si v rámci dotazu zažádáte o další data, která v indexech nejsou, protože se podle nich nevyhledává / netřídí, tak k přístupu na disk dochází. Ale to už je řádově mnohem menší množství fetchů, protože se už jen vyzvednou data z konkrétních pozic na disku.

    Rádi bychom si našli čas na experimentování s CRaC, což by nám mohlo výrazně pomoci s obnovením větší instance databáze zpět do paměti (např. v budoucnosti i na replikách). Aktuálně probíhá jen cold start s postupným načtením indexů z binárních souborů do paměti.

  • 25. 1. 2024 19:06

    B.H.L.

    "Občas jsem u svých zákazníků viděl, jak pracně navrhují určitá řešení nad Postgresem, a říkal jsem si, že jednoduchá vlastní inmemory databáze pro jejich daný use-case by byla řádově rychlejší"
    Hloupá otázka, ale to je tím, že zrovna tuhle fíčuru (tj. držet si data v paměti) Postgres náhodou neumí, nebo je tam nějakej principiélní problém v architektuře těch databází?

  • 25. 1. 2024 21:46

    Novoj

    Rozhodně nejsem PostgreSQL expert - ale v rámci našeho výkonnostního testování jsme měli pronajatou VPS se 128GB RAM (g-32vcpu-128gb na DO), kde se pohodlně celý disk vešel do paměti. Linux se chová tak, že pokud má dostatek volné paměti, tak si do ní ukládá data načtená z disku, takže po zahřátí by teoreticky PostgreSQL vůbec neměla fyzicky chodit na disk. Přesto byla řádově pomalejší, jak naše in-memory implementace.

    Samozřejmě lze namítat, jestli byl návrh DB optimální a jestli jsme databázi zkonfigurovali správně tak, abychom z ní vytáhli co nejvíc. Ale to můžete posoudit sami - zdrojové kódy jsou veřejné.

  • 26. 1. 2024 5:24

    Pavel Stěhule

    Tam spíš půjde o to, jak budete mít nakonfigurované JDBC. Jinak z hlediska konfigurace Pg půjde jen o konfiguraci shared_buffers a možná asynchronního commitu. Posuzovat to nebudu, aby to mělo hlavu a patu, tak bych to musel odzkoušet na nějakém rozumném hw, a pár dní se tomu věnovat, což se mi fakt nechce :-).

  • 26. 1. 2024 5:10

    Pavel Stěhule

    Je tam několik principiálních problémů:

    a) U klasické databáze jsou data na disku v jiném formátu než v paměti, takže když data načítáte, tak neustále musíte dělat konverze. Klasické relační databáze jsou navržené tak, aby mohli nějak fungovat s minimem paměti. Indexy nejsou navržené, aby měly co nejlepší výkon, ale aby se daly serializovat, případně aby se s nimi dalo pracovat, i když se vám vejde do RAM jen relativně malá část, a pořád to ještě bude funkční. Tohle celé u inmemory databází odpodá (za tu cenu, že pokud se vám data nevejdou do RAM, tak inmemory db nefungují nebo mají tragický výkon).

    b) Relační databáze jsou většinou generické (nejsou optimalizované pro nějakou konkrétní úlohu) a jsou to interprety - interpret výrazů, interpret prováděcích plánů, atd. Inmemory databáze tak generické nejsou, mají menší sadu operací, která je zkompilovaná (alespoň větší část).

    c) SQL optimalizátor předpokládá relační model, předpokládá denormalizovanou databázi, předpokládá určité chování statistik nad daty. Pokud něco z toho nemáte - jdete proti relačnímu modelu - např. použitím EAV, tak extra výkon mít nebudete.

    d) SQL optimalizátor má určitou režii plus protokol. To je vidět u extrémně krátkých rychlých dotazů. Pokud nemáte generickou optimalizaci, nedokážete optimalizovat síťovou komunikaci, tak máte brutální overhead, který se projeví u krátkých extrémně častých dotazů (typicky benchmark). U Postgresu je dobré použít socket, prepared statements. Navíc JDBC je dost těžkotonážní interface - předpokládám, že pro přístup s Javy byl použit. To se dá redukovat uloženými procedurami, ale ne všichni tuhle technologii znají. Dovedu si představit, že to co dělá inmemory databáze, bych mohl dosáhnout v Cčkové extenzi Postgresu (ale ne všechno). Ale pro klasického programátora bude jednodušší si napsat vlastní inmemory db v Javě (a použije řadu hotových knihoven, komponent) než napsat Cčkovou extenzi pro Postgres.

    Postgres, pokud máte dost paměti, tak data bude držet v cache datových stránek. Je tam i extenze pg_prewarm, abyste se tato cache rychle zahřála. Problém je, jako u všech klasických databází, že jsou tato data ve formátu v kterém jsou na disku. Když s nimi chcete pracovat, tak je musíte rozbalit, zkonvertovat a tyto konvertovaná data jsou časově omezená na max jeden dotaz, jednu operaci - a jinak to nejde. U klasických databází předpokládáte, že se vám data nevejdou do paměti. Vždy by šlo něco vymyslet, ale pokud nechcete aby vám db lagovala, tak není co moc vymýšlet. Ty klasické databáze nejsou navržené tak, aby vám v nějakých úlohách dávaly nejlepší výkon, ale jsou navržené tak, aby vám ve všech úlohách, které nejdou proti relačnímu modelu, dávaly vždy použitelný výkon. Navrhují se pesimisticky, nikoliv optimalisticky. U inmemory db je to pravý opak.

    Plus máte nějakou režii s garancemi konzistence, s implementací zámků. Inmemory db mohou používat techniky, které jsou jednodušší, rychlejší - mohou používat podobný model jako SQLite. To klasické databáze nemohou - dotazy tam trvají delší dobu, běžně dochází k souběhu, a s jednoduchými řešeními by to ve více uživatelském režimu (máte víc zapisujících procesů) mělo tragický výkon (což je např. vlastnost SQLite).

    Nějaký vývoj směrem k tomu, co dělají inmemory db, je třeba i u Postgresu (u jiných db to nesleduji), např. https://www.orioledata.com/ nicméně obecný názor je, že klasická databáze nemá suplovat inmemory databázi. Cílí to někam jinam, má to jinak uložená data, tudíž i jiné vlastnosti

    Obecně u benchmarků různých technologií je několik problémů - první, že se občas porovnává neporovnatelné, druhý, že se porovnává pouze jeden use case, a třetí - že dost často autoři testů mají expertní znalost pouze jedné technologie, ale už pak jim chybí expertní znalost těch dalších technologií. Plus samozřejmě, že může být zadání, které nějaké technologii prostě sedět nebude.

  • 26. 1. 2024 8:39

    bez prezdivky ...

    Jednak si dovoluju pochybovat o tom, ze nejaky hej nebo pockej navrhne databazi lepe, nez jak je navrzena libovolna univerzalni databaze.

    Dal, kazda svepravna databaze si v ram primarne drzi prave ta data, ktera pouziva. A pokud to ma i fungovat, tak se ocekava, ze cachehit bude vysoko nad 98%. Tudiz ve skutecnosti je v ramce vse, co se pouziva.

  • 26. 1. 2024 9:44

    Pavel Stěhule

    Pro specifické use case může i průměrně dobrý programátor napsat výkonnější inmemory db. Když se dělá analytika, tak agregace nad pamětí v C++ bude minimálně o řád až dva rychlejší než super rychlá relační db. Nejde jen o ten cache hit - ale jde i o to, kolik operací musíte s daty udělat, abyste je mohl používat. Dneska už dost často není brzdou IO, ale CPU.

  • 26. 1. 2024 9:49

    Pavel Stěhule

    Čtení dat, operace nad daty, to je jednoduchá záležitost, když se vám data vejdou do paměti. Zajistit konzistenci, perzistenci, zajistit write cache, paralelní zápis, atd - to už je komplikovaný - ale o tom většinou inmemory databáze nejsou.

  • 26. 1. 2024 13:35

    Pavel Stěhule

    OPRAVA - tam jsem napsal blbost

    c) SQL optimalizátor předpokládá relační model, předpokládá denormalizovanou databázi, předpokládá určité chování statistik nad daty. Pokud něco z toho nemáte - jdete proti relačnímu modelu - např. použitím EAV, tak extra výkon mít nebudete.

    Spravne by melo byt SQL optimalizator predpoklada normalizovanou databazi. - nejak po ranu mi to ujelo.

  • 25. 1. 2024 21:58

    Novoj

    Díky moc za tento názor, velmi věrně kopíruje naše úvahy. Valná většina výpočtů je realizována pomocí množinových operací nad komprimovanými "maticemi" čísel, pro hierarchické vyhledávání máme index ve formě acyklického grafu - takže jste se trefil poměrně přesně.

    Zároveň ale chceme mít některé vlastnosti blízké relačním databázím - máme podporu pro transakce a SNAPSHOT izolaci v duchu MVCC, dokážeme ověřovat konzistenci (tam kde to vývojář bude chtít) a budeme mít i celkem jemně nastavitelnou detekci konfliktů u souběžných transakcí.

    O tom bych chtěl psát v některém z pozdějších dílů seriálu.

    Limity databáze samozřejmě má a snažíme se v tomto být upřímní. evitaDB vidíme jen jako rychlý vyhledávací sekundární index. Na pozadí vždy předpokládáme využití některé z relačních databází. Stejně tak nedoporučujeme ukládat data jen do evitaDB, ale vždy je mít v nějaké primární databázi s vysokými garancemi. Objednávky, košíky, uživatele máme i my takové relační databázi - ale tato data mají úplně jiné potřeby a jiný životní cyklus jak "katalogová data".

  • 26. 1. 2024 11:18

    Ivan Brezina

    Tady plati: "Vy mate Big data? A muzu je videt?" Resil jsem offloading for FullText search z Oracle do Elasticu. E-shop s 10M+ objednavek denne vygeneroval do 100GB dat (se zachovanim 4 mesicu retence).

    Kapacita HW roste, a skutecne dulezita data jsou dnes vlastne hodne mala.
    Jedna vec je davat do Elasticu logy ze serveru, a jina je indexovat jen adresy kam mate dorucit nejake zbozi.

    26. 1. 2024, 11:20 editováno autorem komentáře

  • 26. 1. 2024 17:32

    ardp

    1.
    10M+ objednavek denne ??? To snad byl Aliexpress ? nebo Amazon?

    2.
    Presne tak, vzdycky treba dukladne zvazit, ktre sloupce je nutno indexovat

  • 27. 1. 2024 23:50

    cc

    Co třeba 10 PB?

    100GB je opravdu nic. Navíc 100GB by se dalo asi i hezky zkompresovat a pořád docílit průchod třeba 2-5GB/s na jádro podle komprese a datového formátu, takže i brute-force query bez indexů by na nějakém 64 core Epicu trval třeba půl sekundy. Ale asi ne s Elasticem, který nemá v podstatě žádné optimalizace a i blbá distance query se dá napsat 20x rychlej.