Azure Storage-Anbieter für Durable Functions

Wenn Sie Durable Functions verwenden, ist der Azure Storage Anbieter Ihre Standardoption für die Verwaltung von Status und Orchestrierung. Der Azure Storage Anbieter optimiert die Leistung und Skalierbarkeit für Ihre Anwendungen, indem Sie Ihre Instanzzustände und Warteschlangen in einem Azure Storage Konto speichern.

Mit dem Azure Storage-Anbieter:

  • Azure Warteschlangen steuern die gesamte Funktionsausführung.
  • Azure-Tabellen speichern den Orchestrationsstatus sowie den Status und Verlauf von Entitäten.
  • Azure Blobs und Blob-Leases verteilen Orchestrierungsinstanzen und Entitäten über mehrere App-Instanzen (auch bekannt als worker oder virtual machines).

Sehen wir uns an, wie diese Azure Storage Komponenten zusammenarbeiten und sich auf die Leistung und Skalierbarkeit Ihrer App auswirken.

Azure Storage-Darstellung in einem Aufgabenhub

Ein Aufgabenhub bewahrt alle Instanzzustände und alle Nachrichten dauerhaft auf. Eine kurze Übersicht darüber, wie der Aufgabenhub den Orchestrierungsfortschritt nachverfolgt, finden Sie im Beispiel für die Ausführung des Aufgabenhubs.

Wenn Sie einen Aufgabenhub erstellen, richtet der Azure Storage Anbieter diese Komponenten in Ihrem Speicherkonto ein:

  • Azure Tabellen:
    • In zwei Tabellen werden Ihre Historien und Instanzenzustände gespeichert.
    • Wenn Sie den Tabellenpartitions-Manager aktivieren, speichert eine dritte Tabelle Partitionsinformationen.
  • Azure Warteschlangen:
    • Eine Azure Warteschlange, in der Aktivitätsmeldungen gespeichert werden.
    • Eine oder mehrere Azure-Warteschlangen, in denen Instanznachrichten gespeichert werden.
      • Jede Steuerwarteschlange stellt eine Partition dar, der basierend auf dem Hash der Instanz-ID eine Teilmenge aller Instanznachrichten zugewiesen wird.
  • Azure Blobs:
    • Zusätzliche BLOB-Container für Lease-Blobs und/oder große Nachrichten.

Wenn Sie z. B. Ihren Aufgabenhub xyz benennen und festlegen PartitionCount = 4, werden diese Warteschlangen und Tabellen angezeigt:

Screenshot der Organisation des Aufgaben-Hubs des Azure Storage-Anbieters, das vier Kontrollwarteschlangen, Tabellen und Blob-Container zeigt.

Sehen wir uns jede Komponente an und verstehen, welche Rolle sie spielt.

Historientabelle für Orchestrierungsereignisse

Die Tabelle History ist eine Azure Storage Tabelle, die die Verlaufsereignisse für alle Orchestrierungsinstanzendaten innerhalb Ihres Aufgabenhubs enthält, einschließlich Ausgabenutzlasten aus Aktivitäts- und Suborchestratorfunktionen und Nutzlasten von externen Ereignissen. Der Tabellenname folgt dem Format <TaskHubName>History. Wenn Ihre Instanzen ausgeführt werden, werden dieser Tabelle neue Zeilen hinzugefügt. In dieser Tabelle:

  • Der Partitionsschlüssel wird von der Instanz-ID der Orchestrierung abgeleitet. Standardmäßig sind Instanz-IDs zufällig und stellen eine optimale Verteilung interner Partitionen in Azure Storage sicher.
  • Die Zeilentaste ist eine Sequenznummer, die die Verlaufsereignisse anordnet.

Wenn Sie eine Orchestrierungsinstanz ausführen müssen, lädt das System den vollständigen Verlauf mithilfe einer Bereichsabfrage in einer einzelnen Tabellenpartition in den Arbeitsspeicher. Diese Verlaufsereignisse werden in Ihrem Orchestrator-Funktionscode wiedergegeben und in den zuvor überprüften Zustand wiederhergestellt. Dieser Ansatz folgt dem Event Sourcing-Muster.

Dieser Ansatz erzeugt möglicherweise einen erheblichen Arbeitsspeicherdruck auf einem virtuellen Computer. Verringern Sie die Länge und Größe Ihrer Orchestrierungsgeschichte durch:

  • Aufteilen großer Orchestrierungen in mehrere Suborchestrationen.
  • Verringern Sie die Größe der Ausgaben, die von Ihren Aktivitäts- und Suborchestratorfunktionen zurückgegeben werden.
  • Verringern Sie die Gleichzeitigkeitsschwellen pro virtueller Maschine, um zu begrenzen, wie viele Orchestrierungen gleichzeitig in den Arbeitsspeicher geladen werden können.

Instanzen-Tabelle für den Orchestrierungs- und Entitätsstatus

