Sekvenční vzor convoy

Seskupte související zprávy podle klíče kategorie a zpracovávejte každou skupinu postupně, po jedné zprávě, zatímco různé skupiny zpracováváte paralelně.

Tento vzor řeší rozpor mezi zachováním správného pořadí FIFO v rámci každé logické skupiny a škálováním souběžného zpracování napříč skupinami. Návrh zajišťuje, aby se omezení řazení nestala kritickým bodem celého systému.

Kontext a problém

Aplikace často potřebují zpracovávat související zprávy v pořadí, v jakém přicházejí, a zároveň stále škálovat kapacitu, aby zvládly zvýšené zatížení. V distribuované architektuře je tento požadavek obtížné dosáhnout, protože pracovní procesy nezávisle natahují zprávy ze sdílené fronty. Když o zprávy soutěží více pracovníků, jako ve vzoru Competing Consumers pattern, pořadí přestává být zachováno.

Zvažte systém sledování objednávek, který přijímá datový proud operací, jako je vytvoření objednávky, přidání transakce, úprava předchozí transakce a odstranění objednávky. Operace jednotlivých objednávek musí být zpracovány v pořadí FIFO, protože jejich použití mimo pořadí by poškodilo stav objednávky. Příchozí fronta však protíná operace napříč mnoha objednávkami. Jediný konzument, který vynucuje globální pořadí, se stává úzkým hrdlem a více konzumentů může zpracovávat operace téže objednávky v nesprávném pořadí.

Každý z jednoduchých přístupů k tomuto problému selhává jiným způsobem:

  • Jeden spotřebitel. Jeden příjemce zachovává pořadí zpráv, protože zpracovává jednu zprávu najednou, ale nemůže škálovat, aby zvládl zvýšenou propustnost.

  • Více konkurenčních spotřebitelů. Více spotřebitelů zvyšuje propustnost tím, že paralelně načítají zprávy, ale přicházejí o záruku zachování pořadí v rámci jednotlivých skupin. Dva pracovníci mohou vyzvednout po sobě jdoucí zprávy pro stejnou objednávku a zpracovat je současně nebo mimo pořadí, což naruší stav objednávky.

Řešení

Vzor sekvenčního convoy rozděluje související zprávy do kategorií a zpracovává každou kategorii postupně, jednu zprávu najednou, zatímco kategorie se zpracovávají paralelně.

Vzor funguje tak, že každé zprávě přiřadíte klíč kategorie, který identifikuje skupinu, do které patří. Zprostředkovatel zpráv používá tento klíč k rozdělení zpráv do logických skupin. V rámci každé skupiny broker vynucuje pořadí FIFO, takže příjemce, který zamkne skupinu, přijímá zprávy striktně v tom pořadí, v jakém byly zařazeny do fronty. Různé skupiny můžou zpracovávat různí spotřebitelé současně, takže systém horizontálně škáluje napříč skupinami, aniž by bylo nutné obětovat pořadí v rámci jedné skupiny.

Na Azure poskytují relace zpráv Azure Service Bus integrovanou implementaci tohoto modelu.

Následující diagram znázorňuje obecný vzor sekvenční konvoy.

Diagram sekvenčního vzoru konvoje Zobrazuje producenta, centrální frontu a tři příjemce.

Ve frontě mohou být zprávy z různých kategorií promíchány, jak je znázorněno v následujícím diagramu.

Diagram, který znázorňuje čtyři kategorie prokládaných zpráv v jedné frontě. Každá kategorie zabírá vlastní vodorovný pruh.

Tento model nabízí několik klíčových výhod:

  • Sekvenční zpracování podle skupin Zprávy v rámci každé kategorie se zpracovávají přísně v sekvenci, což brání podmínkám časování, změnám stavu mimo pořadí a potřebě změnit pořadí alternativních řešení.

  • Horizontální škálování napříč skupinami Každá kategorie je nezávislou jednotkou souběžnosti. Přidání spotřebitelů zvyšuje propustnost úměrně počtu aktivních kategorií, aniž by docházelo k narušení záruk řazení.

  • Oddělení producenta a spotřebitele. Producenti zařazují zprávy do fronty, aniž by věděli, který spotřebitel je zpracuje nebo kdy. Spotřebitelé jsou nezávisle škálovatelné a nahraditelné.

Problémy a důležité informace

