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.
Steuern Sie die Häufigkeit, mit der Ihre Anwendung Anforderungen an einen Dienst sendet, damit Sie innerhalb der Einschränkungsgrenzen und der Gesamtkapazität des Diensts bleiben. Dieser Ansatz hilft Ihnen, Drosselungsfehler zu vermeiden oder zu minimieren und den Durchsatz genauer vorherzusagen.
Die Ratelimitierung eignet sich in vielen Szenarien, aber es ist besonders hilfreich für groß angelegte, sich wiederholende automatisierte Aufgaben wie die Batchverarbeitung.
Kontext und Problem
Das Ausführen einer großen Anzahl von Vorgängen für einen gedrosselten Dienst kann zu einem erhöhten Datenverkehr und zu einem reduzierten Durchsatz führen, da Sie abgelehnte Anforderungen nachverfolgen und dann die Vorgänge wiederholen müssen. Da sich die Anzahl der Vorgänge erhöht, kann ein Einschränkungslimit mehrere Läufe des erneuten Sendens von Daten erfordern, was zu einer größeren Leistungsbeeinträchtigung führt.
Betrachten Sie beispielsweise den folgenden problematischen Retry-on-Error-Prozess zum Aufnehmen von Daten in Azure Cosmos DB:
Von Ihrer Anwendung müssen 10.000 Datensätze in Azure Cosmos DB erfasst werden. Jeder Datensatz kostet 10 Anforderungseinheiten (RUs), um den Auftrag abzuschließen, sodass insgesamt 100.000 RUs erforderlich sind.
Für Ihre Azure Cosmos DB-Instanz wurde eine Kapazität von 20.000 RUs bereitgestellt.
Sie senden alle 10.000 Datensätze an Azure Cosmos DB. 2.000 Datensätze werden erfolgreich geschrieben, und 8.000 Datensätze werden abgelehnt.
Sie senden die übrigen 8.000 Datensätze an Azure Cosmos DB. 2.000 Datensätze werden erfolgreich geschrieben, und 6.000 Datensätze werden abgelehnt.
Sie senden die übrigen 6.000 Datensätze an Azure Cosmos DB. 2.000 Datensätze werden erfolgreich geschrieben, und 4.000 Datensätze werden abgelehnt.
Sie senden die übrigen 4.000 Datensätze an Azure Cosmos DB. 2.000 Datensätze werden erfolgreich geschrieben, und 2.000 Datensätze werden abgelehnt.
Sie senden die restlichen 2.000 Datensätze an Azure Cosmos DB. Alle Datensätze werden erfolgreich geschrieben.
Der Aufnahmeauftrag wird erfolgreich abgeschlossen, aber erst nach dem Senden von 30.000 Datensätzen an Azure Cosmos DB. Der gesamte Datensatz besteht aus nur 10.000 Datensätzen.
In diesem Beispiel sind weitere Faktoren zu berücksichtigen:
Eine große Anzahl von Fehlern kann auch zu einer zusätzlichen Arbeit führen, um diese Fehler zu protokollieren und die resultierenden Protokolldaten zu verarbeiten. Der vorherige Ansatz behandelt 20.000 Fehler, und die Protokollierung dieser Fehler kann eine Verarbeitungs-, Speicher- oder Speicherressourcenkosten auferlegen.
Da Sie die Einschränkungsgrenzwerte des Aufnahmediensts nicht kennen, haben Sie keine Möglichkeit, Erwartungen für die Dauer der Datenverarbeitung festzulegen. Die Ratenbegrenzung ermöglicht Ihnen die Berechnung der für die Erfassung benötigten Zeit.
Lösung
Die Ratenbegrenzung kann Ihren Datenverkehr verringern und potenziell den Durchsatz verbessern. Hierzu wird die Anzahl von Datensätzen reduziert, die über einen bestimmten Zeitraum an einen Dienst gesendet werden.
Ein Dienst kann Anforderungen basierend auf verschiedenen Metriken im Laufe der Zeit drosseln, z. B.:
- Die Anzahl von Vorgängen (beispielsweise 20 Anforderungen pro Sekunde)
- Die Datenmenge (beispielsweise 2 GiB pro Minute)
- Die relativen Kosten von Vorgängen (beispielsweise 20.000 RUs pro Sekunde)
Unabhängig von der Metrik, die Sie für die Drosselung verwenden, umfasst die Implementierung der Ratebegrenzung die Steuerung der Anzahl und/oder Größe von Vorgängen, die während eines bestimmten Zeitraums an den Dienst gesendet werden. Durch die Einschränkung der Rate wird ihre Nutzung des Diensts optimiert, ohne die Drosselungskapazität zu überschreiten.
In Szenarien, in denen Ihre APIs Anforderungen schneller verarbeiten können als gedrosselte Aufnahmedienste zulassen, müssen Sie verwalten, wie schnell Sie den Dienst verwenden. Das Behandeln der Drosselung nur als Datenratenkonflikt und das Puffern von Eingabeanforderungen, bis sich der Dienst erholt, stellt ein Risiko dar. Wenn Ihre Anwendung in diesem Szenario nicht mehr reagiert, gehen möglicherweise alle gepufferten Daten verloren.
Zur Vermeidung dieses Risikos empfiehlt es sich gegebenenfalls, die Datensätze an ein langlebiges Messagingsystem zu senden, das in der Lage ist, Ihre Erfassungsrate vollständig auszunutzen. (Dienste wie Azure Event Hubs können Millionen von Vorgängen pro Sekunde verarbeiten.) Sie können dann einen oder mehrere Auftragsverarbeiter verwenden, um die Datensätze aus dem Messagingsystem mit einer kontrollierten Rate zu lesen, die sich innerhalb der Grenzwerte des gedrosselten Diensts befindet. Die Übermittlung von Datensätzen an das Messagingsystem trägt zur Entlastung des internen Arbeitsspeichers bei, da Sie so die Möglichkeit haben, nur Datensätze aus der Warteschlange zu entnehmen, die während eines bestimmten Zeitintervalls verarbeitet werden können.
Azure bietet mehrere langlebige Messagingdienste, die mit diesem Muster verwendet werden können. Hierzu zählen beispielsweise:
Wenn Sie Datensätze senden, ist der Zeitraum, den Sie zum Freigeben von Datensätzen verwenden, möglicherweise präziser als der Zeitraum, für den der Dienst aktiviert wird. Systeme setzen häufig Drosselungen basierend auf Zeitbereichen, mit denen Sie leicht verstehen und arbeiten können. Für den Computer, auf dem ein Dienst ausgeführt wird, können diese Zeitrahmen jedoch im Vergleich zur schnellen Verarbeitung von Informationen sehr lang sein. So kann ein System beispielsweise pro Sekunde oder pro Minute drosseln, während der Code üblicherweise in der Größenordnung von Nano- oder Millisekunden arbeitet.
Obwohl es nicht erforderlich ist, wird häufig empfohlen, kleinere Datensätze häufiger zu senden, um den Durchsatz zu verbessern. Anstatt also versuchen, Datensätze für eine Freigabe einmal pro Sekunde oder einmal pro Minute zu stapeln, können Sie präziser sein als dies, um den Ressourcenverbrauch (Arbeitsspeicher, CPU und Netzwerk) gleichmäßiger zu halten. Dieser Ansatz verhindert potenzielle Engpässe, die durch plötzliche Brüche von Anforderungen verursacht werden. Wenn ein Dienst beispielsweise 100 Vorgänge pro Sekunde zulässt, kann ein Ratelimiter die Anforderungen gleichmäßig verteilen, indem er alle 200 Millisekunden 20 Vorgänge freigibt, wie im nachstehenden Diagramm gezeigt.
Darüber hinaus ist es manchmal erforderlich, dass sich mehrere nicht koordinierte Prozesse einen gedrosselten Dienst teilen. Um die Ratebegrenzung in diesem Szenario zu implementieren, können Sie die Kapazität des Diensts logisch partitionieren und dann ein verteiltes gegenseitiges Ausschlusssystem verwenden, um exklusive Sperren für diese Partitionen zu verwalten. Die nicht koordinierten Prozesse können dann um Sperren für diese Partitionen konkurrieren, wenn sie Kapazität benötigen. Für jede Partition, für die ein Prozess über eine Sperre verfügt, wird ihm eine bestimmte Kapazität erteilt.
Wenn das gedrosselte System beispielsweise 500 Anforderungen pro Sekunde bewältigen kann, können Sie 20 Partitionen mit jeweils 25 Anforderungen pro Sekunde erstellen. Wenn ein Prozess 100 Anfragen stellen müsste, könnte er beim verteilten System für gegenseitigen Ausschluss vier Partitionen anfordern. Das System könnte für zehn Sekunden zwei Partitionen zuweisen. Der Prozess begrenzt daraufhin die Rate auf 50 Anforderungen pro Sekunde, schließt die Aufgabe in zwei Sekunden ab und gibt anschließend die Sperre frei.
Eine Möglichkeit zum Implementieren dieses Musters ist die Verwendung von Azure Storage. In diesem Szenario wird pro logischer Partition in einem Container ein einzelnes 0-Byte-Blob erstellt. Ihre Anwendungen können dann für einen kurzen Zeitraum (beispielsweise 15 Sekunden) direkt exklusive Leases für diese Blobs beziehen. Für jede Lease wird eine Anwendung gewährt, sie kann die Kapazität dieser Partition verwenden. Die Anwendung muss dann die Leasezeit nachverfolgen, damit die Anwendung, wenn die Zeit abläuft, die Nutzung der gewährten Kapazität beenden kann. Wenn Sie dieses Muster implementieren, möchten Sie häufig, dass jeder Prozess versucht, eine zufällige Partition zu leasen, wenn es Kapazität benötigt.
Zur weiteren Verkürzung der Wartezeit kann für jeden Prozess eine kleine exklusive Kapazitätsmenge zugeordnet werden. Ein Prozess würde dann nur versuchen, ein Nutzungsrecht für gemeinsam genutzte Kapazität zu erhalten, wenn er seine reservierte Kapazität überschreiten müsste.
Alternativ zu Azure Storage können Sie diese Art von Lease-Management auch mithilfe von Technologien wie ZooKeeperusw. und Redis/Redsync implementieren.
Probleme und Überlegungen
Berücksichtigen Sie die folgenden Punkte, wenn Sie sich für die Implementierung dieses Musters entscheiden:
Obwohl das Muster "Rate Limiting" die Anzahl der Drosselungsfehler verringern kann, muss Ihre Anwendung dennoch alle möglicherweise auftretenden Drosselungsfehler ordnungsgemäß behandeln.
Stellen Sie sicher, dass Wiederholungen mit der Zinsbegrenzung koordiniert werden. Blinde oder übermäßig aggressive Wiederholungsversuche können die Last erhöhen und Wiederholungsstürme erzeugen, daher verbreiten Sie Rückdrucksignale (z. B. HTTP 429 mit
Retry-After) und verwenden Sie eine begrenzte Anzahl von Wiederholungen mit kleinen zufälligen Verzögerungen zwischen Versuchen.Wenn Ihre Anwendung über mehrere Arbeitsabläufe verfügt, die auf denselben gedrosselten Dienst zugreifen, müssen Sie alle in Ihre Strategie für die Zinsbegrenzung integrieren. Vielleicht unterstützen Sie beispielsweise das Massenladen von Datensätzen in eine Datenbank sowie das Abfragen von Datensätzen in der gleichen Datenbank. Sie können die Kapazität verwalten, indem Sie sicherstellen, dass alle Arbeitsabläufe über den gleichen Mechanismus zur Begrenzung der Geschwindigkeit gegatet werden. Alternativ können Sie separate Kapazitätspools für jeden Arbeitsstream reservieren.
Der gedrosselte Dienst kann in mehreren Anwendungen verwendet werden. In einigen Fällen ist es möglich, diese Verwendung zu koordinieren (wie weiter oben in diesem Artikel gezeigt). Wenn sie beginnen, eine größere als erwartete Anzahl von Drosselungsfehlern zu sehen, kann diese erhöhte Zahl auf die Differenz zwischen Anwendungen hinweisen, die auf einen Dienst zugreifen. In diesem Fall müssen Sie ggf. die vorübergehende Reduzierung des durch den Satzbegrenzungsmechanismus auferlegten Durchsatz in Betracht ziehen, bis die Verwendung von anderen Anwendungen abnimmt.
Wann dieses Muster verwenden
Verwenden Sie dieses Muster in folgenden Fällen:
Sie müssen Drosselungsfehler reduzieren, die durch einen eingeschränkten Dienst ausgelöst werden.
Sie möchten den Datenverkehr im Vergleich zu naiven Retry-on-Error-Ansätzen minimieren.
Sie müssen den Speicherverbrauch reduzieren, indem Sie Datensätze nur aufheben, wenn genügend Kapazität zum Verarbeiten vorhanden ist.
Dieses Muster ist möglicherweise nicht geeignet, wenn:
Der Vorgang erfordert einen sofortigen, synchronen Abschluss mit sehr geringer Latenz und kann keine Warteschlange oder verzögerte Verarbeitung tolerieren.
Der primäre Engpass ist nicht die Anforderungsrate, sondern die Parallelität oder der Ressourcenkonflikt (z. B. CPU-Sättigung oder lang laufende In-Flight-Arbeit). In diesen Fällen sind Skalierungs- oder Parallelitätssteuerelemente besser geeignet.
Arbeitslastgestaltung
Bewerten Sie, wie Sie das Muster "Rate Limiting" im Entwurf einer Workload verwenden, um die in den Azure Well-Architected Framework-Säulen behandelten Ziele und Prinzipien zu erfüllen. Die folgende Tabelle enthält Anleitungen dazu, wie dieses Muster die Ziele jeder Säule unterstützt.
| Säule | So unterstützt dieses Muster die Säulenziele |
|---|---|
| Zuverlässigkeitsentwurfsentscheidungen helfen Ihrer Arbeitsauslastung, ausfallsicher zu werden und sicherzustellen, dass sie nach auftreten eines Fehlers wieder in einen voll funktionsfähigen Zustand versetzt wird. | Diese Taktik schützt den Client, indem er die Einschränkungen und Kosten der Kommunikation mit einem Dienst erkennt und berücksichtigt, wenn der Dienst eine übermäßige Nutzung vorzieht. - RE:07 Selbsterhaltung |
Wenn dieses Muster Kompromisse innerhalb einer Säule einführt, sollten Sie sie gegen die Ziele der anderen Säulen berücksichtigen.
Example
Mit der folgenden Beispielanwendung können Benutzer verschiedenartige Datensätze an eine API übermitteln. Jeder Datensatztyp verfügt über einen eindeutigen Auftragsverarbeiter, der die folgenden Schritte ausführt:
- Überprüfen
- Anreicherung
- Hinzufügung des Datensatzes zur Datenbank
Alle Komponenten der Anwendung (API, Auftragsprozessor A und Auftragsprozessor B) sind separate Prozesse, die unabhängig voneinander skaliert werden können. Die Prozesse kommunizieren nicht direkt miteinander.
In diesem Beispiel stellt jede BLOB-Lease einen festen Anteil des zulässigen Datenbankdurchsatzes dar. Ein Auftragsverarbeiter kann nur in Kombination mit den aktuell gespeicherten Leasingverhältnissen dequeue und schreiben. Wenn Prozessoren im Laufe der Zeit Leases gewinnen oder verlieren, ändert sich die zulässige Schreibrate, wodurch der gesamte Datenbankdatenverkehr innerhalb des konfigurierten Grenzwerts bleibt und gleichzeitig der gesamte Arbeitsfortschritt in der Warteschlange bleibt.
Dieses Diagramm zeigt den folgenden Workflow:
- Ein Benutzer übermittelt 10.000 Datensätze vom Typ A an die API.
- Die API stellt diese 10.000 Datensätze in der Warteschlange A in die Warteschlange A.
- Ein Benutzer übermittelt 5.000 Datensätze vom Typ B an die API.
- Die API queue diese 5.000 Datensätze in der Warteschlange B.
- Auftragsverarbeiter A sieht, dass die Warteschlange A Datensätze enthält und versucht, eine exklusive Lease für Blob 2 zu erhalten.
- Auftragsverarbeiter B sieht, dass die Warteschlange B Datensätze enthält und versucht, eine exklusive Lease für Blob 2 zu erhalten.
- Auftragsverarbeiter A kann die Lease nicht erhalten.
- Auftragsverarbeiter B erhält die Lease für BLOB 2 für 15 Sekunden. Anfragen an die Datenbank können nun auf 100 pro Sekunde begrenzt werden.
- Auftragsverarbeiter B entqueues 100 Datensätze aus der Warteschlange B und schreibt sie.
- Eine Sekunde vergeht.
- Auftragsverarbeiter A sieht, dass die Warteschlange A mehr Datensätze enthält und versucht, eine exklusive Lease für Blob 6 zu erhalten.
- Auftragsverarbeiter B sieht, dass die Warteschlange B mehr Datensätze enthält und versucht, eine exklusive Lease für Blob 3 zu erhalten.
- Auftragsverarbeiter A ruft die Lease für BLOB 6 für 15 Sekunden ab. Anfragen an die Datenbank können nun auf 100 pro Sekunde begrenzt werden.
- Auftragsprozessor B erhält die Lease für BLOB 3 für 15 Sekunden. Es kann nun Datenbankanfragen auf 200 pro Sekunde begrenzen. (Der Prozessor verfügt auch noch über die Lease für das Blob 2.)
- Auftragsverarbeiter A entqueues 100 Datensätze aus der Warteschlange A und schreibt sie.
- Auftragsverarbeiter B entqueues 200 Datensätze aus der Warteschlange B und schreibt sie.
- Eine Sekunde vergeht.
- Auftragsprozessor A sieht, dass die Warteschlange A mehr Datensätze enthält und versucht, eine exklusive Lease für Blob 0 zu erhalten.
- Auftragsverarbeiter B sieht, dass die Warteschlange B mehr Datensätze enthält und versucht, eine exklusive Lease für Blob 1 zu erhalten.
- Auftragsprozessor A erhält die Lease für BLOB 0 für 15 Sekunden. Es kann nun Datenbankanfragen auf 200 pro Sekunde begrenzen. (Der Prozessor verfügt auch noch über die Lease für das Blob 6.)
- Auftragsverarbeiter B ruft die Lease für BLOB 1 für 15 Sekunden ab. Es kann jetzt die Anfragen an die Datenbank auf 300 pro Sekunde begrenzen. (Es verfügt auch über das Leasingrecht für die Blobs 2 und 3.)
- Auftragsverarbeiter A entqueues 200 Datensätze aus der Warteschlange A und schreibt sie.
- Auftragsverarbeiter B entqueues 300 Datensätze aus der Warteschlange B und schreibt sie.
- Und so weiter.
Nach 15 Sekunden wird ein oder beide Aufträge noch nicht abgeschlossen. Wenn die Leases ablaufen, sollte ein Prozessor auch die Anzahl der Anforderungen verringern, die er dequeues und schreibt.
Implementierungen dieses Musters sind in verschiedenen Programmiersprachen verfügbar:
Nächste Schritte
Die folgenden Anleitungen können auch relevant sein, wenn Sie dieses Muster implementieren:
Erweiterte Anforderungseinschränkung mit Azure API Management. Verwenden Sie dies als ergänzende Edge-Zulassungskontrolle, um die Grenzwerte und Quoten pro Schlüssel zu erzwingen und konsistente Rückdrucksignale an Kunden zurückzugeben.
Auswahl von Azure-Messagingdiensten: Event Grid, Event Hubs und Service Bus. Wählen Sie das beste dauerhafte Messaging-Backbone für puffernde und kontrollierte Aufnahme aus.
Behandeln sie vorübergehende Fehler in Azure Anwendungen. Entwurfs-Wiederholungsverhalten, sodass Clients bei Erreichen von Grenzwerten ordnungsgemäß deaktiviert werden.
Verwandte Ressourcen
Die folgenden Muster und Anleitungen können auch relevant sein, wenn Sie dieses Muster implementieren:
Throttling. Das Muster "Rate Limiting" wird in der Regel als Reaktion auf einen gedrosselten Dienst implementiert.
Retry. Wenn Anforderungen an einen gedrosselten Dienst zu Drosselungsfehlern führen, ist es in der Regel angemessen, diese Anforderungen nach einem entsprechenden Intervall erneut zu versuchen.
Queue-Based Lastenausgleich ähnelt dem Muster "Rate Limiting", unterscheidet sich jedoch auf verschiedene Arten:
Bei der Ratenbegrenzung muss die Lastverwaltung nicht unbedingt über Warteschlangen erfolgen, es muss aber ein langlebiger Messagingdienst verwendet werden. Beispielsweise kann ein Muster für die Ratenbegrenzung Dienste wie Apache Kafka oder Event Hubs verwenden.
Das Muster "Rate Limiting" führt das Konzept eines verteilten gegenseitigen Ausschlusssystems auf Partitionen ein, mit dem Sie die Kapazität für mehrere nicht koordinierte Prozesse verwalten können, die mit demselben gedrosselten Dienst kommunizieren.
Ein Queue-Based Lastenausgleichsmuster ist anwendbar, wenn zwischen Diensten ein Leistungskonflikt auftritt oder Sie Resilienz verbessern möchten. Daher handelt es sich um ein breiteres Muster als die Zinsbegrenzung, das sich genauer mit dem effizienten Zugriff auf einen gedrosselten Dienst befasst.