Posledni rok nelze v technologickem svete otevrit RSS ctecku, aniz by clovek nenarazil na clanek o NoSQL databazich. MongoDB, CouchDB, Cassandra, Redis — kazda slibuje neco jineho, ale vsechny sdili jednu myslenku: relacni model neni jedina cesta. Jako tym, ktery posledni dekadu pracuje s Oracle a PostgreSQL, jsme se rozhodli proverit, zda je NoSQL hype, nebo skutecna zmena paradigmatu.
Proc vznikly NoSQL databaze¶
Termin NoSQL se poprve objevil v roce 2009 na konferenci v San Franciscu, ale myslenka nerelacniho uloziste je mnohem starsi. Hlavni hybatel byl jednoduchy — webové aplikace jako Facebook, Google a Amazon museli zpracovavat takove objemy dat a takovy pocet pozadavku, ze tradicni relacni databaze proste nestacily. Oracle muze byt sebevykonnejsi, ale kdyz potrebujete horizontalni skalovani pres stovky serveru, relacni model s jeho JOINy, transakcemi a normalizaci se stava brzdou.
Google publikoval paper o Bigtable v roce 2006, Amazon predstavil Dynamo v roce 2007 a tyto prace inspirovaly celou generaci open-source databazi. Cassandra vznikla ve Facebooku, HBase implementuje Bigtable model na Hadoopu, MongoDB prisla s dokumentovym modelem, ktery je intuitivni pro webove vyvojare. Kazda z techto databazi dela kompromis — vymeni neco z ACID vlastnosti za skalovatelnost, flexibilitu nebo vykon.
Dokumentovy model MongoDB¶
MongoDB je dokumentova databaze, coz znamena, ze data uklada jako JSON-like dokumenty (interni format je BSON — Binary JSON). Kazdy dokument muze mit jinou strukturu, neni potreba predem definovat schema. To je fundamentalní rozdil oproti relacnim databazim, kde musite vytvorit tabulku s pevne danymi sloupci, nez do ni muzete vlozit data.
Pro webove vyvojare je tento model prirozeny. Kdyz vase aplikace pracuje s JSON objekty (a v roce 2011 skoro kazda webova aplikace pracuje s JSON), muzete je ulozit primo do databaze bez nutnosti mapovani na relacni schema. Zadny ORM, zadne impedance mismatch. Dokument v MongoDB muze obsahovat vnorene objekty a pole, coz umoznuje modelovat slozite datove struktury v jednom dokumentu misto vice propojenych tabulek.
Kdy MongoDB dava smysl¶
MongoDB exceluje v situacich, kde schema neni predem zname nebo se casto meni. Typicky priklad jsou katalogove systemy — kazda kategorie produktu muze mit jine atributy. V relacni databazi byste resili EAV pattern (Entity-Attribute-Value) nebo meli desitky nullable sloupcu. V MongoDB proste kazdy produkt ma presne ty atributy, ktere potrebuje.
Dalsi skvely use case je logovani a analytika. Logy maji promenlivou strukturu a objem roste exponencialne. MongoDB zvlada vysoky write throughput a s capped collections nabizi automatickou rotaci starych dat. Pro agregaci nad logy pouzivame MapReduce — coz neni tak pohodlne jako SQL GROUP BY, ale pro velke objemy dat je to efektivnejsi.
Content management systemy jsou dalsi prirozeny fit. Clanky, stranky, komentare — kazdy typ obsahu muze mit jinou strukturu a vnorene komponenty. MongoDB umoznuje ulozit celou stranku jako jeden dokument vcetne metadat, tagu a komentaru. Cteni je pak jediny dotaz misto sloziteho JOINu pres pet tabulek.
Kdy MongoDB NEDAVA smysl¶
A ted ta dulezita cast — kdy NoSQL pouzivat nemáte. Pokud vase data maji silne relacni vazby a potrebujete konzistentni transakce pres vice entit, relacni databaze je stale lepsi volba. Bankovni system, kde prevod penez musi byt atomicky (odecist z jednoho uctu a pricist na druhy v jedne transakci) — to s MongoDB neudelate spolehlive. MongoDB nema multi-document transakce.
Reportovani a ad-hoc dotazy jsou dalsi slabina. SQL je neuveritelne expresivni jazyk pro dotazovani dat. MongoDB query language je omenenejsi — slozite agregace vyzaduji MapReduce, ktery je pomaly a obtizne debugovatelny. Pokud vasi analyti potrebuji denne psat nove dotazy nad daty, Oracle s SQL Developer bude porad produktivnejsi nez MongoDB shell.
Take pozor na duplikaci dat. V relacnim modelu je adresa zakaznika na jednom miste a vsechny objednavky na ni referuji. V MongoDB byste adresu mohli embedovat do kazde objednavky — coz je rychle pro cteni, ale kdyz zakaznik zmeni adresu, musite aktualizovat vsechny dokumenty. Toto je zakladni tradeoff dokumentoveho modelu.
Skalovani — sharding a replica sets¶
Jednou z hlavnich vyhod MongoDB je nativni podpora horizontalniho skalovani. Sharding rozdeli data pres vice serveru podle shard key — napriklad podle ID zakaznika. Kazdy shard obsahuje podmnozinu dat a MongoDB router (mongos) automaticky smeruje dotazy na spravny shard. Pridani noveho shardu je relativne jednoduche a MongoDB automaticky rebalancuje data.
Replica sets zajistuji vysokou dostupnost. Kazdy shard ma primarni uzel a jeden nebo vice sekundarnich uzlu, ktere replikuji data asynchronne. Pokud primarni uzel spadne, sekundarni uzel je automaticky zvolen jako novy primarni. Toto je vyrazne jednodussi nez nastavovani Oracle RAC nebo PostgreSQL streaming replication.
Ale pozor — asynchronni replikace znamena, ze pri failoveru muzete ztratit data, ktera jeste nebyla replikovana. MongoDB nabizi write concern nastaveni, kde muzete vyzadovat potvrzeni zapisu od majority uzlu, ale to snizuje vykon. Je to vzdy kompromis mezi konzistenci a vykonem.
Nase zkusenosti z pilotniho projektu¶
Rozhodli jsme se vyzkouset MongoDB na internim projektu — system pro spravou konfigurace nasich serveru. Kazdy server ma jinou sadu sluzeb, ruzne parametry a historii zmen. V relacnim modelu by to bylo pet tabulek s mnoha nullable sloupci. V MongoDB je kazdy server jeden dokument s presne temi atributy, ktere potrebuje.
Prvni dojem byl skvely — vyvoj sel rychle, nemuseli jsme resit migrace schematu a dotazy byly intuitivni. Problem prisel, kdyz jsme potrebovali hledat servery podle kombinace atributu — MongoDB vyzaduje indexy na kazde pole, ktere chcete efektivne prohledavat, a compound indexy maji svá omezeni. Druhy problem byla absence JOINu — kdyz jsme chteli zobrazit servery s informacemi o jejich datacentru, museli jsme delat dva dotazy a spojovat data v aplikaci.
Na druhou stranu, pridani noveho atributu ke konfiguraci serveru bylo trivialni — zadna ALTER TABLE, zadna migrace, proste jsme zacali ukladat novy atribut. Pro system, ktery se rychle vyviji, je tato flexibilita k nezaplacení.
Srovnani NoSQL databazi¶
MongoDB neni jedina NoSQL databaze a kazda ma svou niku. CouchDB je take dokumentova databaze, ale pouziva HTTP API a ma vestaveny konflikt resolution pro offline-first aplikace. Cassandra je sloupcova databaze optimalizovana pro extremne vysoky write throughput — idealni pro logovani a IoT data. Redis je in-memory key-value store skvely pro cache a session management. HBase bezi na Hadoopu a je urcen pro analyticke workloady nad petabajty dat.
Vyber spravne databaze zavisi na vasem use case. Neexistuje univerzalni odpoved. Casto je nejlepsi reseni polyglot persistence — pouzivat vice databazi v jedne aplikaci, kazdou pro to, v cem je nejlepsi. Relacni databaze pro transakce, MongoDB pro flexibilni dokumenty, Redis pro cache, Elasticsearch pro fulltextove vyhledavani.
CAP teorem a realita¶
Kdyz mluvime o NoSQL, musime zminit CAP teorem. Eric Brewer formuloval hypotezu, ze distribuovany system muze splnovat maximalne dve ze tri vlastnosti: Consistency (konzistence), Availability (dostupnost) a Partition tolerance (odolnost proti rozdeleni site). V praxi to znamena, ze pri sitovem problemu si musite vybrat — bud budete vracet stara data (AP system) nebo budete nedostupni, dokud se sit neobnovi (CP system).
MongoDB je CP system — pri nedostupnosti primary uzlu je cast dat docasne nedostupna, dokud probehne election noveho primary. Cassandra je AP system — vzdy odpovi, ale muze vratit stara data. Tradicni relacni databaze na jednom serveru proste ignoruji partition tolerance, protoze nemaji distribuci.
Zaver¶
NoSQL databaze nejsou nahradou relacnich databazi — jsou doplnkem. MongoDB je skvela volba pro flexibilni schema, vysoky write throughput a horizontalni skalovani. Ale pro transakce, slozite dotazy a silne relacni data zustavame u PostgreSQL a Oracle. Budoucnost je v polyglot persistence — spravna databaze pro spravny problem.