Die Instanzentabelle enthält die Statuswerte aller Orchestrierungs- und Entitätsinstanzen innerhalb eines Aufgabenhubs. Beim Erstellen von Instanzen werden dieser Tabelle neue Zeilen hinzugefügt. In dieser Tabelle:

  • Der Partitionsschlüssel ist entweder die Orchestrierungsinstanz-ID oder der Entitätsschlüssel.
  • Der Zeilenschlüssel ist eine leere Zeichenfolge. Jede Orchestrierungs- oder Entitätsinstanz weist in der Regel eine Zeile auf.

Die Instanztabelle erfüllt Instanzabfrageanforderungen aus Code - und Statusabfrage-HTTP-API-Aufrufen . Sie bleibt schlussendlich konsistent mit dem Inhalt der Tabelle "Verlauf". Diese Trennung von Bedenken folgt dem CQRS-Muster (Command and Query Responsibility Segregation), das Instanzabfragevorgänge effizient verarbeitet.

Mit der Partitionierung der Instanzstabelle können Sie Millionen von Orchestrierungsinstanzen speichern, ohne dass sich dies auf die Laufzeitleistung oder skalierung auswirkt. Die Anzahl der Instanzen kann sich jedoch erheblich auf die Leistung von Abfragen mit mehreren Instanzen auswirken. Um zu steuern, wie viele Daten diese Tabellen speichern, sollten Sie in regelmäßigen Abständen alte Instanzdaten löschen.

Partitionsliste für die Arbeitsverteilung

Notiz

Diese Tabelle ist nur in Ihrem Aufgabenhub sichtbar, wenn Sie die Einstellung Table Partition Manager aktivieren. Um sie zu verwenden, konfigurieren Sie die useTablePartitionManagement Einstellung im host.jsonIhrer App.

Die Tabelle Partitions speichert den Partitionsstatus Ihrer Durable Functions-App und hilft beim Verteilen von Partitionen für die Mitarbeiter Ihrer App. Jede Partition weist eine Zeile auf.

Warteschlangen

Interne Warteschlangen im Aufgabenhub Ihrer Funktions-App lösen Ihre Orchestrator-, Entitäts- und Aktivitätsfunktionen aus und bieten zuverlässige "mindestens einmal"-Nachrichtenzustellungsgarantien. Durable Functions verwendet zwei Arten von Warteschlangen:

Auftragswarteschlange

In Durable Functions erhalten Sie eine Arbeitsaufgaben-Warteschlange pro Aufgabenhub. Es ist eine einfache Warteschlange, die sich wie jede andere queueTrigger-Warteschlange in Azure Functions verhält. Die Arbeitsaufgabenwarteschlange löst Ihre statuslosen Aktivitätsfunktionen aus, indem eine einzelne Nachricht gleichzeitig abgefragt wird. Jede Nachricht enthält Aktivitätsfunktionseingaben und Metadaten, z. B. welche Funktion ausgeführt werden soll. Wenn Ihre Durable Functions-Anwendung auf mehrere virtuelle Computer skaliert wird, konkurrieren sie darum, Aufgaben aus der Aufgabenwarteschlange zu übernehmen.

Steuern von Warteschlangen

Jeder Aufgabenhub in Durable Functions verfügt über mehrere Control-Warteschlangen. Eine Steuerelementwarteschlange ist komplexer als die einfachere Arbeitsaufgabenwarteschlange. Steuerungswarteschlangen lösen Ihre zustandsbehafteten Orchestrator- und Entitätsfunktionen aus. Da Orchestrator- und Entitätsfunktionsinstanzen zustandsbehaftete Singletons sind, darf jede Orchestrierung oder Entität nur von einem Worker gleichzeitig verarbeitet werden. Um dies zu erreichen, weist das System jede Orchestrierungsinstanz oder Entität einer einzigen Steuerwarteschlange zu. Diese Kontrollwarteschlangen sorgen für den Lastenausgleich zwischen Mitarbeitern, um sicherzustellen, dass jede Warteschlange jeweils nur von einem Mitarbeiter verarbeitet wird. Weitere Details zu diesem Verhalten finden Sie in späteren Abschnitten.

Steuerwarteschlangen enthalten verschiedene Orchestrierungslebenszyklus-Nachrichtentypen, wie zum Beispiel:

Das System entfernt bis zu 32 Nachrichten aus einer Kontrollwarteschlange in einer einzigen Umfrage. Diese Nachrichten enthalten Nutzlastdaten und Orchestrierungsinstanzmetadaten. Wenn mehrere dequeuierte Nachrichten auf dieselbe Orchestrierungsinstanz abzielen, werden sie als Batch verarbeitet.

Ein Hintergrundthread fragt ständig Nachrichten in der Warteschlange ab. Konfigurieren Sie die folgenden Warteschlangeneinstellungen in host.json:

  • controlQueueBatchSize: Steuern Sie die Batchgröße jeder Warteschlangenabfragung, die standardmäßig auf 32 festgelegt ist (der von Azure Warteschlangen unterstützte Maximalwert).
  • controlQueueBufferThreshold: Steuert die maximale Anzahl von Nachrichten in der Warteschlange, die im In-Memory gepuffert werden. Der Standardwert variiert je nach Faktoren wie Ihrem Hostingplantyp.

Weitere Informationen zu diesen Einstellungen finden Sie in der host.json Schemadokumentation .

Tip

