Nejlepší přístup pro shardování tabulek MySQL je neprovádět, pokud to není zcela nevyhnutelné.
Když píšete aplikaci, obvykle to chcete dělat způsobem, který maximalizuje rychlost a rychlost vývojáře. Latenci (čas do připravenosti odpovědi) nebo propustnost (počet odpovědí za časovou jednotku) optimalizujete pouze v případě potřeby.
Rozdělíte a poté přiřadíte oblasti k různým hostitelům (=fragment) pouze v případě, že se součet všech těchto oblastí již nevejde do jedné instance databázového serveru – důvodem je zápis nebo čtení.
Případ zápisu je buď a) frekvence zápisů trvale přetěžuje disky tohoto serveru nebo b) probíhá příliš mnoho zápisů, takže replikace trvale zaostává v této hierarchii replikace.
Případ čtení pro sharding nastane, když je velikost dat tak velká, že se jejich pracovní sada již nevejde do paměti a čtení dat začne narážet na disk, místo aby byla většinu času obsluhována z paměti.
Pouze když máte abys to udělal.
Ve chvíli, kdy střípíte, za to platíte několika způsoby:
Velká část vašeho SQL již není deklarativní.
Normálně v SQL říkáte databázi, jaká data chcete, a necháte na optimalizátoru, aby tuto specifikaci proměnil v program pro přístup k datům. To je dobrá věc, protože je flexibilní a protože psaní těchto programů pro přístup k datům je nudná práce, která poškozuje rychlost.
Ve sdíleném prostředí pravděpodobně spojujete tabulku v uzlu A s daty v uzlu B nebo máte tabulku větší než uzel v uzlech A a B a spojujete data z ní s daty v uzlu B a C. Začínáte psát řešení spojení založená na hash na straně aplikace ručně, abyste to vyřešili (nebo znovuobjevujete cluster MySQL), což znamená, že skončíte se spoustou SQL, které již nejsou deklarativní, ale vyjadřují funkčnost SQL procedurálním způsobem. (např. používáte příkazy SELECT v cyklech).
Vystavujete se velké latenci sítě.
Normálně lze dotaz SQL vyřešit lokálně a optimalizátor ví o nákladech spojených s přístupy k místnímu disku a řeší dotaz způsobem, který minimalizuje náklady.
Ve sdíleném prostředí jsou dotazy řešeny buď spuštěním přístupů klíč–hodnota přes síť do více uzlů (doufejme s dávkovými přístupy klíčů a nikoli vyhledáváním jednotlivých klíčů za zpáteční cestu), nebo posunutím částí WHERE
klauzule dále k uzlům, kde je lze použít (to se nazývá 'podmínka posunutí dolů'), nebo obojí.
Ale i v nejlepším případě to zahrnuje mnohem více okružních jízd po síti než místní situace a je to složitější. Zejména proto, že optimalizátor MySQL neví vůbec nic o latenci sítě (OK, cluster MySQL se v tom pomalu zlepšuje, ale pro vanilla MySQL mimo cluster to stále platí).
Ztrácíte hodně vyjadřovací schopnosti SQL.
Dobře, to je pravděpodobně méně důležité, ale omezení cizích klíčů a další mechanismy SQL pro integritu dat nejsou schopny překlenout více fragmentů.
MySQL nemá žádné API, které umožňuje asynchronní dotazy, které jsou v provozuschopném stavu.
Pokud jsou data stejného typu umístěna na více uzlech (např. uživatelská data na uzlech A, B a C), horizontální dotazy je často nutné řešit proti všem těmto uzlem („Najít všechny uživatelské účty, které nebyly přihlášeny po dobu 90 dnů nebo více"). Doba přístupu k datům lineárně roste s počtem uzlů, pokud nelze paralelně požádat o více uzlů a výsledky agregovat tak, jak přicházejí ("Map-Reduce").
Předpokladem k tomu je asynchronní komunikační API, které pro MySQL v dobrém funkčním stavu neexistuje. Alternativou je spousta rozvětvení a propojení v dětských procesech, což je návštěva světa sání na sezónní předplatné.
Jakmile začnete se sdílením, datová struktura a topologie sítě se stanou viditelnými jako výkonnostní body vaší aplikace. Aby vaše aplikace fungovala přiměřeně dobře, musí si těchto věcí být vědoma, a to znamená, že smysl má skutečně pouze sharding na úrovni aplikace.
Otázkou spíše je, zda chcete provést automatické shardování (určení, který řádek jde do kterého uzlu například hashováním primárních klíčů), nebo chcete-li funkčně rozdělit ručně („Tabulky související s příběhem uživatele xyz jdou na toto master, zatímco tabulky související s abc a def přejdou na tento master“).
Funkční sharding má tu výhodu, že pokud je proveden správně, je většinu vývojářů většinou neviditelný, protože všechny tabulky související s jejich uživatelským příběhem budou dostupné lokálně. To jim umožňuje stále těžit z deklarativního SQL tak dlouho, jak je to možné, a také bude mít menší latenci sítě, protože počet přenosů mezi sítěmi je minimální.
Funkční sharding má nevýhodu v tom, že neumožňuje, aby žádná jednotlivá tabulka byla větší než jedna instance, a vyžaduje ruční zásah návrháře.
Funkční sharding má tu výhodu, že se poměrně snadno provádí na existující kódové základně s řadou změn, které nejsou přehnaně velké. http://Booking.com udělal to několikrát v minulých letech a fungovalo to pro ně dobře.
Po tom všem, když se podívám na vaši otázku, věřím, že se ptáte špatně, nebo zcela špatně rozumím vašemu prohlášení o problému.