pátek 11. listopadu 2011

MongoDB - komentář k posledním událostem

V posledním týdnu se po různých diskusích začalo trousit hodně negativní reklamy na MongoDB. Jedním z těch příkladů je anonymní Don't use MongoDB s odpovědí přímo od 10gen. Samozřejmě konkurence si taky přihřála polívčičku ačkoliv to později uvedla na pravou míru. Kdybych to měl shrnout MongoDB je designované s určitými vlastnostmi a vy je buďto akceptujete a budete s nimi počítat a nebo budete nemile překvapeni.

Prvním poměrně zásadním designovým rozhodnutím bylo vypnutí (default) potvrzovacího módu pro write operace. To má za následek, že sice z vašeho pohledu zapíšete data, ale to neznamená, že se data byla ve skutečnosti zapsána na disk. Důvod k tomuto rozhodnutí je přesvědčení autorů, že ne všechny zápisu musí být kritické a zdržovat klienta. Pokud například používáte MongoDB pro sběr logovacích událostí tak vás pravděpodobně nebude mrzet, že některé z nich nebudou za určité konstelace trvale zapsány. Každopádně, a to je důležité zdůraznit, potvrzení zápisu můžete ovládat klientem a to do té míry, že můžete například vynutit zápis na určitý počet replikačních instancí Mongo v clusteru.

Dalším poměrně často kritizovaným aspektem MongoDB designu byla možná korupce datového souboru při pádu serveru. MongoDB používá mapované soubory do paměti a jednou za čas udělá fsync, kterým se zapíše aktuální stav na disk. Může dojít k porušení integrity pokud ustřelíte MongoDB v ten pravý okamžik, potom vám nezbývá nic jiného než pustit recovery. Od verze 1.6 můžete použít žurnál a máte vystaráno. To má sice negativní implikace na výkon zápisových operací, ale v nereplikovaném řešení je to jediná možnost. Pokud provozujete MongoDB v master/slave módu a nebo replica setu, můžete nechat sesynchronizovat porušený node z masteru či dalších replikantů a máte po problému (teorie - nezkošuel jsem zatím).

Posledním designovým rozhodnutím, které bývá často kritizované, je globální read/write zámek. Díky němu si nikdo jiný neškrtne pokud běží zápisová operace. To je docela nemilé, ale... Záleží kolik zápisových operací máte vzhledem ke čtení. Moje domněnka je, že rozhodnutí použít globální zámek udělali, protože je to nejjednodušší způsob, jak vyřešit zamykání dat bez zvýšení paměťové náročnosti (nevýhoda MVCC). Každou novou verzi databáze se optimalizuje výkonnost zkracováním kritické cesty, aby se zámek držel pokud možno co možná nejkratší dobu.

Toliko k nejčastěji uváděným "nedostatkům" nebo designových rysům MongoDB. Celá ta diskuze mi velmi připomíná debatu Ruby on Rails versus zbytek světa asi před třemi lety: "No vy to sice umíte krásně, ale to se nedá použít, protože požadavky se odbavují jeden po druhém. To nemůže nikdo nikdy použít pro reálný projekt". Samozřejmě kdo chce psa bíti hůl si vždycky najde. V tomhle případě se krásně ukázalo, že pokud existuje technické řešení, pak to není vůbec problém. Pokud bych to převedl zpět na MongoDB, firma 10gen si všechno velmi dobře uvědomuje a velmi se snaží všechny defekty řešit a databázi dál vylepšovat.

Nástup NoSQL řešení je změnou paradigmatu, kterým jsme vyvíjeli webové aplikace posledních deset let. Relační databáze jsou nahrazovány alternativními úložišti z různých důvodů, které jsou dostatečně známé. Ten kdo dneska pošilhává po NoSQL řešení by neměl počítat s tím, že dostane hotový produkt typu relační databáze, jinak bude dost zklamaný. Pokud hodláte MongoDB použít mějte všechny tyto věci na paměti.