Durch das Erhöhen des controlQueueBufferThreshold-Werts können einzelne Orchestrierungen oder Entitäten Ereignisse schneller verarbeiten. Es kann jedoch auch die Speicherauslastung erhöhen. Die höhere Speicherauslastung kommt zum Teil aus dem Ziehen weiterer Nachrichten aus der Warteschlange und zum Teil aus dem Abrufen weiterer Orchestrierungshistorien in den Speicher. Das Verringern des Werts kann die controlQueueBufferThreshold Speicherauslastung effektiv reduzieren.

Abfragen von Warteschlangen

Die Erweiterung "Durable Task" implementiert einen zufälligen exponentiellen Back-off-Algorithmus, um zu reduzieren, wie sich die Abfrage in leerer Warteschlange auf Speichertransaktionskosten auswirkt. Wenn die Laufzeit eine Nachricht findet, sucht sie sofort nach einer anderen Nachricht. Wenn keine Nachricht gefunden wird, wartet sie, bevor Sie es erneut versuchen. Nach nachfolgenden fehlgeschlagenen Versuchen, eine Warteschlangennachricht abzurufen, erhöht sich die Wartezeit weiterhin bis zur maximalen Wartezeit, die standardmäßig auf 30 Sekunden festgelegt ist.

Sie können die maximale Abrufverzögerung durch die Eigenschaft maxQueuePollingInterval in der host.json Datei konfigurieren.

  • Ein höherer Wert könnte zu höheren Nachrichtenverarbeitungslatenz führen, obwohl Sie nur höhere Latenzen nach Inaktivitätszeiträumen erwarten würden.
  • Ein niedrigerer Wert könnte aufgrund erhöhter Speichertransaktionen zu höheren Speicherkosten führen.

Notiz

Wenn Sie die Azure Functions Verbrauchs- und Premiumpläne nutzen, fragt der Azure Functions Scale Controller alle Kontroll- und Arbeitswarteschlangen alle 10 Sekunden ab. Diese zusätzliche Abfrage ist erforderlich, um zu bestimmen, wann Funktions-App-Instanzen aktiviert und Skalierungsentscheidungen getroffen werden sollen. Derzeit ist das 10-Sekunden-Intervall konstant und nicht konfiguriert.

Verzögerungen beim Starten der Orchestrierung

Orchestrierung-Instanzen starten, wenn das System eine ExecutionStarted Nachricht in eine der Warteschlangen des Task Hubs stellt. Unter bestimmten Bedingungen können Verzögerungen von mehreren Sekunden zwischen der Planung der Ausführung einer Orchestrierung und dem tatsächlichen Start auftreten. Während dieses Intervalls bleibt die Orchestrierungsinstanz im Pending Zustand. Für diese Verzögerungen gibt es zwei mögliche Gründe:

  • Backlogged Control Queues:

    Wenn die Steuerelementwarteschlange für Ihre Instanz eine große Anzahl von Nachrichten enthält, kann die Laufzeit zeitlang dauern, bevor sie die ExecutionStarted Nachricht empfängt und verarbeitet. Nachrichtenrückstände können auftreten, wenn Ihre Orchestrierungen von Abläufen eine große Anzahl von Ereignissen gleichzeitig verarbeiten. Zu den Ereignissen, die in die Steuerelementwarteschlange gelangen, gehören:

    • Orchestrierungsstartereignisse
    • Abschluss der Aktivität
    • Dauerhafte Timer
    • Beendigung
    • Externe Ereignisse

    Wenn eine Verzögerung des Backlogs unter normalen Umständen auftritt, erwägen Sie, einen neuen Aufgabenhub mit einer größeren Anzahl von Partitionen zu erstellen. Das Konfigurieren zusätzlicher Partitionen führt dazu, dass die Runtime weitere Steuerwarteschlangen zur Lastverteilung erstellt. Jede Partition entspricht 1:1 einer Kontrollwarteschlange. Es sind maximal 16 Partitionen möglich.

  • Rückabfragungsverzögerungen:

    Sie sollten nur ein Back-off-Abfrageverhalten für die zuvor beschriebenen Kontrollwarteschlangen beobachten, wenn Ihre App auf zwei oder mehr Instanzen skaliert. Sie können eine Verzögerung vermeiden, wenn:

    • Sie haben nur eine App-Instanz
    • Die App-Instanz, die die Orchestrierung startet, ist auch dieselbe Instanz, die die Zielsteuerungswarteschlange abfragt.

    Reduzieren Sie die Rückabfragungsverzögerungen, indem Sie Ihre host.json Einstellungen aktualisieren.

Blobs

In den meisten Fällen verwendet Durable Functions nicht Azure Storage Blobs zum Speichern von Daten. Warteschlangen und Tabellen weisen jedoch size limits auf, die verhindern können, dass Durable Functions alle erforderlichen Daten in einer Speicherzeile oder Warteschlangennachricht beibehalten.

