Skalierungsrisiken steuern

Mit Cloud Tasks können Sie große Mengen asynchroner Aufgaben senden und gleichzeitig die Rate steuern, mit der Traffic Ihre Warteschlangen und nachgelagerten Dienste erreicht. Durch die Anwendung von schrittweisen Hochlaufmustern und Ratenkontrollen können Sie Arbeitslasten reibungslos skalieren, ohne dass es zu Spitzen bei der Warteschlangenlatenz oder zu einer Überlastung des Ziels kommt, wenn der Traffic schneller steigt, als sich die Infrastruktur anpassen kann.

Übersicht

Dieses Dokument enthält Richtlinien zu Best Practices für die Aufrechterhaltung einer hohen Cloud Tasks-Leistung in Warteschlangen mit hohem Traffic. Eine Warteschlange mit hoher TPS ist eine Warteschlange mit 500 oder mehr erstellten oder gesendeten Aufgaben pro Sekunde (TPS). Eine Warteschlangengruppe mit hoher TPS ist eine zusammenhängende Gruppe von Warteschlangen, z. B. [queue0001, queue0002, …, queue0099], in denen insgesamt mindestens 2.000 Aufgaben pro Sekunde erstellt oder gesendet werden. Sie können die historischen TPS einer Warteschlange oder einer Gruppe von Warteschlangen mithilfe der Cloud Monitoring-Messwerte aufrufen, api/request_count für CreateTask-Vorgänge und queue/task_attempt_count für Aufgabenversuche. Warteschlangen und Warteschlangengruppen mit hohem Traffic sind anfällig für zwei verschiedene Arten von Fehlern:

Eine Warteschlangenüberlastung tritt auf, wenn die Erstellung und Verteilung von Aufgaben an eine einzelne Warteschlange oder Warteschlangengruppe schneller zunimmt, als sich die Warteschlangeninfrastruktur anpassen kann. Die Infrastruktur von Google verwendet adaptive Ebenen, die die Last basierend auf Traffic-Mustern dynamisch neu verteilen. Diese Anpassung braucht Zeit. Eine Zielüberlastung tritt auf, wenn die Aufgabenverteilungsrate zu Traffic-Spitzen in der nachgelagerten Zielinfrastruktur führt. In beiden Fällen sollten Sie das 500/50/5-Muster befolgen: Wenn Sie über 500 TPS skalieren, erhöhen Sie den Traffic alle 5 Minuten um maximal 50 %.

Unabhängig vom 500/50/5-Muster für Arbeitslasten mit hohen TPS-Werten wirkt sich der anfängliche Warteschlangen-Hochlauf auf alle Warteschlangen aus, wenn sie aus einem kalten oder inaktiven Zustand gestartet werden, einschließlich Warteschlangen, die für moderate Versandraten konfiguriert sind. In diesem Dokument werden verschiedene Szenarien beschrieben, die Skalierungsrisiken mit sich bringen können. Außerdem finden Sie Beispiele für die Verwaltung des Warteschlangen-Hochlaufs und die Anwendung des 500/50/5-Musters.

Anfänglicher Warteschlangenaufbau

Das 500/50/5-Muster gilt für Warteschlangen mit hohen TPS, die bereits in einem stabilen Zustand sind. Der anfängliche Warteschlangen-Ramp-up ist ein separater Systemmechanismus, der für alle Warteschlangen gilt, einschließlich Warteschlangen, die für moderate Versandraten wie 20–100 TPS konfiguriert sind, wenn sie von einem kalten oder inaktiven Zustand in den stabilen Betrieb übergehen.

Eine Warteschlange wechselt in den folgenden Situationen in den Status „Kalt“ oder „Inaktiv“:

  • Die Warteschlange wurde neu erstellt oder nach einer Pause fortgesetzt.

  • Die Warteschlange war auch nur für wenige Minuten ohne aktive Sendungen inaktiv.

  • Die Warteschlange wird nach dem Backoff von nachgelagerten HTTP-Fehlerantworten vom Typ 429 oder 5xx wiederhergestellt. Weitere Informationen dazu, wie sich der Backoff-Fehler auf die Versandraten auswirkt, finden Sie unter Backoff-Fehler und erzwungene Raten.

