Auto Scaling für - Amazon Elastic Container Service

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Auto Scaling für

Ein Amazon ECS-Service ist eine verwaltete Sammlung von Aufgaben. Jeder Dienst verfügt über eine zugeordnete Aufgabendefinition, eine gewünschte Aufgabenanzahl und eine optionale Platzierungsstrategie. Die automatische Skalierung des Amazon ECS-Dienstes wird über den Application Auto Scaling Dienst implementiert. Application Auto Scaling verwendet CloudWatch Metriken als Quelle für die Skalierung von Metriken. Außerdem werden CloudWatch Alarme verwendet, um Schwellenwerte festzulegen, wann der Dienst ein- oder ausskaliert werden soll. Sie geben die Schwellenwerte für die Skalierung an, indem Sie entweder ein Metrikziel festlegen, dasZiel-Nachverfolgungoder durch Angabe von Schwellenwerten, die alsSkalierung. Nachdem die Application Auto Scaling konfiguriert wurde, berechnet sie kontinuierlich die gewünschte Anzahl der Aufgaben für den Dienst. Außerdem wird Amazon ECS benachrichtigt, wenn sich die gewünschte Aufgabenanzahl ändern soll, indem sie entweder skaliert oder skaliert wird.

Um die automatische Skalierung des Dienstes effektiv zu nutzen, müssen Sie eine geeignete Skalierungsmetrik auswählen. In den folgenden Abschnitten wird beschrieben, wie eine Metrik ausgewählt wird.

Charakterisierung Ihrer Anwendung

Die richtige Skalierung einer Anwendung erfordert die Kenntnis der Bedingungen, in denen die Anwendung skaliert werden soll und wann sie skaliert werden soll. Im Wesentlichen sollte eine Anwendung skaliert werden, wenn prognostiziert wird, dass der Bedarf die Kapazität übersteigt. Umgekehrt kann eine Anwendung skaliert werden, um Kosten zu sparen, wenn Ressourcen den Bedarf übersteigen.

Identifizieren einer Auslastungsmetrik

Um effektiv zu skalieren, ist es wichtig, eine Metrik zu identifizieren, die Auslastung oder Sättigung anzeigt. Diese Metrik muss die folgenden Eigenschaften aufweisen, um für die Skalierung nützlich zu sein.

  • Die Metrik muss mit der Nachfrage korreliert sein. Wenn Ressourcen stabil gehalten werden, sich aber der Bedarf ändert, muss sich auch der Metrikwert ändern. Die Metrik sollte steigen oder abnehmen, wenn der Bedarf steigt oder sinkt.

  • Der Metrikwert muss proportional zur Kapazität skaliert werden. Wenn der Bedarf konstant bleibt, muss das Hinzufügen weiterer Ressourcen zu einer proportionalen Änderung des Metrikwerts führen. Die Verdoppelung der Anzahl der Aufgaben sollte daher dazu führen, dass die Metrik um 50% sinkt.

Die beste Methode zur Identifizierung einer Auslastungsmetrik besteht in Lasttests in einer Vorproduktionsumgebung, z. B. in einer Stagingumgebung. Kommerzielle und Open-Source-Lösungen für Lasttests sind weit verbreitet. Diese Lösungen können in der Regel entweder synthetische Last erzeugen oder realen Benutzerverkehr simulieren.

Um den Prozess des Lasttests zu starten, sollten Sie zunächst Dashboards für die Auslastungsmetriken Ihrer Anwendung erstellen. Diese Metriken umfassen CPU-Auslastung, Speicherauslastung, E/A-Vorgänge, E/A-Warteschlangentiefe und Netzwerkdurchsatz. Sie können diese Metriken mit einem Dienst wie CloudWatch Container Insights erfassen. Oder verwenden Sie Amazon Managed Service für Prometheus zusammen mit Amazon Managed Service for Grafana. Stellen Sie während dieses Prozesses sicher, dass Sie Metriken für die Antwortzeiten oder die Arbeitsabschlussraten Ihrer Anwendung erfassen und plotten.

