Úvaha nad horizontálním škálováním databází a těžkostmi s tím spojenými

Škálování databází je velké téma a já rozhodně nejsem takový odborník, abych tady rozebíral kdovíjaké detaily. Zcela jistě znáte termíny jako je sharding, o kterém psal Dagi už před 5 lety, popřípadě znáte termín partitioning, který nám nabízejí některé DB stroje „zadarmo" a jiné „za peníze„. Alternativním způsobem horizontálního škálování je škálování pomocí sady replik pro čtení, o kterém lze uvažovat v případě, že máte aplikaci, které řádově méně zapisuje do databáze než z ní čte. Konkrétně se jedná o to, že máte několik databázových strojů v režimu MASTER-SLAVE(S), který se často nasazuje už jen z důvodu hot-backupu (tj. v případě výpadku master databáze je možné velmi rychle z repliky učinit nový master a pokračovat v běhu aplikace).

Jelikož já i moji kolegové jsme šetřiví, napadlo nás, že by nemuselo být od věci repliku, kterou naše Operations nasadili právě z důvodu hot-backupu využít i pro zrychlení / škálování aplikace. Jsme si samozřejmě vědomi, že tento přístup má svoje riziko - v případě výpadku jedné z databází a přepnutím master databáze na záložní repliku půjdou všechny dotazy původně rozdělené na dva stroje na jeden. Pokud bychom tedy uvažovali o tomto druhu škálování bylo by lepší se bavit o dvou replikách nebo by musela být záloha naddimenzovaná oproti master stroji.

Problém, na kterém jsme se však vždy zarazili, byl spojen s tím, že nemáte garantováno, kdy se v replice objeví stejná data jako na masteru. Zpoždění replikace se může pohybovat pouze v milisekundách, ale může nabývat i vyšší hodnoty. Pokud bychom tedy používali MASTER pouze na zápisy a některý ze SLAVE na čtení, budeme mít problém s tím, že data, která v jednom requestu uživatel vytvoří nemusí nutně v dalším requestu vidět. Ať si kdo chce co chce říká o eventuální konzistenci - tohle je z pohledu BFU zcela jasná chyba, kterou nám bude reportovat a požadovat její odstranění.

Napadaly nás různé možnosti kompenzačních technik, ale všechny byly dost pracné - zvlášť v kombinaci s tradiční relační databází, kdy má uživatel často k dispozici plnou škálu funkcí jako je ad-hoc třídění, filtrování, seskupování atp. Tento týden jsem ale dostal nápad, jak by mohlo být možné relativně jednoduše tento problém řešit a otevřít nám tak cestu k využití replik pro škálování. V tomto článku bych se chtěl o něj s Vámi podělit a třeba přijdete na nějaká úskalí, která mě nedošla a nápad půjde do koše. Když na žádná nepřijdete budu mít větší jistotu, že je nápad životaschopný.

Můj nápad je stojí na znalosti přesné timestamp posledního zápisu uživatele a timestamp posledního synchronizovaného záznamu v replice. Zjednodušeně řečeno - jediné riziko čtení dat z repliky spočívá v tom, že tam ještě nemusí být data, která uživatel právě zapsal. Pokud mám jistotu, že tam data již jsou použiji ke čtení repliku, pokud vím, že tam nejsou použiji ke čtení zase master a budu tak dělat až do doby, než se mi data objeví na replikace. Pak přepnu čtení na repliku. Za předpokladu, že uživatel výrazně více čte z databáze než do ní zapisuje bude z master databáze číst jen velmi málo uživatelů po velmi omezenou dobu.

Diskuzní příspěvky
Zatím zde nejsou žádné zprávy