Wenn Aufgaben in einer kalten oder inaktiven Warteschlange ankommen, werden sie von Cloud Tasks nicht sofort mit der konfigurierten max_dispatches_per_second-Rate gesendet. Um nachgelagerte Ziele vor plötzlichen Traffic-Spitzen zu schützen, beginnt Cloud Tasks mit dem Senden mit einer niedrigen Basisrate, z. B. etwa 1 TPS. Anschließend wird die erzwungene Versandrate in regelmäßigen Bewertungsintervallen schrittweise erhöht. Die erzwungene Rate wird so lange erhöht, wie die Warteschlangennachfrage gesättigt ist und Ziel-Handler HTTP-2xx-Antworten zurückgeben. Je nach Zielrate kann es einige Minuten dauern, bis hohe max_dispatches_per_second-Werte erreicht werden.

Wenn Ihre Arbeitslast ungleichmäßigen Traffic sendet, der durch kurze inaktive Zeiträume von einigen Minuten oder mehr getrennt ist, wird die Warteschlange zwischen den Bursts auf einen kalten Zustand zurückgesetzt und dieser Hochlaufprozess wird bei jedem Burst wiederholt. So minimieren Sie Hochlaufverzögerungen für burst-empfindliche Arbeitslasten: Beachten Sie die folgenden Best Practices:

  • Sorgen Sie für einen gleichmäßigen Baseline-Traffic, um latenzempfindliche Warteschlangen zwischen Bursts warm zu halten.

  • Verwenden Sie vorhandene Warteschlangen wieder, anstatt sie häufig zu löschen und neu zu erstellen.

  • Stellen Sie ausreichend Downstream-Zielkapazität bereit, damit Handler HTTP-2xx-Antworten zurückgeben und keine HTTP-429- oder 5xx-Fehlerantworten zurückgeben, die die erzwungene Versandrate zurücksetzen.

Warteschlangen-Drosselung diagnostizieren

Wenn Ihre Warteschlange Aufgaben langsamer als die konfigurierte max_dispatches_per_second-Rate sendet, prüfen Sie, ob der Engpass durch das Hochfahren einer kalten oder inaktiven Warteschlange, Backoff bei Überlastung des Ziels oder Nebenläufigkeitslimits verursacht wird.

Hochfahren einer kalten oder inaktiven Warteschlange

Die anfängliche Warteschlangen-Hochskalierung ist wahrscheinlich die Ursache, wenn alle folgenden Bedingungen erfüllt sind:

  • Die Warteschlange wurde vor Kurzem erstellt, nach einer Pause fortgesetzt oder war einige Minuten inaktiv, bevor Traffic eingegangen ist.
  • Aufgabenversuche sind ohne Zielfehler erfolgreich und zeigen response_code="OK" im Monitoring-Messwert cloudtasks.googleapis.com/queue/task_attempt_count an.
  • Die Anzahl der laufenden Sendungen bleibt unter max_concurrent_dispatches, während cloudtasks.googleapis.com/queue/depth oder cloudtasks.googleapis.com/queue/task_attempt_delays erhöht ist. Gleichzeitig wird die Versandrate in cloudtasks.googleapis.com/queue/task_attempt_count schrittweise über regelmäßige Bewertungsintervalle erhöht.

Weitere Informationen zu Monitoring-Messwerten finden Sie unter Messwerte an Monitoring senden.

Zielüberlastung und Backoff bei Überlastung

Cloud Tasks reduziert die Versandraten dynamisch, wenn Ihr nachgelagertes Ziel HTTP-429 Too Many Requests- oder HTTP-5xx-Fehlerantworten wie HTTP-503 Service Unavailable zurückgibt. Dieser Backoff verhindert eine Überlastung des Ziels.

Wenn Sie prüfen möchten, ob Zielfehler dazu führen, dass Cloud Tasks die Zustellung drosselt, rufen Sie den Monitoring-Messwert cloudtasks.googleapis.com/queue/task_attempt_count auf, gruppiert nach dem Label response_code. Wenn das Warteschlangen-Logging aktiviert ist, können Sie die Logs der Antwortversuche auch im Log-Explorer prüfen:

resource.type="cloud_tasks_queue"
jsonPayload.attemptResponseLog.status!="OK"