Beginnen Sie beim Lasttest mit einer kleinen Anforderungs- oder Auftragseinfügungsrate. Halten Sie diese Rate für einige Minuten stabil, damit sich Ihre Anwendung aufwärmen kann. Dann erhöhen Sie langsam die Rate und halten Sie sie für ein paar Minuten stabil. Wiederholen Sie diesen Zyklus und erhöhen Sie die Rate jedes Mal, bis die Reaktions- oder Abschlusszeiten Ihrer Anwendung zu langsam sind, um Ihre Service-Level-Ziele (SLOs) zu erreichen.

Untersuchen Sie während des Lasttests die einzelnen Auslastungsmetriken. Die Metriken, die zusammen mit der Belastung steigen, sind die besten Kandidaten, die als beste Auslastungsmetriken dienen.

Identifizieren Sie als Nächstes die Ressource, die die Sättigung erreicht. Untersuchen Sie gleichzeitig auch die Auslastungsmetriken, um zu sehen, welche auf einer hohen Ebene zuerst abgeflacht wird. Oder überprüfen Sie, welche Spitze erreicht, und stürzt dann zuerst Ihre Anwendung ab. Wenn beispielsweise die CPU-Auslastung von 0% auf 70 -80% erhöht wird, wenn Sie Last hinzufügen, und bleibt dann an diesem Lebel, nachdem noch mehr Last hinzugefügt wurde, dann ist es sicher zu sagen, dass die CPU gesättigt ist. Abhängig von der CPU-Architektur kann es niemals 100% erreichen. Angenommen, die Speicherauslastung steigt, wenn Sie Last hinzufügen, und dann stürzt Ihre Anwendung plötzlich ab, wenn sie die Speichergrenze der Aufgabe oder Amazon EC2 Instance erreicht. In dieser Situation ist es wahrscheinlich der Fall, dass Speicher vollständig verbraucht wurde. Möglicherweise werden mehrere Ressourcen von Ihrer Anwendung verbraucht. Wählen Sie daher die Metrik aus, die die Ressource darstellt, die zuerst ausfällt.

Versuchen Sie zuletzt erneut Load Testing, nachdem Sie die Anzahl der Tasks oder Amazon EC2 Instances verdoppelt haben. Angenommen, die Schlüsselmetrik erhöht oder verringert, um die Hälfte der Rate wie zuvor. Wenn dies der Fall ist, ist die Metrik proportional zur Kapazität. Dies ist eine gute Auslastungsmetrik für die automatische Skalierung.

Betrachten Sie nun dieses hypothetische Szenario. Angenommen, Sie laden testen eine Anwendung und stellen fest, dass die CPU-Auslastung schließlich 80% bei 100 Anforderungen pro Sekunde erreicht. Wenn mehr Last hinzugefügt wird, erhöht sich die CPU-Auslastung nicht mehr. Ihre Anwendung reagiert jedoch langsamer. Anschließend führen Sie den Lasttest erneut aus, indem Sie die Anzahl der Aufgaben verdoppeln, aber die Rate auf den vorherigen Spitzenwert halten. Wenn Sie feststellen, dass die durchschnittliche CPU-Auslastung auf etwa 40% sinkt, ist die durchschnittliche CPU-Auslastung ein guter Kandidat für eine Skalierungsmetrik. Wenn die CPU-Auslastung hingegen nach der Erhöhung der Anzahl der Aufgaben bei 80% bleibt, ist die durchschnittliche CPU-Auslastung keine gute Skalierungsmetrik. In diesem Fall ist mehr Forschung erforderlich, um eine geeignete Metrik zu finden.

Allgemeine Anwendungsmodelle und Skalierungseigenschaften

Software aller Art wird aufAWS. Viele Arbeitslasten werden selbst entwickelt, während andere auf populärer Open-Source-Software basieren. Unabhängig davon, wo sie stammen, haben wir einige gemeinsame Entwurfsmuster für Dienstleistungen beobachtet. Wie effektiv skaliert werden kann, hängt zum großen Teil vom Muster ab.

