Výkon a škálování v Durable Functions (Azure Functions)

Pokud chcete optimalizovat výkon a škálovatelnost, je důležité pochopit jedinečné charakteristiky škálování Durable Functions. V tomto článku vysvětlujeme, jak se pracovní procesy škálují na základě zatížení a jak se dají vyladit různé parametry.

Škálování pracovního procesu

Základní výhodou konceptu centra úkolů je, že počet pracovníků, kteří zpracovávají pracovní položky centra úkolů, je možné průběžně upravovat. Aplikace můžou konkrétně přidávat další pracovní procesy (horizontální navýšení kapacity), pokud je potřeba práci zpracovat rychleji, a můžou pracovní procesy odebrat (škálovat), pokud není dostatek práce, aby pracovní procesy zůstaly zaneprázdněné. Pokud je centrum úloh zcela nečinné, je dokonce možné škálovat na nulu . Při škálování na nulu nejsou k dispozici žádní pracovníci; Pouze kontroler škálování a úložiště musí zůstat aktivní.

Tento koncept znázorňuje následující diagram:

Diagram škálování pracovního procesu

Automatické škálování

Stejně jako u všech Azure Functions spuštěných v plánech Consumption a Elastic Premium Durable Functions podporuje automatické škálování prostřednictvím kontroleru škálování Azure Functions. Kontroler škálování monitoruje, jak dlouho musí zprávy a úkoly čekat, než se zpracují. Na základě těchto latencí se může rozhodnout, jestli se mají přidávat nebo odebírat pracovní procesy.

Poznámka

Od verze Durable Functions 2.0 je možné aplikace funkcí nakonfigurovat tak, aby běžely v rámci koncových bodů služby chráněných virtuální sítí v plánu Elastic Premium. V této konfiguraci Durable Functions aktivuje žádosti o škálování místo kontroleru škálování. Další informace najdete v tématu Monitorování škálování modulu runtime.

Automatické škálování v plánu Premium může pomoct udržet počet pracovních procesů (a proto provozní náklady) přibližně úměrné zatížení, ke kterému aplikace dochází.

Využití procesoru

Funkce orchestratoru se spouští na jednom vlákně, aby bylo zajištěno, že provádění může být deterministické napříč mnoha přehráními. Z důvodu tohoto provádění s jedním vláknem je důležité, aby vlákna funkcí orchestrátoru neprovádá úlohy náročné na procesor, vstupně-výstupní operace nebo blokovaly z jakéhokoli důvodu. Jakákoli práce, která může vyžadovat vstupně-výstupní operace, blokování nebo více vláken, by se měla přesunout do funkcí aktivit.

Funkce aktivit mají stejné chování jako běžné funkce aktivované frontou. Mohou bezpečně provádět vstupně-výstupní operace, provádět operace náročné na procesor a používat více vláken. Vzhledem k tomu, že triggery aktivit jsou bezstavové, můžou volně škálovat na nevázaný počet virtuálních počítačů.

Funkce entit se také spouští na jednom vlákně a operace se zpracovávají jednorázově. Funkce entit ale nemají žádná omezení typu kódu, který lze spustit.

Časové limity funkcí

Aktivity, orchestrátor a funkce entit podléhají stejným časovým limitům funkcí jako všechny Azure Functions. Obecně platí, že Durable Functions považuje časové limity funkcí za stejné jako neošetřené výjimky vyvolané kódem aplikace.

Pokud dojde například k vypršení časového limitu aktivity, zaznamená se spuštění funkce jako selhání a orchestrátor oznámí a zpracuje časový limit stejně jako jakákoli jiná výjimka: opakování probíhá, pokud je zadána voláním, nebo může být spuštěna obslužná rutina výjimky.

Dávkování operací entit

Pokud chcete zvýšit výkon a snížit náklady, může jedna pracovní položka spouštět celou dávku operací entit. V plánech consumption se každá dávka pak účtuje jako jedno spuštění funkce.

Ve výchozím nastavení je maximální velikost dávky 50 pro plány spotřeby a 5000 pro všechny ostatní plány. Maximální velikost dávky lze také nakonfigurovat v souboru host.json . Pokud je maximální velikost dávky 1, je dávkování efektivně zakázané.