Wenn beispielsweise ein Datenabschnitt, den Sie in einer Warteschlange beibehalten müssen, 45 KB überschreitet, wenn er serialisiert wird, komprimiert Durable Functions die Daten und speichert sie stattdessen in einem Blob. Beim Speichern von Daten im Blob Storage speichert Durable Functions eine Referenz auf diesen Blob in der Tabellenzeile oder der Warteschlangennachricht. Wenn Durable Functions die Daten abrufen muss, ruft sie sie automatisch aus dem Blob ab. Suchen Sie nach diesen BLOBs, die im BLOB-Container <taskhub>-largemessages gespeichert sind.

Leistungsüberlegungen

Die zusätzlichen Schritte für die Komprimierung und Speicherung im Blob bei großen Nachrichten können hohe Kosten in Bezug auf CPU und E/A-Latenz verursachen. Darüber hinaus muss Durable Functions gespeicherte Daten im Arbeitsspeicher laden und kann dies für viele verschiedene Funktionsausführungen gleichzeitig tun.

Daher kann das Beibehalten großer Datennutzlasten zu einer hohen Speicherauslastung führen. Um den Arbeitsspeicheraufwand zu minimieren, sollten Sie große Datennutzlasten manuell (z. B. im BLOB-Speicher) beibehalten und Verweise auf diese Daten übergeben. Ihr Code kann die Daten dann nur laden, wenn sie erforderlich sind, um redundante Lasten während der Orchestratorfunktionswiedergabe zu vermeiden.

Das Speichern von Nutzlasten auf lokalen Datenträgern wird nicht empfohlen, da der Zustand auf dem Datenträger nicht garantiert verfügbar ist. Funktionen können während ihrer gesamten Lebensdauer auf verschiedenen virtuellen Computern ausgeführt werden.

Konfigurieren des Azure Storage-Anbieters

Der Azure Storage-Anbieter ist der Standardspeicheranbieter und erfordert keine explizite Konfiguration, NuGet-Paketverweise oder Erweiterungsbundleverweise. Sie finden den vollständigen Satz von Durable Functions host.json Konfigurationsoptionen unter dem Pfad extensions/durableTask/storageProvider.

Connections

Die eigenschaft connectionName in host.json ist ein Verweis auf die Umgebungskonfiguration, die angibt, wie die App eine Verbindung mit Azure Storage herstellen soll. Folgendes kann angegeben werden:

  • Der Name eines gemeinsam genutzten Präfixes für mehrere Anwendungseinstellungen, die zusammen eine identitätsbasierte Verbindung definieren. Verwaltete Identitäten verwenden Microsoft Entra Authentifizierung, um die sicherste Verbindung mit Ihrem Speicherkonto bereitzustellen.
  • Der Name einer Anwendungseinstellung, die eine Verbindungszeichenfolge enthält. Um eine Verbindungszeichenfolge zu erhalten, führen Sie die unter Manage Speicherkontozugriffsschlüssel gezeigten Schritte aus.

Wenn der konfigurierte Wert sowohl eine genaue Übereinstimmung für eine einzelne Einstellung als auch eine Präfix-Übereinstimmung für andere Einstellungen ist, wird die genaue Übereinstimmung verwendet. Wenn in „host.json“ kein Wert angegeben ist, lautet der Standardwert AzureWebJobsStorage.

Identitätsbasierte Verbindungen

Wenn Sie Version 2.7.0 oder höher der Erweiterung nutzen und den Azure Speicheranbieter verwenden, können Sie anstelle eines Connection-Strings mit einem geheimen Schlüssel eine Microsoft Entra Identität nutzen. Dazu definieren Sie Einstellungen unter einem gemeinsamen Präfix, das der Eigenschaft connectionName in der Trigger- und Bindungskonfiguration entspricht.

Um eine identitätsbasierte Verbindung für Durable Functions zu verwenden, konfigurieren Sie die folgenden App-Einstellungen:

Eigentum Vorlage für Umgebungsvariable Description Beispielwert
Blob-Dienst-URI <CONNECTION_NAME_PREFIX>__blobServiceUri Der Datenebenen-URI des Blob-Diensts des Speicherkontos im HTTPS-Schema. https://<storage_account_name>.blob.core.windows.net
Warteschlangendienst-URI <CONNECTION_NAME_PREFIX>__queueServiceUri Der Datenebenen-URI des Warteschlangendiensts des Speicherkontos im HTTPS-Schema. https://<storage_account_name>.queue.core.windows.net
Tabellendienst-URI <CONNECTION_NAME_PREFIX>__tableServiceUri Der Datenebenen-URI eines Tabellendiensts des Speicherkontos im HTTPS-Schema. https://<storage_account_name>.table.core.windows.net

Es können zusätzliche Eigenschaften festgelegt werden, um die Verbindung anzupassen. Weitere Informationen finden Sie unter Allgemeine Eigenschaften für identitätsbasierte Verbindungen.

Beim Hosten im Azure Functions Dienst verwenden identitätsbasierte Verbindungen eine managed Identity. Standardmäßig wird eine vom System zugewiesene Identität verwendet, auch wenn mit den Eigenschaften credential und clientID eine vom Benutzer zugewiesene Identität angegeben werden kann. Beachten Sie, dass das Konfigurieren einer benutzerseitig zugewiesenen Identität mit einer Ressourcen-ID nicht unterstützt wird. Wird sie in anderen Kontexten ausgeführt, etwa bei der lokalen Entwicklung, wird stattdessen Ihre Entwickleridentität verwendet, dies lässt sich jedoch anpassen. Weitere Informationen finden Sie unter Lokale Entwicklung mit identitätsbasierten Verbindungen.

