Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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.
Hinweis
Erkunden Sie andere unterstützte Speicheranbieter basierend auf Ihren spezifischen Anforderungen.
Speicherdarstellung
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:
Sehen wir uns jede Komponente an und verstehen, welche Rolle sie spielt.
-
Verlaufstabelle(
xyzHistory) -
Instances table(
xyzInstances) - Partitionstabelle
-
Arbeitsaufgabenwarteschlange(
xyz-workitems) -
Steuerungs-Warteschlangen(
xyz-control-00,xyz-control-01,xyz-control-02,xyz-control-03) -
Blobs und Blob Leases(
xyz-largemessages,xyz-applease,xyz-leases)
Verlaufstabelle
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 historischen Ereignisse werden im Funktionscode Ihres Orchestrators wiedergegeben und stellen so den zuvor gespeicherten Zustand wieder her. 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.
- Verkleinerung der Ausgabegröße Ihrer Aktivitäts- und Suborchestratorfunktionen.
- Senken Sie die Parallelitätsdrosselungen pro virtueller Maschine, um zu limitieren, wie viele Orchestrationen parallel in den Speicher geladen werden können.
Instanztabelle
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 schließlich konsistent mit dem Inhalt der History-Tabelle. 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.
Partitionstabelle
Hinweis
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 Task-Hub Ihrer Funktions-App lösen Ihre Orchestrator-, Entitäts- und Aktivitätsfunktionen aus und gewährleisten 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 Warteschlange für Arbeitselemente triggert Ihre statuslosen Aktivitätsfunktionen, indem sie jeweils eine einzelne Nachricht aus der Warteschlange nimmt. 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 Entity-Funktionsinstanzen zustandsbehaftete Singletons sind, darf jede Orchestrierung bzw. Entity 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 einen Lastausgleich zwischen den Workern, um sicherzustellen, dass jede Warteschlange jeweils nur von einem Worker bearbeitet wird. Weitere Details zu diesem Verhalten finden Sie in späteren Abschnitten.
Steuerwarteschlangen enthalten verschiedene Orchestrierungslebenszyklus-Nachrichtentypen, wie zum Beispiel:
- Orchestrator-Steuerungsnachrichten
- Antwortmeldungen der Aktivitätsfunktion
- Timer-Nachrichten
Das System ruft in einem einzigen Abfragevorgang bis zu 32 Nachrichten aus einer Steuerwarteschlange ab. Diese Nachrichten enthalten Nutzlastdaten und Orchestrierungsinstanzmetadaten. Wenn mehrere dequeuierte Nachrichten auf dieselbe Orchestrierungsinstanz abzielen, werden sie als Batch verarbeitet.
Ein Hintergrund-Thread fragt ständig die Nachrichten der Steuerwarteschlange 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 .
Tipp
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.
Abrufen von Warteschlangen
Die Durable Task-Erweiterung implementiert einen zufälligen exponentiellen Backoff-Algorithmus, um zu reduzieren, wie sich das Polling der Leerlaufwarteschlange auf die 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 Polling-Verzögerung über die Eigenschaft maxQueuePollingInterval in der Datei host.json 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.
Hinweis
Bei der Ausführung in den Azure Functions Consumption- und Premium-Plänen fragt der Azure Functions-Skalierungscontroller jede Steuerungs- und Arbeitselementwarteschlange einmal 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 der Ausführung auftreten. Während dieses Intervalls bleibt die Orchestrierungsinstanz im Pending Zustand. Für diese Verzögerungen gibt es zwei mögliche Gründe:
Backlog Warteschlangen:
Wenn die Warteschlange Ihrer Instanz eine große Anzahl von Nachrichten enthält, kann es einige Zeit dauern, bis die Laufzeit die
ExecutionStarted-Nachricht erhält und verarbeitet. Nachrichtenrückstände können entstehen, wenn Ihre Orchestrierungen viele Ereignisse 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.
Verzögerungen beim Abbruch des Pollings:
Das oben beschriebene Abbrechen der Abfrage von Warteschlangen sollte auftreten wenn Ihre App auf zwei oder mehr Instanzen skaliert . Sie können eine Verzögerung vermeiden, wenn:
- Sie haben nur eine App-Instanz
- Die Anwendungsinstanz, die die Orchestrierung startet, ist auch dieselbe Instanz, die die Zielsteuerungswarteschlange abfragt.
Reduzieren Sie die Rückabfragungsverzögerungen, indem Sie Ihre
host.jsonEinstellungen 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.
Überlegungen zur Leistung
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 Speicheranbieters
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.
Verbindungen
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 connection string enthält. Um eine connection string 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 | Beschreibung | 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. Bei Ausführung in anderen Kontexten (z. B. bei der lokalen Entwicklung) wird stattdessen Ihre Entwickleridentität verwendet, Dieses Verhalten kann angepasst werden. Weitere Informationen finden Sie unter Lokale Entwicklung mit identitätsbasierten Verbindungen.
Erteilen der Berechtigung für die Identität
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.
Von Bedeutung
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, eine Rolle zu zuweisen, die auch das Schreiben in diesen Dienst zulässt, da dies eine übermäßige Berechtigung für einen Lesevorgang 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:
- Mitwirkender an Speicherblobdaten
- Mitwirkender an Storage-Warteschlangendaten
- Storage Table Data-Beitragender
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.
- Für Durable Functions werden Legacy v1-Allzweckspeicherkonten 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.
Hinweis
Im Allgemeinen sollten Ihre Orchestratorfunktionen leicht sein und keine großen Datenmengen benötigen. Sie müssen keine große Anzahl von Steuerwarteschlangen-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 Worker Ihre Partitionen verwalten. Im folgenden Diagramm ist beispielsweise zu sehen, dass die Orchestratoren 1 bis 6 über die Partitionen verteilt lastverteilt sind. Ebenso erfolgt bei Partitionen, ähnlich wie für Aktivitäten, über Worker hinweg ein Lastenausgleich. Ihre Partitionen haben ein Lastenausgleich zwischen Workern, unabhängig davon, wie viele Orchestratoren gestartet werden.
Wenn Sie die Azure Functions Consumption- oder Elastic Premium-Pläne verwenden oder eine lastbasierte automatische Skalierung konfiguriert haben, werden bei steigendem Datenverkehr mehr Worker zugewiesen, und Ihre Partitionen werden schließlich auf alle Worker verteilt. Bei weiterer Skalierung wird schließlich jede Partition von einem einzelnen Worker verwaltet.
Aktivitäten werden weiterhin auf alle Worker verteilt, wie in der folgenden Abbildung dargestellt.
Die Obergrenze für die maximale Anzahl paralleler aktiver Orchestrierungen zu einem bestimmten Zeitpunkt entspricht der Anzahl der Ihrer Anwendung zugewiesenen Worker mal Ihrem Wert für maxConcurrentOrchestratorFunctions.
Sie können diese obere Grenze genauer bestimmen, wenn Ihre Partitionen vollständig auf die Worker skaliert sind. Da jeder Worker nur über eine einzige Host-Instanz von Functions verfügt, entspricht die maximale Anzahl der aktiven parallelen Orchestrierung der Anzahl der Partitionen mal Ihres Wertes für maxConcurrentOrchestratorFunctions.
Hinweis
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.
Bei der horizontalen Skalierung werden Steuerungswarteschlangen-Leases möglicherweise neu über Functions-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 Task-Hub mit drei Partitionen (und damit drei Steuerungswarteschlangen) konfigurieren, können Orchestrierungsinstanzen und -entitäten auf alle drei Hostinstanzen, die die Lease halten, verteilt 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.
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.
Orchestrierungsinstanzen und Entitäten sind auf alle Steuerwarteschlangeninstanzen verteilt. Die Verteilung erfolgt durch Hashing der Instanz-ID der Orchestrierung oder des Entitätsnamens und des Schlüsselpaars. Da die Orchestrierungsinstanz-IDs standardmäßig zufällige GUIDs sind, werden die Instanzen gleichmäßig auf 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 verlängerte Sitzungen aktivieren, werden Sie in der Regel eine reduzierte E/A-Last gegenüber dem zugrunde liegenden persistenten Speicher und einen insgesamt verbesserten Durchsatz feststellen.
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, replayt das System Orchestrator-Funktionen anhand des Inhalts der Historie-Tabelle. Standardmäßig wird Ihr Orchestratorfunktionscode immer dann wiedergegeben, wenn ein Batch von Nachrichten aus einer Steuerelement-Warteschlange entfernt wird. Selbst wenn Sie das Auffächern nach außen/innen-Muster verwenden und warten, bis alle Aufgaben abgeschlossen sind, kommt es zu Wiederholungen, da nach und nach Stapel von Aufgabenantworten 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 fächern eine große Anzahl von Aktionen nach außen und innen auf, 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.
Hinweis
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 (Auffächern nach außen) | 100 Aktivitäten pro Sekunde pro Instanz |
| Parallele Antwortverarbeitung (Auffächern nach innen) | 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 eine beträchtliche Auslastung eines Azure Storage-Kontos verursachen, und entsprechend hohe Auslastungen können zu einer Drosselung des Speicherkontos führen.
Tipp
In einigen Fällen können Sie den Durchsatz von externen Ereignissen, Aktivitäts-Fan-Ins und Entitäten-Operationen erhöhen, indem Sie den Wert der controlQueueBufferThreshold-Einstellung in Ihrem 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
- Privates Netzwerk
- 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
durableauf1fest. 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
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 Durable Functions auf Azure Storage ihre Durchsatzanforderungen nicht erfüllt, sollten Sie stattdessen den Netherite-Speicheranbieter für Durable Functions verwenden.
Vergleichen Sie den erreichbaren Durchsatz für verschiedene grundlegende Szenarien.
Das Netherite-Speicher-Back-End wurde von Microsoft Research entworfen und entwickelt. Es verwendet Azure Event Hubs und die FASTER Datenbanktechnologie auf Azure Page Blobs. Das Design von Netherite ermöglicht eine Verarbeitung mit höherem Durchsatz von Orchestrierungen und Entitäten im Vergleich zu anderen Anbietern. In einigen Benchmark-Szenarien erhöhte sich der Durchsatz im Vergleich zum Standardanbieter Azure Storage um mehr als eine Größenordnung.
Weitere Informationen zu den unterstützten Speicheranbietern für Durable Functions und deren Vergleich finden Sie in der Dokumentation Durable Functions Speicheranbieter.