Poznámka

Pokud spuštění jednotlivých operací entit trvá dlouho, může být užitečné omezit maximální velikost dávky, aby se snížilo riziko vypršení časových limitů funkcí, zejména u plánů spotřeby.

Ukládání do mezipaměti instance

Obecně platí, že pro zpracování pracovní položky orchestrace musí pracovní proces obojí

  1. Načtěte historii orchestrace.
  2. Přehrajte kód orchestrátoru pomocí historie.

Pokud stejný pracovní proces zpracovává více pracovních položek pro stejnou orchestraci, může poskytovatel úložiště tento proces optimalizovat ukládáním historie do paměti pracovního procesu, což eliminuje první krok. Kromě toho může orchestrátor uprostřed spuštění ukládat do mezipaměti, což eliminuje druhý krok, přehrání historie a také.

Typickým účinkem ukládání do mezipaměti je snížení vstupně-výstupních operací vůči základní službě úložiště a celková vylepšená propustnost a latence. Ukládání do mezipaměti naopak zvyšuje spotřebu paměti pracovního procesu.

Ukládání do mezipaměti instance v současné době podporuje poskytovatel služby Azure Storage a poskytovatel úložiště Netherite. Následující tabulka obsahuje porovnání.

Poskytovatel služby Azure Storage Zprostředkovatel úložiště Netherite Poskytovatel úložiště MSSQL
Ukládání do mezipaměti instance Podporováno
(Pouze pracovní proces .NET)
Podporováno Nepodporováno
Výchozí nastavení Zakázáno Povoleno Není k dispozici
Mechanismus Rozšířené relace Mezipaměť instance Není k dispozici
Dokumentace Zobrazit rozšířené relace Viz mezipaměť instance Není k dispozici

Tip

Ukládání do mezipaměti může snížit četnost přehrání historie, ale nemůže úplně eliminovat přehrávání. Při vývoji orchestrátorů důrazně doporučujeme je otestovat na konfiguraci, která zakáže ukládání do mezipaměti. Toto chování vynuceného přehrání může být užitečné pro detekci porušení omezení kódu funkce orchestratoru v době vývoje.

Porovnání mechanismů ukládání do mezipaměti

Poskytovatelé používají různé mechanismy k implementaci ukládání do mezipaměti a nabízejí různé parametry ke konfiguraci chování ukládání do mezipaměti.

  • Rozšířené relace, které používá poskytovatel služby Azure Storage, uchovávají orchestrátory mid-execution v paměti, dokud nebudou nějakou dobu nečinné. Parametry pro řízení tohoto mechanismu jsou extendedSessionsEnabled a extendedSessionIdleTimeoutInSeconds. Další podrobnosti najdete v části Rozšířené relace v dokumentaci poskytovatele služby Azure Storage.

Poznámka

Rozšířené relace jsou podporovány pouze v pracovním procesu .NET.

  • Mezipaměť instance, kterou používá poskytovatel úložiště Netherite, uchovává stav všech instancí, včetně jejich historie, v paměti pracovního procesu a přitom sleduje celkovou využitou paměť. Pokud velikost mezipaměti překročí limit nakonfigurovaný službou InstanceCacheSizeMB, vyřadí se data o nejméně naposledy použitých instancích. Pokud CacheOrchestrationCursors je nastavena na hodnotu true, mezipaměť také ukládá orchestrátory mid-execution spolu se stavem instance. Další podrobnosti najdete v části Mezipaměť instance v dokumentaci poskytovatele úložiště Netherite.

Poznámka

Instance ukládají do mezipaměti všechny sady SDK jazyka, ale CacheOrchestrationCursors tato možnost je dostupná jenom pro pracovní proces .NET v procesu.

Omezení souběžnosti

Jedna instance pracovního procesu může souběžně spouštět více pracovních položek . To pomáhá zvýšit paralelismus a efektivněji využívat pracovní procesy. Pokud se ale pracovní proces pokusí zpracovat příliš mnoho pracovních položek současně, může vyčerpat dostupné prostředky, jako je zatížení procesoru, počet síťových připojení nebo dostupná paměť.