Sowohl in response_code als auch in jsonPayload.attemptResponseLog.status zeichnet Cloud Tasks kanonische gRPC-Statuscodes anstelle von numerischen HTTP-Statuscodes auf. Beispiel: HTTP 429 wird RESOURCE_EXHAUSTED zugeordnet, HTTP 503 wird UNAVAILABLE zugeordnet, HTTP 500 wird INTERNAL zugeordnet und HTTP 504 oder eine Zeitüberschreitung wird DEADLINE_EXCEEDED zugeordnet.

Wenn Sie RESOURCE_EXHAUSTED, UNAVAILABLE oder andere Serverfehlerstatus vom Ziel erhalten, skalieren Sie die Ziel-Dienstinstanzen hoch oder erhöhen Sie die Ziel-Nebenläufigkeit, bevor Sie die Versandlimits für die Warteschlange erhöhen.

Weitere Informationen zum Aktivieren von Warteschlangenlogs finden Sie unter Cloud Logging mit Warteschlangen verwenden.

Engpass bei der Nebenläufigkeit

Gemäß dem Satz von Little begrenzt die nachgelagerte Ziellatenz den maximalen Durchsatz:

Max Throughput (tasks/sec) = min(
  max_dispatches_per_second,
  max_concurrent_dispatches / Downstream Latency in seconds
)

Wenn die Downstream-Ausführungslatenz beispielsweise 2 Sekunden beträgt und max_concurrent_dispatches auf 100 festgelegt ist, ist der Durchsatz auf 50 Aufgaben pro Sekunde begrenzt, auch wenn max_dispatches_per_second auf 500 konfiguriert ist.

Um zu diagnostizieren, ob die Nebenläufigkeit der Engpass ist, teilen Sie max_concurrent_dispatches durch die Zielantwortlatenz, die im Feld jsonPayload.attemptResponseLog.attemptDuration in Logging aufgezeichnet wurde. Vergleichen Sie diesen berechneten Schwellenwert mit Ihrer tatsächlichen Versandrate im Monitoring-Messwert cloudtasks.googleapis.com/queue/task_attempt_count. Wenn die tatsächlichen Dispatches in der Nähe dieses Schwellenwerts stagnieren, während cloudtasks.googleapis.com/queue/depth oder cloudtasks.googleapis.com/queue/task_attempt_delays wächst, führen Sie eine der folgenden Aktionen aus:

  • Wenn Ihr Downstream-Ziel über freie Kapazität verfügt, z. B. wenn Aufgaben die meiste Zeit auf externe E/A warten, erhöhen Sie max_concurrent_dispatches.
  • Wenn Ihr Downstream-Ziel bereits eine hohe Ressourcenauslastung aufweist, kann eine Erhöhung von max_concurrent_dispatches die Zielüberlastung verschlimmern. Skalieren Sie stattdessen Ihre Zielinstanzen horizontal oder reduzieren Sie die Latenz bei der Handler-Ausführung.

Warteschlangenüberlastung

Warteschlangen oder Warteschlangengruppen können jederzeit überlastet werden, wenn der Traffic plötzlich zunimmt. In diesen Warteschlangen kann Folgendes auftreten:

  • Erhöhte Latenz bei der Aufgabenerstellung
  • Erhöhte Fehlerrate bei der Aufgabenerstellung
  • Geringere Weiterleitungsrate

Um sich davor zu schützen, sollten Sie in jeder Situation, in der die Erstellungs- oder Versandrate einer Warteschlange oder Warteschlangengruppe plötzlich ansteigen kann, Kontrollen einrichten. Beginnen Sie mit maximal 500 Vorgängen pro Sekunde für eine kalte Warteschlange oder Warteschlangengruppe und erhöhen Sie den Traffic dann alle 5 Minuten um 50 %. Theoretisch können Sie mit diesem Hochlaufplan nach 90 Minuten auf 740.000 Vorgänge pro Sekunde skalieren. Es gibt eine Reihe von Umständen, unter denen dies auftreten kann.

Beispiel:

  • Beim Implementieren neuer Funktionen, die in großem Umfang Cloud Tasks nutzen
  • Beim Verschieben von Traffic zwischen Warteschlangen
  • Bei der gleichmäßigen Verteilung der Traffic-Last auf mehr oder weniger Warteschlangen
  • Beim Ausführen von Batchjobs, die eine große Anzahl von Aufgaben einfügen