Der effiziente CPU-gebundene Server

Der effiziente CPU-gebundene Server nutzt fast keine anderen Ressourcen als CPU- und Netzwerkdurchsatz. Jede Anfrage kann allein von der Anwendung bearbeitet werden. Anforderungen hängen nicht von anderen Diensten wie Datenbanken ab. Die Anwendung kann Hunderttausende gleichzeitiger Anforderungen verarbeiten und mehrere CPUs effizient nutzen. Jede Anforderung wird entweder von einem dedizierten Thread mit geringem Speicheraufwand bedient, oder es gibt eine asynchrone Ereignisschleife, die auf jeder CPU ausgeführt wird, die Anforderungen bedient. Jedes Replikat der Anwendung ist gleichermaßen in der Lage, eine Anfrage zu verarbeiten. Die einzige Ressource, die vor der CPU aufgebraucht sein könnte, ist die Netzwerkbandbreite. Bei CPU-Bound-Diensten ist die Speicherauslastung selbst bei Spitzendurchsatz ein Bruchteil der verfügbaren Ressourcen.

Diese Art von Anwendung eignet sich für CPU-basierte automatische Skalierung. Die Anwendung genießt maximale Flexibilität bei der Skalierung. Es kann vertikal skaliert werden, indem größere Amazon EC2 Instances oder Fargate vCPUs bereitgestellt werden. Und es kann auch horizontal skaliert werden, indem mehr Replikate hinzugefügt werden. Durch das Hinzufügen weiterer Replikate oder das Verdoppeln der Instanzgröße wird die durchschnittliche CPU-Auslastung im Verhältnis zur Kapazität um die Hälfte reduziert.

Wenn Sie Amazon EC2 Kapazität für diese Anwendung verwenden, sollten Sie sie in Betracht ziehen, sie auf rechenoptimierten Instances wie demc5oder .c6g-Familie.

Der effiziente speichergebundene Server

Der effiziente speichergebundene Server weist pro Anforderung eine beträchtliche Menge an Arbeitsspeicher zu. Bei maximaler Parallelität, aber nicht notwendigerweise Durchsatz, wird der Speicher aufgebraucht, bevor die CPU-Ressourcen aufgebraucht sind. Der Speicher, der einer Anforderung zugeordnet ist, wird freigegeben, wenn die Anforderung beendet wird. Zusätzliche Anfragen können akzeptiert werden, solange Speicher verfügbar ist.

Diese Art von Anwendung eignet sich für speicherbasierte automatische Skalierung. Die Anwendung genießt maximale Flexibilität bei der Skalierung. Es kann sowohl vertikal skaliert werden, indem größere Amazon EC2 oder Fargate Speicherressourcen bereitgestellt werden. Und es kann auch horizontal skaliert werden, indem mehr Replikate hinzugefügt werden. Durch das Hinzufügen weiterer Replikate oder das Verdoppeln der Instanzgröße kann die durchschnittliche Speicherauslastung relativ zur Kapazität um die Hälfte reduziert werden.

Wenn Sie Amazon EC2 Kapazität für diese Anwendung verwenden, sollten Sie diese auf speicheroptimierten Instances wie demr5oder .r6g-Familie.

Einige speichergebundene Anwendungen geben den Speicher nicht frei, der einer Anforderung zugeordnet ist, wenn sie endet, so dass eine Verringerung der Parallelität nicht zu einer Verringerung des verwendeten Speichers führt. Dafür raten wir davon ab, eine speicherbasierte Skalierung zu verwenden.

Der arbeiterbasierte Server

