Minimalizace koordinace

Azure Storage
Azure SQL Database
Azure Cosmos DB

Minimalizujte koordinaci mezi aplikačními službami, abyste dosáhli škálovatelnosti.

Většina cloudových aplikací se skládá z několika aplikačních služeb – webových front-endů, databází, obchodních procesů, vytváření sestav a analýzy atd. K dosažení škálovatelnosti a spolehlivosti by měla každá z těchto služeb běžet na více instancích.

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:

Database lock diagram

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 dalším častým zdrojem koordinace. Například objednávka musí být zpracována právě jednou. Dva pracovní procesy naslouchají a čekají na nové objednávky. Worker1 převezme objednávku ke zpracování. Aplikace musíte zajistit, aby Worker2 neduplikoval práci, ale taky když Worker1 selže, objednávka se neztratí.

Coordination diagram

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ímu procesu je přiřazen určitý rozsah objednávek (například podle fakturační oblasti). Pokud dojde k chybě pracovního procesu, nová instance převezme práci tam, kde předchozí instance skončila, ale instance mezi sebou nesoupeří.

Doporučení

Zapojte 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é transakce je lepší, pokud se systému zvládne přizpůsobit konečné konzistenci, případně pomocí modelu kompenzační transakce po selhání transakci logicky vrátit.

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 atomická operace vyžadující 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.

Dělení dat. 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 dělení dat do horizontálních oddílů může zvýšit souběžnost, protože služba zapisující do jednoho horizontálního oddílu neovlivní službu zapisující do jiného horizontálního oddílu.

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í proces selže uprostřed operace, jiný pracovní proces pracovní položku jednoduše převezme. Pokud pracovní proces potřebuje aktualizovat data a generovat další zprávy jako součást své logiky, měl by se použít vzor zpracování idempotentních zpráv.

Používejte pokud možno 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á transakce upraví 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 prováděné práce je možné práci rozdělit do nezávislých úloh, které jde provést pomocí několika uzlů fungují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 procesu. 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 procesu se zvolí jako vedoucí nová instance.