Wenden Sie in diesen und anderen Fällen das 500/50/5-Muster an.

Aufteilung des Traffics in App Engine verwenden

Wenn eine App Engine-Anwendung die Aufgaben erstellt, können Sie die Aufteilung des Traffics in App Engine (App Engine-Standardumgebung oder flexible App Engine-Umgebung) nutzen, um Traffic-Anstiege zu glätten. Wenn Sie den Traffic auf verschiedene Versionen aufteilen (Standardumgebung oder flexible Umgebung), können Sie die Anzahl der ratenverwalteten Anfragen im Laufe der Zeit erhöhen, um den Zustand der Warteschlange zu schützen. Betrachten wir als Beispiel den Fall, dass der Traffic zu einer neu erweiterten Warteschlangengruppe erhöht wird: [queue0000, queue0199] ist eine Sequenz von Warteschlangen mit hoher TPS,die insgesamt 100.000 TPS-Erstellungen zu Spitzenzeiten erhalten.

Die neue Warteschlangensequenz ist [queue0200, queue0399]. Nachdem Sie den gesamten Traffic verschoben haben, verdoppelt sich die Anzahl der Warteschlangen in der Sequenz und der neue Warteschlangenbereich erhält 50 % des gesamten Traffics der Sequenz.

Wenn Sie die Version bereitstellen, die die Anzahl der Warteschlangen erhöht, erhöhen Sie den Traffic zur neuen Version und damit zu den neuen Warteschlangen schrittweise mithilfe der Traffic-Aufteilung:

  • Beginnen Sie damit, 1 % des Traffics in die neue Version zu verschieben. Beispiel: 50 % von 1 % von 100.000 TPS ergibt 500 TPS für die neuen Warteschlangen.
  • Erhöhen Sie den Traffic, der an den neuen Release gesendet wird, alle 5 Minuten um 50 %, wie in der folgenden Tabelle beschrieben:
Minuten seit Bereitstellungsbeginn % des in die neue Version verschobenen Gesamt-Traffics % des Gesamt-Traffics für die neuen Warteschlangen % des Gesamt-Traffics für die alten Warteschlangen
0 1,0 0,5 99,5
5 1,5 0,75 99,25
10 2,3 1,15 98,85
15 3,4 1,7 98,3
20 5,1 2,55 97,45
25 7,6 3,8 96,2
30 11,4 5,7 94,3
35 17,1 8,55 91,45
40 25,6 12,8 87,2
45 38,4 19,2 80,8
50 57,7 28,85 71,15
55 86,5 43,25 56,75
60 100 50 50

Releasebedingte Traffic-Spitzen

Wenn Sie einen Release veröffentlichen, der den Traffic zu einer Warteschlange oder Warteschlangengruppe erheblich erhöht, ist die graduelle Einführung ebenfalls ein wichtiger Mechanismus, um die Erhöhungen zu glätten. Führen Sie Ihre Instanzen schrittweise ein, sodass beim ersten Start nicht mehr als 500 Vorgänge pro Sekunde für die neuen Warteschlangen ausgeführt werden. Erhöhen Sie die Anzahl der Vorgänge alle 5 Minuten um maximal 50 %.

Neue Warteschlangen oder Warteschlangengruppen mit hohen TPS

Neu erstellte Warteschlangen sind besonders anfällig. Gruppen von Warteschlangen, z. B. [queue0000, queue0001, …, queue0199], sind in den ersten Roll-out-Phasen genauso empfindlich wie einzelne Warteschlangen. Für diese Warteschlangen ist die schrittweise Einführung eine wichtige Strategie. Führen Sie neue oder aktualisierte Dienste, die Warteschlangen oder Warteschlangengruppen mit hohen TPS-Werten erstellen, schrittweise ein. Halten Sie die anfängliche Last unter 500 TPS und erhöhen Sie die Last um maximal 50 % in Abständen von mindestens 5 Minuten.

Kürzlich erweiterte Warteschlangengruppen