Při rozhodování o implementaci tohoto modelu zvažte následující body:

  • Kategorie a jednotka škálování Určete, na základě jaké vlastnosti příchozích zpráv můžete horizontálně škálovat. Klíč kategorie definuje jednotku paralelismu: každá jedinečná hodnota klíče se stane nezávisle zpracovatelnou skupinou. Ve scénáři sledování objednávek je tato vlastnost ID objednávky. Volba příliš obecného klíče (například jednoho ID zákazníka pro všechny objednávky) omezuje paralelismus, zatímco volba příliš detailního klíče nepřináší žádný smysluplný přínos z hlediska pořadí.

  • Omezení propustnosti Vyhodnoťte propustnost cílové zprávy. Vzhledem k tomu, že tento model vynucuje sekvenční zpracování v rámci každé kategorie, je propustnost na každou kategorii ohraničena časem zpracování jedné zprávy. Optimalizujte dobu zpracování zpráv, například pomocí asynchronních vstupně-výstupních operací nebo dávkových zápisů podřízených dat, protože tato doba přímo určuje maximální propustnost pro každou kategorii. Pokud je váš požadavek na celkovou propustnost velmi vysoký, znovu zvažte, jestli je pro celý životní cyklus zpráv nezbytné přísné řazení FIFO. Alternativy zahrnují vynucení úvodní a závěrečné zprávy k ohraničení sekvence nebo řazení zpráv podle časového razítka v rámci dávkového okna a následné odeslání této dávky k paralelnímu zpracování.

  • Možnosti služby. Ověřte, jestli váš výběr zprostředkovatele zpráv podporuje jednorázové zpracování zpráv v rámci fronty nebo kategorie fronty. Ne všechny služby pro zasílání zpráv poskytují uzamykání na úrovni relace nebo záruky FIFO v rámci oddílu. Pokud zprostředkovatel tuto funkci nativně nepodporuje, musí příjemce implementovat vlastní koordinaci logiky, která zvyšuje složitost a riziko duplicitního zpracování, zmeškaných zpráv nebo provádění mimo pořadí. Podpora relací může také omezit volbu úrovně zasílání zpráv nebo skladové položky, která ovlivňuje náklady.

  • Schopnost dalšího vývoje. Naplánujte, jak do systému přidáte nové kategorie zpráv. Model musí pojmout růst kardinality kategorií, aniž by vyžadoval strukturální změny spotřebitelů. Předpokládejme například, že systém registru popsaný výše je specifický pro jednoho zákazníka. Pokud potřebujete připojit nového zákazníka, měli byste být schopni přidat sadu procesorů registru, které distribuují práci podle ID zákazníka, aniž byste přepracovali topologii fronty.

  • Doručení zpráv mimo pořadí. Zprávy mohou dorazit v jiném pořadí kvůli proměnlivé latenci sítě mezi producentem a brokerem, než se začne uplatňovat řazení relací brokeru. Zvažte použití pořadových čísel k ověření řazení v rámci každé kategorie. Do poslední zprávy transakce můžete zahrnout také příznak ukončení sekvence, aby spotřebitelé mohli zjistit, kdy je sekvence dokončena.

  • Zpracování otrávené zprávy. Zpráva, která opakovaně selže při zpracování v rámci relace, blokuje všechny následné zprávy v této relaci, protože vzor vynucuje striktní sekvenční řazení. Navrhněte strategii pro detekci otrávených zpráv, jako je sledování počtu pokusů o doručení, a přesuňte je do fronty nedoručených zpráv po definované prahové hodnotě opakování, aby zbývající zprávy v relaci mohly pokračovat ve zpracování.

  • Dostupnost zprostředkovatele. Zprostředkovatel zpráv je pro všechny kategorie sdílenou závislostí. Její dostupnost a odolnost přímo ovlivňují záruky spolehlivosti modelu. Vyhodnoťte funkce odolnosti na úrovni zprostředkovatele, jako jsou zóny dostupnosti a geografické zotavení po havárii, na základě požadavků na dostupnost a rozpočtu úlohy, protože konfigurace s vyšší odolností obvykle zvyšují náklady.

  • Správnost klíče producenta. Model předpokládá, že producenti správně nastavují klíč kategorie (ID relace) u každé zprávy. Pokud producent nastaví nesprávný klíč, ať už omylem nebo kvůli chybě, zpráva se přesměruje do nesprávné relace a poškodí stav dané skupiny. Ověřte, že producenti přiřazují klíče kategorií konzistentně, a pokud je výsledek nesprávně směrované zprávy závažný, zvažte přidání logiky ověření klíče na příjemce.

  • Provozní složitost. Sledování zpracování založeného na relacích přináší vyšší provozní režii než standardní zpracování fronty. Operátoři potřebují přehled o nahromadění front v relacích (o počtu aktivních relací a počtu zpráv čekajících v jednotlivých relacích), aby mohli identifikovat kategorie, které zaostávají. Relace obsahující nedoručené zprávy vyžadují samostatný postup pro monitorování a nápravu, aby bylo možné prověřit zprávy, jejichž zpracování selhalo, odstranit hlavní příčinu a znovu odeslat opravené zprávy zpět do relace.

  • Kolize a latence uzamčení relace Zamykání relací zvyšuje latenci, protože každý příjemce musí před zpracováním zpráv získat výhradní uzamčení relace. Pokud uživatel uchovává zámek relace, nemůže žádný jiný uživatel zpracovávat zprávy z této relace, i když je příjemce pomalý nebo dočasně zastavený. Pokud je doba uzamčení příliš krátká, může vypršení platnosti zámku způsobit opětovné zpracování zprávy. Pokud je doba uzamčení příliš dlouhá, zpožďuje obnovení pozastavený příjemce. Vylaďte dobu trvání uzamčení relace na základě očekávané doby zpracování zpráv a implementujte obnovení zámku pro delší operace.

  • Škálování a náklady na spotřebitele Paralelismus napříč relacemi se překládá na souběžné instance příjemců. V bezserverovém modelu, jako je Azure Functions, každá aktivní relace odpovídá jednomu souběžnému provádění a ve vyhrazeném modelu odpovídá jedné instanci nebo vláknu. Počet aktivních relací proto přímo ovlivňuje náklady na výpočetní prostředky. Naplánujte omezení škálování uživatelů a řízení souběžnosti, které vyrovnává propustnost proti nákladům.