Der worker-basierte Server verarbeitet eine Anforderung für jeden einzelnen Worker-Thread nacheinander. Die Arbeits-Threads können leichte Threads sein, wie POSIX-Threads. Sie können auch Threads mit schwereren Gewichten wie UNIX-Prozesse sein. Egal, welcher Thread sie sind, es gibt immer eine maximale Parallelität, die die Anwendung unterstützen kann. Normalerweise wird das Parallelitätslimit proportional zu den verfügbaren Speicherressourcen festgelegt. Wenn das Parallelitätslimit erreicht ist, werden zusätzliche Anforderungen in eine Backlog-Queue gestellt. Wenn die Rückstandswarteschlange überläuft, werden zusätzliche eingehende Anforderungen sofort abgelehnt. Zu den üblichen Anwendungen, die zu diesem Muster passen, gehören Apache Webserver und Gunicorn.

Anforderungs-Parallelität ist normalerweise die beste Metrik für die Skalierung dieser Anwendung. Da für jedes Replikat ein Parallelitätslimit vorhanden ist, ist es wichtig, eine Skalierung durchzuführen, bevor das durchschnittliche Limit erreicht wird.

Der beste Weg, um Anforderungs-Parallelitätsmetriken zu erhalten, besteht darin, dass Ihre Anwendung sie an CloudWatch meldet. Jedes Replikat Ihrer Anwendung kann die Anzahl gleichzeitiger Anforderungen als benutzerdefinierte Metrik mit hoher Häufigkeit veröffentlichen. Wir empfehlen, dass die Frequenz mindestens einmal pro Minute eingestellt ist. Nachdem mehrere Berichte gesammelt wurden, können Sie die durchschnittliche Parallelität als Skalierungsmetrik verwenden. Diese Metrik wird berechnet, indem die Gesamtparallelität genommen und durch die Anzahl der Replikate dividiert wird. Wenn beispielsweise die Gesamtparallelität 1000 beträgt und die Anzahl der Replikate 10 beträgt, beträgt die durchschnittliche Parallelität 100.

Wenn sich Ihre Anwendung hinter einem Application Load Balancer befindet, können Sie auch dieActiveConnectionCount-Metrik für den Load Balancer als Faktor in der Skalierungsmetrik. DieActiveConnectionCount-Metrik muss durch die Anzahl der Replikate geteilt werden, um einen Durchschnittswert zu erhalten. Der Durchschnittswert muss für die Skalierung verwendet werden, im Gegensatz zum unformatierten Zählwert.

Damit dieser Entwurf am besten funktioniert, sollte die Standardabweichung der Antwortlatenz bei niedrigen Anforderungsraten gering sein. Wir empfehlen, dass in Zeiten geringer Nachfrage die meisten Anfragen innerhalb kurzer Zeit beantwortet werden, und es gibt nicht viele Anfragen, die wesentlich länger als die durchschnittliche Zeit dauern, um zu antworten. Die durchschnittliche Reaktionszeit sollte nahe der 95. Perzentil-Reaktionszeit liegen. Andernfalls können Warteschlangenüberläufe als Ergebnis auftreten. Dies führt zu Fehlern. Es wird empfohlen, dass Sie bei Bedarf zusätzliche Replikate bereitstellen, um das Überlaufrisiko zu verringern.

Der wartende Server

Der wartende Server führt eine gewisse Verarbeitung für jede Anforderung durch, ist jedoch stark davon abhängig, dass ein oder mehrere Downstream-Dienste funktionieren. Containeranwendungen nutzen oft nachgelagerte Dienste wie Datenbanken und andere API-Dienste. Es kann einige Zeit dauern, bis diese Dienste reagieren, insbesondere in Szenarien mit hoher Kapazität oder hoher Parallelität. TDies liegt daran, dass diese Anwendungen tendenziell wenige CPU-Ressourcen und ihre maximale Parallelität in Bezug auf den verfügbaren Speicher verwenden.

Der wartende Dienst eignet sich entweder im speichergebundenen Server-Pattern oder im worker-basierten Server-Pattern, je nachdem, wie die Anwendung entworfen wurde. Wenn die Parallelität der Anwendung nur durch den Speicher begrenzt ist, sollte die durchschnittliche Speicherauslastung als Skalierungsmetrik verwendet werden. Wenn die Parallelität der Anwendung auf einem Workerlimit basiert, sollte die durchschnittliche Parallelität als Skalierungsmetrik verwendet werden.