Wenn Sie die Gesamtkapazität einer Warteschlangengruppe erhöhen, z. B. queue0000-queue0199 auf queue0000-queue0399 erweitern, folgen Sie dem 500/50/5-Muster. Bei Roll-out-Verfahren verhalten sich neue Warteschlangengruppen nicht anders als einzelne Warteschlangen. Wenden Sie das 500/50/5-Muster auf die neue Gruppe als Ganzes an, nicht nur auf einzelne Warteschlangen innerhalb der Gruppe.

Für diese Erweiterungen von Warteschlangengruppen ist die schrittweise Einführung eine wichtige Strategie. Wenn die Traffic-Quelle App Engine ist, können Sie die Aufteilung des Traffics verwenden. Wenn Sie Ihren Dienst migrieren, um Aufgaben zu der erhöhten Anzahl von Warteschlangen hinzuzufügen, sollten Sie Ihre Instanzen schrittweise bereitstellen, damit beim ersten Start nicht mehr als 500 Vorgänge für die neuen Warteschlangen ausgeführt werden. Erhöhen Sie den Traffic alle 5 Minuten um maximal 50 %.

Warteschlangengruppen im Notfall erweitern

Gelegentlich möchten Sie vielleicht eine vorhandene Warteschlangengruppe erweitern, z. B. weil Sie erwarten, dass der Warteschlangengruppe schneller Aufgaben hinzugefügt werden, als die Gruppe sie senden kann. Wenn Sie die Namen der neuen Warteschlangen gleichmäßig auf die vorhandenen Warteschlangennamen in lexikografischer Reihenfolge verteilen, können Sie sofort Traffic an diese Warteschlangen senden. Achten Sie darauf, dass nicht mehr als 50 % neue verschachtelte Warteschlangen vorhanden sind und dass der Traffic zu jeder Warteschlange weniger als 500 TPS beträgt. Diese Methode ist eine Alternative zur Aufteilung des Traffics und zur graduellen Einführung.

Um diese Art von verschachtelter Benennung zu erreichen, hängen Sie ein Suffix an Warteschlangen an, die auf gerade Zahlen enden. Wenn Sie beispielsweise 200 vorhandene Warteschlangen [queue0000–queue0199] haben und 100 neue Warteschlangen erstellen möchten, wählen Sie [queue0000a, queue0002a, queue0004a, …, queue0198a] als neue Warteschlangennamen anstelle von [queue0200–queue0299].

Wenn Sie eine weitere Erhöhung benötigen, können Sie alle 5 Minuten bis zu 50 % mehr Warteschlangen verschachteln.

Aufgaben in großem Umfang oder im Batch in die Warteschlange stellen

Wenn Sie eine große Anzahl von Aufgaben hinzufügen müssen, z. B. Millionen oder Milliarden, kann ein Double-Injection-Muster nützlich sein. Anstatt Aufgaben aus einem einzelnen Job zu erstellen, verwenden Sie eine Injektor-Warteschlange. Jede Aufgabe, die der Injektor-Warteschlange hinzugefügt wird, wird aufgeteilt und fügt der relevanten Warteschlange oder Warteschlangengruppe 100 Aufgaben hinzu. Sie können die Injector-Warteschlange im Laufe der Zeit beschleunigen. Beginnen Sie beispielsweise mit 5 TPS, um 500 TPS in der Zielwarteschlange oder Warteschlangengruppe zu generieren, und erhöhen Sie die Rate dann alle 5 Minuten um 50 %.

Benannte Aufgaben

Wenn Sie eine neue Aufgabe erstellen, weist Cloud Tasks der Aufgabe standardmäßig einen eindeutigen Namen zu. Mit dem Parameter name können Sie einer Aufgabe einen eigenen Namen zuweisen. Dies führt jedoch zu signifikanten Leistungseinbußen sowie zu erhöhten Latenzen und möglicherweise zu höheren Fehlerraten für die benannten Aufgaben. Sequenzielle Aufgabennamen wie Zeitstempel können diesen Overhead erheblich vergrößern.

Wenn Sie eigene Namen zuweisen, verwenden Sie ein gut verteiltes Präfix für Aufgabennamen, z. B. einen Hash des Inhalts. Weitere Informationen zum Benennen einer Aufgabe finden Sie in der Feldreferenz zu Task.name.

Zielüberlastung