Kdy použít tento vzor

Tento model použijte v těchto případech:

  • Zprávy přicházejí v pořadí a musí být zpracovány ve stejném pořadí.
  • Zprávy je možné kategorizovat tak, aby každá kategorie byla nezávislou jednotkou škálování systému.

Tento vzor nemusí být vhodný v těchto případech:

  • Očekáváte extrémně vysokou propustnost scénářů (miliony zpráv za minutu), protože požadavek FIFO omezuje škálování, které může systém dosáhnout.

  • Řazení zpráv není povinné. Pokud lze zprávy zpracovávat nezávisle v libovolném pořadí, vzor Competing Consumers umožňuje jednodušší horizontální škálování bez koordinační režie spojené se zamykáním relací.

Návrh úloh

Vyhodnoťte, jak používat sekvenční konvoje v návrhu úlohy k řešení cílů a principů zahrnutých v pilířích Azure Well-Architected Frameworku. Následující tabulka obsahuje pokyny, jak tento model podporuje cíle jednotlivých pilířů.

Pilíř Jak tento model podporuje cíle pilíře
Spolehlivostní rozhodnutí o návrhu pomáhají vaší pracovní zátěži stát se odolná proti poruchám a zajistit, aby se po selhání obnovila do plně funkčního stavu. Tento vzor využívá řazení FIFO založené na relacích k eliminaci souběhových stavů, logiky zpracování zpráv náchylné ke kolizím a dalších náhradních řešení pro chybně seřazené zprávy, která mohou vést k selháním.

- RE:02 Kritické toky
- RE:07 Úlohy na pozadí

Pokud tento model představuje kompromisy v rámci pilíře, zvažte je proti cílům ostatních pilířů.

Příklad

V Azure můžete tento vzor implementovat pomocí relací zpráv služby Service Bus. Pro příjemce můžete použít buď Azure Logic Apps s konektorem Service Bus peek-lock, nebo Azure Functions s aktivačním modulem Service Bus.

Když producent nastaví SessionId vlastnost zprávy, Service Bus seskupí všechny zprávy, které sdílejí stejné ID relace, do jedné logické relace. Klient přijme relaci a získá k ní výhradní zámek. Tento zámek zaručuje, že zprávy pro danou relaci zpracovává vždy jenom jeden příjemce a že zprávy přicházejí v pořadí FIFO. Ostatní příjemci můžou současně přijímat a zpracovávat různé relace a zajišťovat paralelní propustnost napříč skupinami.