Der Java-basierte Server

Wenn Ihr Java-basierter Server CPU-gebunden ist und proportional zu CPU-Ressourcen skaliert, ist er möglicherweise für das effiziente CPU-gebundene Servermuster geeignet. Wenn dies der Fall ist, kann die durchschnittliche CPU-Auslastung als Skalierungsmetrik geeignet sein. Viele Java-Anwendungen sind jedoch nicht an CPU-gebunden, was die Skalierung schwierig macht.

Um die optimale Leistung zu erzielen, empfehlen wir, dass Sie dem Java Virtual Machine (JVM) -Heap so viel Arbeitsspeicher wie möglich zuweisen. Aktuelle Versionen der JVM, einschließlich Java 8 Update 191 oder höher, legen automatisch die Heap-Größe so groß wie möglich fest, dass sie in den Container passt. Dies bedeutet, dass in Java die Speicherauslastung selten proportional zur Anwendungsauslastung ist. Wenn die Anforderungsrate und Parallelität zunimmt, bleibt die Speicherauslastung konstant. Aus diesem Grund empfehlen wir nicht, Java-basierte Server basierend auf der Speicherauslastung zu skalieren. Stattdessen wird in der Regel empfohlen, die CPU-Auslastung zu skalieren.

In einigen Fällen stoßen Java-basierte Server auf Heap-Erschöpfung, bevor die CPU erschöpft wird. Wenn Ihre Anwendung anfällig für Heap-Erschöpfung bei hoher Parallelität ist, sind durchschnittliche Verbindungen die beste Skalierungsmetrik. Wenn Ihre Anwendung anfällig für Heap-Erschöpfung bei hohem Durchsatz ist, ist die durchschnittliche Anforderungsrate die beste Skalierungsmetrik.

Server, die andere Garbage-gesammelte Laufzeiten verwenden

Viele Serveranwendungen basieren auf Laufzeiten, die Garbage Collection wie .NET und Ruby ausführen. Diese Serveranwendungen passen möglicherweise in eines der zuvor beschriebenen Muster. Wie bei Java empfehlen wir jedoch nicht, diese Anwendungen basierend auf dem Speicher zu skalieren, da ihre beobachtete durchschnittliche Speicherauslastung oft nicht mit Durchsatz oder Nebenläufigkeit korreliert.

Für diese Anwendungen wird empfohlen, die CPU-Auslastung zu skalieren, wenn die Anwendung CPU-gebunden ist. Andernfalls wird empfohlen, dass Sie basierend auf den Ergebnissen Ihrer Lasttests den durchschnittlichen Durchsatz oder die durchschnittliche Parallelität skalieren.

Job verarbeiter

Viele Arbeitslasten beinhalten asynchrone Auftragsverarbeitung. Dazu gehören Anwendungen, die keine Anforderungen in Echtzeit empfangen, sondern stattdessen eine Arbeitswarteschlange abonnieren, um Aufträge zu empfangen. Für diese Arten von Anwendungen ist die richtige Skalierungsmetrik fast immer Warteschlangentiefe. Das Wachstum der Warteschlange ist ein Hinweis darauf, dass ausstehende Arbeit die Verarbeitungskapazität übersteigt, während eine leere Warteschlange anzeigt, dass mehr Kapazität vorhanden ist als Arbeit zu erledigen.

AWSMessaging-Dienste wie Amazon SQS und Amazon Kinesis Data Streams bieten CloudWatch Metriken, die für die Skalierung verwendet werden können. Für Amazon SQSApproximateNumberOfMessagesVisibleist die beste Metrik. Bei Kinesis Data Streams sollten Sie dieMillisBehindLatest-Metrik, veröffentlicht von der Kinesis Client Library (KCL). Diese Metrik sollte für alle Verbraucher gemittelt werden, bevor sie für die Skalierung verwendet wird.