Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Minimalizace koordinace pro dosažení škálovatelnosti
Většina cloudových aplikací se skládá z několika aplikačních služeb, jako jsou webové front-endy, databáze, obchodní procesy a vytváření sestav a analýza. K dosažení škálovatelnosti a spolehlivosti by měla každá z těchto služeb běžet na více instancích.
Nekomordované systémy, kde je možné pracovat nezávisle bez nutnosti předávat zprávy mezi počítači, jsou obecně jednodušší škálovat. Koordinace obvykle není binárním stavem, ale spektrem. Koordinace probíhá v různých vrstvách, jako jsou data nebo výpočty.
Co se stane, když se dvě instance pokusí provést souběžné operace, které ovlivňují některý sdílený stav? V některých případech musí mezi uzly existovat koordinace, například zachování záruk modelu ACID. V tomto diagramu Node2 čeká na Node1, až uvolní zámek databáze:
Koordinace omezuje výhody horizontálního škálování a vytváří kritická místa. V tomto příkladu při škálování aplikace na více instancí a přidávání dalších instancí sledujete vyšší výskyt sporů o zámky. V nejhorším případě budou instance front-endu trávit většinu času čekáním na zámky.
Sémantika „právě jednou“ je také častým zdrojem pro koordinaci. Například objednávka musí být zpracována právě jednou. Dva pracovníci naslouchají novým objednávkám.
Worker1 převezme objednávku ke zpracování. Aplikace musí zajistit, aby Worker2 neduplikoval práci, a pokud Worker1 selže, pořadí se neztratí.
Můžete například použít model, jako je Scheduler Agent Supervisor, ke koordinaci pracovních procesů, ale v takovém případě může být lepším řešením rozdělení práce. Každému pracovníkovi je přiřazen určitý rozsah objednávek (například podle fakturačního regionu). Pokud dojde k chybě procesu, nová instance převezme práci tam, kde předchozí instance skončila, ale více instancí spolu nekoliduje.
Doporučení
Používejte oddělené komponenty, které komunikují asynchronně. Komponenty by měly v ideálním případě používat události ke vzájemné komunikaci.
Přijměte konečnou konzistenci. Pokud jsou data distribuovaná, vynucení záruk silné konzistence vyžaduje koordinaci. Předpokládejme například, že operace aktualizuje dvě databáze. Místo jejich zařazení do jediné transakční oblasti je lepší, pokud se systém zvládne přizpůsobit eventuální konzistenci, případně pomocí vzoru kompenzační transakce transakci po selhání logicky obnovit.
Používejte události domény k synchronizaci stavu. Událost domény je událost, která zaznamenává, když se stane něco, co má význam v rámci domény. Dotčené služby můžou události naslouchat, což je lepší než používat globální transakci ke koordinaci mezi více službami. Pokud se používá tento přístup, musí systém tolerovat konečnou konzistenci (viz předchozí položka).
Zvažte modely jako CQRS a Event Sourcing. Tyto dva modely můžou pomoct snížit kolize mezi úlohami pro čtení a úlohami pro zápis.
Model CQRS odděluje operace čtení od operací zápisu. V některých implementacích jsou čtená data fyzicky oddělená od zapisovaných dat.
V modelu Event Sourcing se změny stavu zaznamenávají jako řada událostí v úložišti dat jen s možností připojovat. Připojení události do datového proudu je atomickou operací, která vyžaduje minimální zamykání.
Tyto dva modely se vzájemně doplňují. Pokud úložiště jen pro zápis v modelu CQRS používá Event Sourcing, úložiště jen pro čtení může naslouchat stejným událostem a vytvářet čitelný snímek aktuálního stavu, optimalizovaný pro dotazy. Před přijetím modelu CQRS nebo Event Sourcing je ale potřeba znát obtíže spojené s tímto přístupem.
Rozdělte data a stav. Vyhněte se vložení všech vašich dat do jedno schématu dat, které sdílí mnoho aplikačních služeb. Architektura mikroslužeb vynucuje tuto zásadu tak, že každá služba je zodpovědná za své vlastní úložiště dat. V rámci jedné databáze může dělení dat do horizontálních oddílů zlepšit souběžnost, protože služba zápisu do jednoho horizontálního oddílu nemá vliv na službu zápisu do jiného horizontálního oddílu. I když dělení přidává určitou míru koordinace, můžete pomocí dělení zvýšit paralelismus, aby se zlepšila škálovatelnost. Rozdělení monolitického stavu do menších bloků dat, aby bylo možné data spravovat nezávisle.
Navrhujte idempotentní operace. Pokud je to možné, navrhujte operace tak, aby byly idempotentní. Tímto způsobem je možné je zpracovávat pomocí sémantiky „aspoň jednou“. Například můžete přidat pracovní položky do fronty. Pokud pracovník havaruje uprostřed operace, převezme úkol jiný pracovník. Pokud pracovní proces potřebuje aktualizovat data a generovat další zprávy jako součást logiky, měl by se použít model zpracování idempotentních zpráv .
Pokud možno používejte optimistickou souběžnost. Pesimistické řízení souběžnosti používá zámky databáze, aby se zabránilo konfliktům. To může způsobit horší výkon a snížit dostupnost. S optimistickým řízením souběžnosti každá jednotlivá transakce upravuje kopii nebo snímek dat. Když je transakce potvrzena, databázový stroj transakci ověří a odmítne všechny transakce, které by ovlivnily konzistenci databáze.
Azure SQL Database a SQL Server podporují optimistickou souběžnost prostřednictvím izolace snímku. Některé služby úložiště Azure podporují optimistickou souběžnost prostřednictvím značek Etag, včetně služeb Azure Cosmos DB a Azure Storage.
Zvažte MapReduce nebo jiné paralelní, distribuované algoritmy. V závislosti na datech a typu práce, které se mají provést, můžete práci rozdělit na nezávislé úlohy, které může provádět několik uzlů pracujících paralelně. Přečtěte si téma Styl architektury pro velký objem výpočtů.
Používejte ke koordinaci volbu vedoucího. V případech, kdy potřebujete koordinovat operace, zkontrolujte, že koordinátor se nestane v aplikaci kritickým prvkem způsobujícím selhání. Pomocí modelu volby vedoucího procesu je vždy jedna instance vedoucí a funguje jako koordinátor. V případě selhání vedoucího se zvolí nová instance jako vedoucí.
Spravovat koordinaci mezi občas připojenými klienty
Samotná eventuální konzistence nestačí, když odpojení klienti využívají sdílený prostředek s pevným limitem, například místa na akci. Více klientů může operovat se stejnou zdánlivě dostupnou kapacitou a pozdější synchronizace jejich záznamů už nemůže napravit nadměrnou alokaci tohoto prostředku, například když se vpustí více lidí, než kolik pojme dané místo konání. Tady je několik doporučení koordinace pro použití v tomto scénáři:
Rozdělte kvótu, ne jen data. Než se klient odpojí, přiřaďte mu výhradní rezervaci z dostupné kapacity. Klient může schvalovat offline operace jenom v době, kdy má rezervace kapacitu. Ujistěte se, že centrálně spotřebovaná kapacita, centrálně dostupná kapacita a úplná velikost všech nevyřízených rezervací nepřekročí globální limit. Když se klient znovu připojí, porovnejte to, co spotřeboval, a vraťte nevyužitou kapacitu.
Rozhodněte, kdo ponese následky problému. Pokud klienti musí fungovat offline bez exkluzivních rezervací, zvolte jednu ze tří obchodních možností: ponechte pevnou kapacitní rezervu dimenzovanou na maximální souhrnnou offline poptávku, během odpojení nastavte operace měnící kapacitu jako pouze pro čtení nebo akceptujte občasné nadměrné přidělení kapacity.
Surface selhání odsouhlasení operátoru. Přesuňte konflikty, které nelze automaticky vyřešit, do fronty ke kontrole. Pro akce, které systém může obrátit, použijte model kompenzační transakce . Nevratné nebo nejednoznačné výsledky směrujte operátorovi, který může uplatnit definovaná obchodní pravidla.