Berechtigung für die Identität erteilen

Unabhängig davon, welche Identität verwendet wird, muss diese über Berechtigungen zum Ausführen der vorgesehenen Aktionen verfügen. Für die meisten Azure Dienste bedeutet dies, dass Sie eine Rolle in Azure RBAC zuweisen müssen, indem Sie entweder integrierte oder benutzerdefinierte Rollen verwenden, die diese Berechtigungen bereitstellen.

Important

Vom Zieldienst werden möglicherweise einige nicht für alle Kontexte erforderliche Berechtigungen verfügbar gemacht. Befolgen Sie nach Möglichkeit das Prinzip der geringsten Berechtigung, und gewähren Sie der Identität nur die erforderlichen Berechtigungen. Wenn die App beispielsweise nur Daten aus einer Datenquelle lesen muss, verwenden Sie eine Rolle, die nur über Leseberechtigungen verfügt. Es wäre nicht angemessen, diesem Dienst eine Rolle zuzuweisen, die auch Schreibzugriff gewährt, da dies für eine Leseoperation eine zu weitreichende Berechtigung wäre. Ebenso sollten Sie sicherstellen, dass die Rollenzuweisung auf die Ressourcen begrenzt ist, die gelesen werden müssen.

Sie müssen eine Rollenzuweisung erstellen, die Zugriff auf Azure Speicher zur Laufzeit bietet. Verwaltungsrollen wie Besitzer sind nicht ausreichend. Die folgenden integrierten Rollen werden empfohlen, wenn Sie die Durable Functions Erweiterung im normalen Betrieb verwenden:

Ihre Anwendung erfordert möglicherweise weitere Berechtigungen basierend auf dem von Ihnen geschriebenen Code. Wenn Sie das Standardverhalten verwenden oder connectionName explizit auf „AzureWebJobsStorage“ festlegen, finden Sie unter Verbinden mit dem Hostspeicher mit einer Identität weitere Aspekte im Zusammenhang mit Berechtigungen.

Auswahl des Speicherkontos

Durable Functions erstellt die in einem konfigurierten Azure Storage Konto verwendeten Warteschlangen, Tabellen und Blobs. Sie können angeben, welches Konto in Ihrer host.json Datei verwendet werden soll.

  • Die Einstellung durableTask/storageProvider/connectionStringName (Durable Functions 2.x)
  • Die Einstellung durableTask/azureStorageConnectionStringName (in Durable Functions 1.x)
{
  "extensions": {
    "durableTask": {
      "storageProvider": {
        "connectionStringName": "MyStorageAccountAppSetting"
      }
    }
  }
}

Beachten Sie diese Überlegungen bei der Auswahl des Speicherkontos für Ihre App für dauerhafte Funktionen:

  • Konfigurieren Sie für leistungsabhängige Workloads ein anderes Speicherkonto als das Standardkonto (AzureWebJobsStorage). Da Durable Functions Azure Storage stark verwendet, isoliert ein dediziertes Speicherkonto Durable Functions Speichernutzung von der internen Nutzung durch den Azure Functions-Host.
  • Sie benötigen standardmäßige allgemeine Azure Storage Konten, wenn Sie den Azure Storage Anbieter verwenden. Andere Speicherkontotypen werden derzeit nicht unterstützt.
  • Legacy v1 allgemeine Speicherkonten für Durable Functions werden empfohlen. Die neueren v2-Speicherkonten können für Durable Functions Workloads teurer sein. Erfahren Sie mehr über Azure Storage Kontotypen.

Horizontales Skalieren des Orchestrators

Zwar können Sie Aktivitätsfunktionen unendlich skalieren, indem Sie weitere virtuelle Computer elastisch hinzufügen, aber einzelne Orchestratorinstanzen und Entitäten sind darauf beschränkt, eine einzelne Partition zu bewohnen. Die maximale Anzahl von Partitionen ist durch die partitionCount Konfiguration in Ihrer host.json begrenzt.

Notiz

Im Allgemeinen sollten Ihre Orchestratorfunktionen leicht sein und keine großen Datenmengen benötigen. Sie müssen keine große Anzahl von Kontrollwarteschlangen-Partitionen erstellen, um einen hohen Durchsatz bei Orchestrierungen zu gewährleisten. Sie sollten die meisten der schweren Arbeit in zustandslosen Aktivitätsfunktionen ausführen, die Sie unendlich skalieren können.

Sie definieren die Anzahl an Steuerwarteschlangen in Ihrer host.json Datei. Im folgenden Beispiel host.json wird die durableTask/storageProvider/partitionCount-Eigenschaft (durableTask/partitionCount in Durable Functions 1.x) auf 3 gesetzt. Sie haben so viele Steuerwarteschlangen wie Partitionen.

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

Sie können einen Aufgabenhub mit 1 bis 16 Partitionen konfigurieren. Wenn Sie keinen Wert angeben, ist die Standardpartitionsanzahl vier.