V příkladu sledování objednávek systém zpracuje každou zprávu registru v pořadí, ve kterém je přijata, a odešle každou transakci do jiné fronty, kde je kategorie nastavena na ID objednávky. Transakce v tomto scénáři nikdy nezahrnuje více objednávek, takže konzumenti zpracovávají jednotlivé kategorie paralelně, ale v rámci každé kategorie ve FIFO pořadí.

Procesor registru oddálí zprávy zrušením dávkování obsahu každé zprávy v první frontě:

Diagram ukázkové architektury sekvenčního konvoje. Zobrazuje producenta, frontu účetní knihy, procesor účetní knihy, frontu transakcí a tři procesory objednávek.

Procesor registru provádí tři kroky:

  1. Prochází účetní knihu po jednotlivých transakcích.
  2. Nastaví ID relace zprávy tak, aby odpovídalo ID objednávky.
  3. Odešle každou transakci účetní knihy do sekundární fronty se session ID nastaveným na ID objednávky.

Příjemci naslouchají sekundární frontě a zpracovávají všechny zprávy s odpovídajícími ID objednávek v pořadí FIFO. Klienti používají režim peek-lock.

Fronta účetní knihy je přechodovým bodem ze sekvenčního na paralelní zpracování: všechny transakce jí nejprve procházejí postupně, než se rozdělí do paralelního zpracování založeného na relacích. Tato fáze serializace je hlavním úzkým hrdlem škálovatelnosti, protože omezuje propustnost celého navazujícího řetězce zpracování. Jakmile ale procesor registru oddálí zprávy do sekundární fronty, můžou se příjemci nezávisle škálovat napříč relacemi, a to podle ID objednávky.

Podpůrné technologie

  • Relace zpráv Service Bus: Seskupuje zprávy podle ID relace a vynucuje zpracování FIFO v rámci každé relace. Relace zpráv jsou hlavním mechanismem v Azure pro implementaci vzoru sekvenčního konvoje.

  • trigger Azure Functions Service Bus: Podporuje triggery založené na relacích, které umožňují instancím funkcí zpracovávat zprávy z jedné relace najednou.

  • Konektor Service Bus pro Logic Apps: Poskytuje konektor Service Bus s podporou režimu Peek-Lock pro zpracování front s podporou relací při zpracování založeném na pracovních postupech.

Přispěvatelé

Microsoft udržuje tento článek. Tento článek napsali následující přispěvatelé.

Hlavní autor:

  • Naga Venkata Cheruvu | Vedoucí architekt cloudových řešení + infrastruktura umělé inteligence

Pokud chcete zobrazit nepublikované profily LinkedIn, přihlaste se k LinkedIn.

  • Vzor konkurujících si příjemců: Více příjemců si paralelně vyzvedává zprávy ze sdílené fronty, což zvyšuje propustnost, ale ruší záruky pořadí jednotlivých zpráv. Vzor Sekvenční konvoj řeší problém s pořadím, který přináší vzor Competing Consumers. Řeší tuto mezeru rozdělením zpráv do relací s klíči kategorií a následným zpracováním jednotlivých relací.

  • Vzor vyrovnávání zatížení pomocí fronty: Fronta slouží jako vyrovnávací mezivrstva mezi producenty a spotřebiteli, aby pohltila špičky a vyrovnala nerovnoměrné zatížení. Vzorec Sequential Convoy staví na tomto ukládání do vyrovnávací paměti tím, že přidává rozdělení podle relací, takže fronta rovnoměrně rozkládá zatížení mezi kategorie a zároveň zachovává pořadí FIFO v rámci každé kategorie.

  • Model prioritní fronty: Zprávy se směrují do samostatných front nebo podle priority v rámci fronty, aby se práce s vyšší prioritou zpracovávala před prací s nižší prioritou. Pokud je nutné zachovat také pořadí v rámci úrovně priority, lze vzor Sequential Convoy zkombinovat s prioritní frontou, aby se v rámci každé relace identifikované klíčem priority vynutilo zpracování FIFO.

  • Peek-Lock (nedestruktivní čtení zprávy): Tato operace atomicky načte a uzamkne zprávu z fronty nebo předplatného pro zpracování.

  • Doručování korelovaných zpráv ve správném pořadí v Logic Apps pomocí relací Service Bus: Tento příspěvek na blogu popisuje podporu vzoru Sequential Convoy v Logic Apps.