Aby se zajistilo, že jednotlivý pracovní proces nepřekončí, může být nutné omezovat souběžnost jednotlivých instancí. Omezením počtu funkcí, které jsou současně spuštěny u každého pracovního procesu, se můžeme vyhnout vyčerpání limitů prostředků daného pracovního procesu.

Poznámka

Omezení souběžnosti platí jenom místně, aby se omezilo to, co se právě zpracovává na pracovní proces. Tato omezení tedy neomešují celkovou propustnost systému.

Tip

V některýchpřípadechch K tomu může dojít, když každý pracovní proces zabere méně práce, což způsobí, že kontroler škálování přidá více pracovních procesů, aby zůstal ve frontách, což pak zvyšuje celkovou propustnost.

Konfigurace omezení

Limity souběžnosti aktivit, orchestrátoru a funkcí entity je možné nakonfigurovat v souboru host.json . Relevantní nastavení jsou durableTask/maxConcurrentActivityFunctions pro funkce aktivit a durableTask/maxConcurrentOrchestratorFunctions pro orchestrátor i funkce entit. Tato nastavení řídí maximální počet funkcí orchestrátoru, entity nebo aktivity, které jsou načteny do paměti jednoho pracovního procesu.

Poznámka

Orchestrace a entity se načtou do paměti pouze v případě, že aktivně zpracovávají události nebo operace, nebo pokud je povolena ukládání do mezipaměti instance . Po spuštění logiky a čekání (tj. stisknutí příkazu await (C#) nebo yield (JavaScriptu, Pythonu) v kódu funkce orchestrátoru se můžou uvolnit z paměti. Orchestrace a entity, které jsou uvolněné z paměti, se nezapočítávají do maxConcurrentOrchestratorFunctions omezení. I když jsou miliony orchestrací nebo entit ve stavu "Spuštěno", počítají se pouze do limitu omezení, když jsou načteny do aktivní paměti. Orchestrace, která naplánuje funkci aktivity podobně, se nezapočítává do omezení, pokud orchestrace čeká na dokončení provádění aktivity.

Funkce 2.0

{
  "extensions": {
    "durableTask": {
      "maxConcurrentActivityFunctions": 10,
      "maxConcurrentOrchestratorFunctions": 10
    }
  }
}

Functions 1.x

{
  "durableTask": {
    "maxConcurrentActivityFunctions": 10,
    "maxConcurrentOrchestratorFunctions": 10
  }
}

Důležité informace o modulu runtime jazyka

Vybraný modul runtime jazyka může uplatňovat striktní omezení souběžnosti nebo vaše funkce. Například aplikace Durable Function napsané v Pythonu nebo PowerShellu můžou podporovat pouze spuštění jedné funkce na jednom virtuálním počítači. To může vést k významným problémům s výkonem, pokud nejsou pečlivě zohledněna. Pokud například orchestrátor fandí na 10 aktivit, ale modul runtime jazyka omezuje souběžnost pouze na jednu funkci, pak se 9 z 10 funkcí aktivity zablokuje a čeká se na spuštění. Tyto 9 zablokované aktivity navíc nebudou moct být vyrovnávat zatížení žádným dalším pracovníkům, protože modul runtime Durable Functions je již načetl do paměti. To se stává zvlášť problematické, pokud jsou funkce aktivit dlouhotrvající.

Pokud modul runtime jazyka, který používáte, omezuje souběžnost, měli byste aktualizovat nastavení souběžnosti Durable Functions tak, aby odpovídalo nastavení souběžnosti vašeho modulu runtime jazyka. Tím zajistíte, že se modul runtime Durable Functions nebude pokoušet spouštět více funkcí současně, než povoluje modul runtime jazyka, což umožňuje vyrovnání zatížení všech čekajících aktivit na jiné virtuální počítače. Pokud máte například aplikaci v Pythonu, která omezuje souběžnost na 4 funkce (možná je nakonfigurovaná pouze se 4 vlákny v jednom pracovním procesu jazyka nebo 1 vlákno ve 4 jazykových pracovních procesech), měli byste nakonfigurovat obojí maxConcurrentOrchestratorFunctions i maxConcurrentActivityFunctions na 4.

Další informace a doporučení k výkonu pro Python najdete v tématu Zvýšení výkonu propustnosti aplikací Pythonu v Azure Functions. Techniky uvedené v této referenční dokumentaci pro vývojáře v Pythonu můžou mít významný dopad na výkon a škálovatelnost Durable Functions.

Počet oddílů

Někteří poskytovatelé úložiště používají mechanismus dělení a umožňují zadat partitionCount parametr.

Při použití dělení nekonkurují pracovní procesy přímo pro jednotlivé pracovní položky. Místo toho jsou pracovní položky nejprve seskupené do partitionCount oddílů. Tyto oddíly se pak přiřazují pracovníkům. Tento dělený přístup k distribuci zatížení může pomoct snížit celkový počet požadovaných přístupů k úložišti. Může také povolit ukládání instancí do mezipaměti a zlepšit umístění, protože vytváří spřažení: všechny pracovní položky pro stejnou instanci jsou zpracovány stejným pracovním procesem.

Poznámka

Horizontální navýšení kapacity dělení na více instancí, protože většina partitionCount pracovních procesů může zpracovávat pracovní položky z dělené fronty.

Následující tabulka ukazuje, pro každého zprostředkovatele úložiště, které fronty jsou rozdělené do oddílů, a povolený rozsah a výchozí hodnoty parametru partitionCount .

Poskytovatel služby Azure Storage Zprostředkovatel úložiště Netherite Poskytovatel úložiště MSSQL
Zprávy instance Partitioned Partitioned Není dělené
Zprávy o aktivitách Není dělené Partitioned Není dělené
Výchozí partitionCount 4 12 Není k dispozici
Maximální partitionCount 16 32 Není k dispozici
Dokumentace Viz Horizontální navýšení kapacity nástroje Orchestrator Podívejte se na důležité informace o počtu oddílů. Není k dispozici

Upozornění

Po vytvoření centra úloh už nelze počet oddílů změnit. Proto je vhodné nastavit ji na dostatečně velkou hodnotu, aby vyhovovala budoucím požadavkům na horizontální navýšení kapacity pro instanci centra úloh.

Konfigurace počtu oddílů

Parametr partitionCount lze zadat v souboru host.json . Následující příklad fragmentu kódu host.json nastaví durableTask/storageProvider/partitionCount vlastnost (nebo durableTask/partitionCount v Durable Functions 1.x) na 3.

Durable Functions 2.x

{
  "extensions": {
    "durableTask": {
      "storageProvider": {
        "partitionCount": 3
      }
    }
  }
}

Durable Functions 1.x

{
  "extensions": {
    "durableTask": {
      "partitionCount": 3
    }
  }
}

Cíle výkonu

Při plánování použití Durable Functions pro produkční aplikaci je důležité zvážit požadavky na výkon v rané fázi procesu plánování. Mezi základní scénáře použití patří:

  • Postupné spuštění aktivity: Tento scénář popisuje funkci orchestrátoru, která spouští řadu funkcí aktivit po druhé. Nejvíce se podobá ukázce řetězení funkcí .
  • Paralelní provádění aktivit: Tento scénář popisuje funkci orchestrátoru, která paralelně spouští mnoho funkcí aktivity pomocí vzoru Fan-out, Fan-in .
  • Paralelní zpracování odpovědí: Tento scénář je druhou polovinou modelu Fan-out, Fan-in . Zaměřuje se na výkon ventilátoru. Je důležité si uvědomit, že na rozdíl od fan-outu se ventilátor provádí jednou instancí funkce orchestrátoru, a proto může běžet jenom na jednom virtuálním počítači.
  • Zpracování externích událostí: Tento scénář představuje jednu instanci funkce orchestrátoru, která čeká na externí události po jednom.
  • Zpracování operace entit: Tento scénář testuje, jak rychle může jednaentita čítače zpracovat konstantní proud operací.

V příslušné dokumentaci pro poskytovatele úložiště poskytujeme čísla propustnosti pro tyto scénáře. Zejména jde o toto:

Tip

Na rozdíl od ventilátoru jsou operace ventilátorů omezené na jeden virtuální počítač. Pokud vaše aplikace používá model ventilátoru, ventilátoru a máte obavy o výkon ventilátoru, zvažte dílčí rozdělení ventilátoru funkce aktivity mezi několik dílčích orchestrací.

Další kroky