Bei Szenarien mit geringem Datenverkehr skaliert sich Ihre Anwendung, sodass nur wenige Mitarbeiter Ihre Partitionen verwalten. Im folgenden Diagramm können Sie beispielsweise sehen, dass die Orchestratoren 1 bis 6 über Partitionen hinweg gleichmäßig verteilt sind. Ähnlich werden Partitionen, wie zum Beispiel Aktivitäten, lastenbasiert auf Mitarbeiter verteilt. Ihre Partitionen haben ein Lastenausgleich zwischen Mitarbeitern, unabhängig davon, wie viele Orchestratoren gestartet werden.

Diagramm, das die Scale-In-Orchestrierung mit Partitionen zeigt, die von einer kleinen Anzahl von Workern verwaltet werden.

Wenn Sie im Azure Functions Consumption- oder Elastic Premium-Tarif arbeiten oder eine lastbasierte automatische Skalierung konfiguriert haben, werden bei zunehmendem Datenverkehr mehr Instanzen zugeteilt, und Ihre Partitionen werden gleichmäßig auf alle verteilt. Wenn Sie weiterhin eine Skalierung durchführen, verwaltet ein einzelner Worker die einzelnen Partitionen.

Aktivitäten werden weiterhin auf alle Mitarbeiter verteilt, wie in der folgenden Abbildung dargestellt.

Diagramm mit ersten skalierten Orchestrierungen mit Partitionen, die über Worker verteilt sind.

Die obere Grenze der maximalen Anzahl gleichzeitigen aktiven Orchestrierungen zu einem bestimmten Zeitpunkt entspricht der Anzahl der Worker, die Ihrer Anwendung zugeordnet sind, mal Ihrem Wert für maxConcurrentOrchestratorFunctions.

Sie können diese obere Schranke genauer machen, wenn Ihre Partitionen vollständig über Arbeiter verteilt skaliert sind. Wenn vollständig skaliert, da jeder Worker nur eine einzige Hostinstanz für Funktionen hat, entspricht die maximale Anzahl aktiver gleichzeitiger Orchestratorinstanzen der Anzahl Ihrer Partitionen multipliziert mit Ihrem Wert für .

Notiz

In diesem Kontext bedeutet aktiv, dass eine Orchestrierung oder Entität in den Arbeitsspeicher geladen wird und neue Ereignisseverarbeitet. Wenn Ihre Orchestrierung oder Entität auf weitere Ereignisse wartet, z. B. den Rückgabewert einer Aktivitätsfunktion, wird sie aus dem Speicher entladen und wird nicht mehr als aktiv betrachtet. Orchestrierungen und Entitäten werden später nur dann in den Arbeitsspeicher neu geladen, wenn neue Ereignisse zum Verarbeiten vorhanden sind. Es gibt keine praktische maximale Anzahl von Gesamt-Orchestrierungen oder Entitäten, die auf einem einzelnen virtuellen Computer ausgeführt werden können, auch wenn sie sich alle im Zustand "Ausführen" befinden. Die einzige Einschränkung ist die Anzahl gleichzeitig aktiver Orchestrierungs- oder Entitätsinstanzen.

Die folgende Abbildung zeigt ein vollständig skaliertes Szenario, in dem weitere Orchestratoren hinzugefügt werden, aber einige sind inaktiv, in Grau dargestellt.

Diagramm, das zweite skalierte Orchestrierungen mit mehr Orchestratoren zeigt, von denen einige inaktiv sind.

Während der Skalierung werden die Kontrollwarteschlangen-Leases möglicherweise über Funktionen-Host-Instanzen verteilt, um sicherzustellen, dass Ihre Partitionen gleichmäßig verteilt werden. Diese Leases werden intern als Azure Blob Storage-Leases implementiert und stellen sicher, dass jede einzelne Orchestrierungsinstanz oder Entität jeweils nur auf einer einzelnen Hostinstanz ausgeführt wird. Wenn Sie einen Aufgabenhub mit drei Partitionen (und daher drei Kontrollwarteschlangen) konfigurieren, können Orchestrierungsinstanzen und Entitäten zur Lastverteilung über alle drei lease-haltenden Hostinstanzen genutzt werden. Sie können weitere virtuelle Computer hinzufügen, um die Kapazität für die Ausführung der Aktivitätsfunktion zu erhöhen.

Das folgende Diagramm veranschaulicht, wie der Azure Functions Host mit den Speicherentitäten in einer skalierten Umgebung interagiert.

Diagramm, das zeigt, wie Azure Functions Host während des Scaleouts mit Speicherentitäten interagiert.

Alle virtuellen Maschinen konkurrieren um Nachrichten in der Arbeitsaufgabenwarteschlange. Allerdings können nur drei virtuelle Maschinen Nachrichten aus Steuerwarteschlangen abrufen, und jede virtuelle Maschine sperrt eine einzelne Steuerwarteschlange.

Instanzen und Entitäten der Orchestrierung sind auf alle Instanzen der Steuerwarteschlange verteilt. Die Verteilung erfolgt durch Hashing der Instanz-ID der Orchestrierung oder des Entitätsnamens und des Schlüsselpaars. Da Orchestrierungsinstanz-IDs per Voreinstellung zufällige GUIDs sind, werden Instanzen gleichmäßig über alle Steuerwarteschlangen verteilt.