Cloud Tasks kann nachgelagerte Dienste und Ressourcen, die Sie verwenden, wie App Engine, Firestore im Datastore-Modus (Datastore) und Ihr Netzwerk, überlasten, wenn die Warteschlangenverteilung plötzlich stark ansteigt. Wenn sich ein Rückstand an Aufgaben angesammelt hat, kann das Aufheben der Pausierung dieser Warteschlangen diese Dienste möglicherweise überlasten. Um eine Überlastung des Ziels zu vermeiden, sollten Sie das 500/50/5-Muster befolgen: Wenn eine Warteschlange mehr als 500 TPS sendet, erhöhen Sie den von einer Warteschlange ausgelösten Traffic alle 5 Minuten um maximal 50 %. Verwenden Sie Monitoring-Messwerte, um Traffic-Anstiege proaktiv zu überwachen. Mit Monitoring-Benachrichtigungen können Sie potenziell gefährliche Situationen erkennen.

Pausierung von Warteschlangen mit hohen TPS aufheben oder fortsetzen

Wenn Sie eine pausierte Warteschlange fortsetzen, wendet Cloud Tasks die anfängliche Warteschlangen-Hochlaufphase an und erhöht die Versandrate schrittweise von einer niedrigen Baseline auf die konfigurierte max_dispatches_per_second-Rate der Warteschlange. Wenn sich jedoch ein großer Rückstand an Aufgaben in einer Warteschlange mit hoher TPS oder in mehreren Warteschlangen ansammelt, die Sie gleichzeitig fortsetzen, kann die Versandrate immer noch schneller steigen, als nachgelagerte Zieldienste skaliert werden können. Wenn Sie Warteschlangen mit einem großen Backlog fortsetzen, sollten Sie die Fortsetzung mehrerer Warteschlangen zeitlich versetzt vornehmen, um eine Überlastung des Ziels zu vermeiden. Alternativ können Sie die max_dispatches_per_second-Rate vorübergehend senken und dann nach dem 500/50/5-Muster schrittweise erhöhen. Weitere Informationen dazu, wie Cloud Tasks die Verteilung drosselt und hochfährt, wenn Warteschlangen fortgesetzt werden, finden Sie unter Backoff-Fehler und erzwungene Raten.

Im Bulk geplante Aufgaben

Eine große Anzahl von Aufgaben, die gleichzeitig gesendet werden sollen, kann auch zu einer Überlastung des Ziels führen. Wenn Sie eine große Anzahl von Aufgaben gleichzeitig starten müssen, sollten Sie die Warteschlangenratensteuerung verwenden, um die Verteilungsrate schrittweise zu erhöhen, oder die Zielkapazität im Voraus bereitstellen.

Erhöhter Fanout

Wenn Sie Dienste aktualisieren, die von Cloud Tasks aufgerufen werden, kann die Erhöhung der Anzahl von Remote-Aufrufen zu Produktionsrisiken führen. Angenommen, die Aufgaben in einer Warteschlange mit hoher TPS rufen den Handler /task-foo auf. Ein neuer Release kann die Kosten für den Aufruf von /task-foo erheblich erhöhen, wenn beispielsweise mehrere teure Datastore-Aufrufe zum Handler hinzugefügt werden. Das Ergebnis einer solchen Veröffentlichung ist ein massiver Anstieg des Datastore-Traffics, der direkt mit Änderungen des Nutzertraffics zusammenhängt. Verwenden Sie eine schrittweise Einführung oder Trafficaufteilung, um die Hochlaufphase zu verwalten.

Wiederholungsversuche

Ihr Code kann bei einem Fehler beim Aufrufen der Cloud Tasks API einen neuen Versuch starten. Wenn jedoch ein erheblicher Teil der Anfragen mit serverseitigen Fehlern fehlschlägt, kann eine hohe Wiederholungsrate Ihre Warteschlangen weiter überlasten und die Wiederherstellung verlangsamen. Begrenzen Sie die Menge des ausgehenden Traffics, wenn Ihr Client feststellt, dass ein erheblicher Teil der Anfragen mit serverseitigen Fehlern fehlschlägt. Sie können beispielsweise den Algorithmus für die adaptive Drosselung verwenden, der im Kapitel Umgang mit Überlastung des Buchs Site Reliability Engineering beschrieben wird. Die gRPC-Clientbibliotheken von Google implementieren eine Variante dieses Algorithmus.