Erweiterte Sitzungen

Erweiterte Sitzungen sind ein Cache-Mechanismus, der Ihre Orchestrierungen und Entitäten im Speicher hält, selbst nachdem die Nachrichtenverarbeitung abgeschlossen ist. Wenn Sie erweiterte Sitzungen aktivieren, sehen Sie normalerweise eine reduzierte E/A gegenüber dem zugrunde liegenden dauerhaften Speicher und einen insgesamt verbesserten Durchsatz.

Sie können erweiterte Sitzungen aktivieren, indem Sie durableTask/extendedSessionsEnabled auf true in Ihrer host.json Datei setzen. Mit der durableTask/extendedSessionIdleTimeoutInSeconds Einstellung können Sie steuern, wie lange eine Leerlaufsitzung im Arbeitsspeicher verbleibt:

{
  "extensions": {
    "durableTask": {
      "extendedSessionsEnabled": true,
      "extendedSessionIdleTimeoutInSeconds": 30
    }
  }
}

Beachten Sie zwei mögliche Nachteile dieser Einstellung:

  • Die allgemeine Speicherauslastung Ihrer Funktions-App erhöht sich, da Leerlaufinstanzen nicht so schnell aus dem Arbeitsspeicher entladen werden.
  • Wenn Sie viele gleichzeitige, unterschiedliche, kurzlebige Orchestrator- oder Entitätsfunktionsausführungen haben, können Sie insgesamt einen geringeren Durchsatz sehen.

Wenn Sie durableTask/extendedSessionIdleTimeoutInSeconds auf 30 Sekunden festlegen, belegt eine kurzlebige Orchestrator- oder Entitätsfunktions-Episode, die in weniger als 1 Sekunde ausgeführt wird, dennoch 30 Sekunden Arbeitsspeicher. Zudem wird sie auf das zuvor erwähnte Kontingent durableTask/maxConcurrentOrchestratorFunctions angerechnet, sodass möglicherweise verhindert wird, dass andere Orchestrator- oder Entitätsfunktionen ausgeführt werden.

Erweiterte Sitzungen wirken sich auf Orchestrator- und Entitätsfunktionen unterschiedlich aus. Sehen wir uns an, wie sie mit Orchestratorfunktionen arbeiten.

Wiedergabe von Funktionen des Orchestrators

Wie bereits erwähnt, gibt das System Orchestratorfunktionen mithilfe des Inhalts der Tabelle "Verlauf" wieder. Standardmäßig wird der Orchestratorfunktionscode jedes Mal erneut ausgeführt, wenn eine Serie von Nachrichten aus einer Kontrollwarteschlange entfernt wird. Auch wenn Sie das Lüfter-/Fan-In-Muster verwenden und auf alle auszuführenden Aufgaben warten, treten Wiedergaben auf, wenn Batches von Aufgabenantworten im Laufe der Zeit verarbeitet werden. Wenn Sie erweiterte Sitzungen aktivieren, bleiben Orchestratorfunktionsinstanzen länger im Arbeitsspeicher, und neue Nachrichten können ohne vollständige Wiedergabe des Verlaufs verarbeitet werden.

Am häufigsten können Sie die Leistungsverbesserung erweiterter Sitzungen beobachten, wenn:

  • Sie haben eine begrenzte Anzahl von Orchestrierungsinstanzen, die gleichzeitig ausgeführt werden.
  • Ihre Orchestrierungen verfügen über eine große Anzahl sequenzieller Aktionen (z. B. Hunderte von Aktivitätsfunktionsaufrufen), die schnell abgeschlossen werden.
  • Ihre Orchestrierungen fan-out und fan-in eine große Anzahl von Aktionen, die ungefähr zur gleichen Zeit abgeschlossen werden.
  • Ihre Orchestratorfunktionen müssen große Nachrichten verarbeiten oder cpuintensive Datenverarbeitungen durchführen.

In allen anderen Situationen wird in der Regel keine erkennbare Leistungsverbesserung für Orchestratorfunktionen angezeigt.

Notiz

Sie sollten diese Einstellungen nur verwenden, nachdem Sie Ihre Orchestratorfunktion vollständig entwickelt und getestet haben. Das standardmäßige aggressive Wiedergabeverhalten kann hilfreich sein, um Verletzungen von Orchestratorfunktionscodeeinschränkungen zur Entwicklungszeit zu erkennen, sodass sie standardmäßig deaktiviert ist.

Leistungsziele

In der folgenden Tabelle sind die erwarteten maximalen Durchsatznummern für den Szenarioartikel aufgeführt.

"Instanz" bezieht sich auf eine einzelne Instanz einer Orchestratorfunktion, die auf einem einzelnen kleinen virtuellen Computer (A1) in Azure App Service ausgeführt wird. In allen Fällen wird davon ausgegangen, dass Sie erweiterte Sitzungen aktiviert haben. Ihre tatsächlichen Ergebnisse können je nach CPU- oder E/A-Arbeit variieren, die ihr Funktionscode ausführt.

Szenario Maximaler Durchsatz
Sequenzielle Aktivitätsausführung Fünf Aktivitäten pro Sekunde, pro Instanz
Parallele Aktivitätsausführung (Fan-out) 100 Aktivitäten pro Sekunde pro Instanz
Parallele Antwortverarbeitung (Zusammenführung) 150 Antworten pro Sekunde pro Instanz
Externe Ereignisverarbeitung 50 Ereignisse pro Sekunde pro Instanz
Verarbeitung von Operationen von Entitäten 64 Vorgänge pro Sekunde

Wenn die erwarteten Durchsatznummern nicht angezeigt werden und die CPU- und Speicherauslastung fehlerfrei angezeigt wird, überprüfen Sie, ob die Ursache mit der Integrität Ihres Speicherkontos verbunden ist. Die Durable Functions Erweiterung kann erhebliche Lasten auf ein Azure Storage Account setzen, und ausreichend hohe Lasten können zu einer Drosselung des Storage-Accounts führen.

Tip

In einigen Fällen können Sie den Durchsatz externer Ereignisse, die Sammlung von Aktivitäten (Fan-In) und Entitätsvorgänge erhöhen, indem Sie den Wert der controlQueueBufferThreshold Konfigurationseinstellung in Ihrer host.json erhöhen. Wenn Sie diesen Wert über die Standardeinstellung hinaus erhöhen, verwendet der Speicheranbieter des Durable Task Frameworks mehr Arbeitsspeicher, um diese Ereignisse aggressiver vorabzuladen, wodurch Verzögerungen reduziert werden, die mit dem Abrufen von Nachrichten aus den Steuerwarteschlangen von Azure Storage verbunden sind. Weitere Informationen finden Sie in der Referenzdokumentation zu host.json.

Flex-Verbrauchsplan

Der Flex-Verbrauch-Plan ist ein Azure Functions Hostingplan, der viele Vorteile des Verbrauchsplans bietet, einschließlich:

  • Ein serverloses Abrechnungsmodell
  • Private Netzwerke
  • Auswahl der Speichergröße der Instanz
  • Vollständige Unterstützung für die Authentifizierung verwalteter Identitäten

Sie sollten diese Leistungsempfehlungen befolgen, wenn Sie Durable Functions im Flex-Verbrauchsplan hosten:

  • Legen Sie die Anzahl der stets bereiten Instanzen für die Gruppe durable auf 1 fest. Diese Einstellung stellt sicher, dass Sie immer eine Instanz bereit haben, Durable Functions verwandte Anforderungen zu verarbeiten, wodurch der Kaltstart Ihrer Anwendung reduziert wird.
  • Reduzieren Sie das Intervall für die Warteschlangenabfrage auf 10 Sekunden oder weniger. Da dieser Plantyp sensibler für Abfrageverzögerungen in der Warteschlange ist, trägt das Verringern des Abrufintervalls dazu bei, die Häufigkeit von Abrufvorgängen zu erhöhen, um sicherzustellen, dass Anforderungen schneller verarbeitet werden. Häufigere Polling-Vorgänge führen jedoch zu höheren Azure-Storage-Konto-Kosten.

Verarbeitung mit hohem Durchsatz mit dem Durable Task Scheduler

Die Azure Storage Back-End-Architektur setzt bestimmte Einschränkungen auf die maximale theoretische Leistung und Skalierbarkeit von Durable Functions. Wenn Ihre Tests zeigen, dass dauerhafte Funktionen in Azure Storage Ihre Durchsatzanforderungen nicht erfüllen, erwägen Sie den Wechsel zum Durable Task Scheduler, dem empfohlenen Speicheranbieter für dauerhafte Funktionen.

Der permanente Aufgabenplaner ist ein vollständig verwalteter Azure-Dienst, der für dauerhafte Aufgabenarbeitslasten entwickelt wurde. Im Vergleich zum Azure Storage-Anbieter bietet der Durable Task Scheduler Folgendes:

  • Geringere Latenz durch Push-basiertes Streamen von Arbeitsaufgaben über gRPC, wodurch die Notwendigkeit einer Warteschlangenabfragung nicht mehr erforderlich ist.
  • Verringerter Ressourcenverbrauch ohne separates Speicherkonto zum Bereitstellen oder Verwalten.
  • Integrierte Überwachung über das Dashboard des Durable Task Schedulers zum Filtern, Überprüfen und Verwalten von Orchestrierungsinstanzen.
  • Automatische Bereinigung mit konfigurierbaren automatischen Aufbewahrungsrichtlinien für veraltete Orchestrierungsdaten.

Vorhandene Apps für dauerhafte Funktionen können ohne Codeänderungen zum Dauerhaften Aufgabenplaner migriert werden. Erste Schritte finden Sie unter "Schnellstart: Erstellen eines dauerhaften Aufgabenplanungsmoduls".

Weitere Informationen zu allen unterstützten Speicheranbietern für dauerhafte Funktionen und deren Vergleich finden Sie in der Dokumentation zu Speicheranbietern für dauerhafte Funktionen .

Nächste Schritte