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.
Optimierung der auto Skalierung des Amazon ECS-Service
Ein Amazon ECS-Service ist eine verwaltete Sammlung von Aufgaben. Jedem Service ist eine Aufgabendefinition, eine gewünschte Anzahl von Aufgaben und eine optionale Platzierungsstrategie zugeordnet.
Amazon ECS Service Auto Scaling funktioniert über den Application Auto Scaling-Service. Application Auto Scaling verwendet CloudWatch Metriken als Quelle für Skalierungsmetriken. Es verwendet auch CloudWatch Alarme, um Schwellenwerte dafür festzulegen, wann Ihr Service erweitert oder verkleinert werden soll.
Sie geben die Schwellenwerte für die Skalierung an. Sie können ein metrisches Ziel festlegen, das als Skalierung der Zielverfolgung bezeichnet wird. Sie können auch Schwellenwerte angeben, was als schrittweise Skalierung bezeichnet wird.
Nachdem Sie Application Auto Scaling konfiguriert haben, berechnet es kontinuierlich die entsprechende gewünschte Task-Anzahl für den Service. Es benachrichtigt Amazon ECS auch, wenn sich die gewünschte Anzahl an Aufgaben ändern sollte, entweder durch Verkleinern oder Vergrößern.
Um Service Auto Scaling effektiv nutzen zu können, müssen Sie eine geeignete Skalierungsmetrik auswählen. In den folgenden Abschnitten wird erläutert, wie Sie eine Metrik auswählen.
Charakterisierung Ihrer Anwendung
Um eine Anwendung richtig zu skalieren, müssen Sie die Bedingungen kennen, unter denen Sie Ihre Anwendung skalieren und wann Sie sie skalieren sollten.
Im Wesentlichen sollten Sie Ihre Anwendung skalieren, wenn prognostiziert wird, dass die Nachfrage die Kapazität übersteigt. Umgekehrt können Sie Ihre Anwendung skalieren, um Kosten zu sparen, wenn die Ressourcen den Bedarf übersteigen.
Identifizieren einer Nutzungskennzahl
Für eine effektive Skalierung müssen Sie eine Metrik identifizieren, die auf Auslastung oder Sättigung hinweist. 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 Sie die Ressourcen konstant halten, sich aber der Bedarf ändert, muss sich auch der Metrikwert ändern. Die Kennzahl sollte steigen oder sinken, wenn die Nachfrage steigt oder sinkt.
-
Der metrische Wert muss proportional zur Kapazität skaliert werden. Wenn die Nachfrage konstant bleibt, muss das Hinzufügen weiterer Ressourcen zu einer proportionalen Änderung des metrischen Werts führen. Eine Verdoppelung der Anzahl der Aufgaben sollte also zu einer Verringerung der Metrik um 50% führen.
Der beste Weg, eine Nutzungsmetrik zu ermitteln, sind Belastungstests in einer Vorproduktionsumgebung, wie z. B. einer Staging-Umgebung. 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 echten Benutzerverkehr simulieren.
Um mit dem Auslastungstest zu beginnen, sollten Sie zunächst Dashboards für die Nutzungsmetriken Ihrer Anwendung erstellen. Zu diesen Kennzahlen gehören CPU-Auslastung, Speicherauslastung, I/O Betriebsabläufe, I/O Warteschlangentiefe und Netzwerkdurchsatz. Sie können diese Metriken mit einem Service wie CloudWatch Container Insights sammeln. Sie können sie auch sammeln, indem Sie Amazon Managed Service for Prometheus zusammen mit Amazon Managed Grafana verwenden. Stellen Sie während dieses Vorgangs sicher, dass Sie Kennzahlen zu den Antwortzeiten oder den Abschlussquoten Ihrer Anwendung erfassen und grafisch darstellen.
Beginnen Sie beim Auslastungstest mit einer geringen Anzahl von Anfragen oder Stellenangeboten. Halten Sie diese Rate mehrere Minuten lang konstant, damit sich Ihre Bewerbung aufwärmen kann. Erhöhen Sie dann langsam die Geschwindigkeit und halten Sie sie einige Minuten lang konstant. Wiederholen Sie diesen Zyklus und erhöhen Sie die Rate jedes Mal, bis die Antwort- oder Abschlusszeiten Ihrer Anwendung zu langsam sind, um Ihre Service-Level-Ziele zu erreichen (SLOs).
Untersuchen Sie beim Belastungstest die einzelnen Nutzungsmetriken. Die Metriken, die mit der Auslastung steigen, eignen sich am besten als Ihre besten Nutzungskennzahlen.
Identifizieren Sie als Nächstes die Ressource, deren Sättigung erreicht ist. Untersuchen Sie gleichzeitig auch die Nutzungskennzahlen, um festzustellen, welche sich auf hoher Ebene zuerst abflachen. Oder untersuchen Sie, welches System seinen Höhepunkt erreicht und dann zuerst Ihre Anwendung zum Absturz bringt. Wenn die CPU-Auslastung beispielsweise von 0 auf 70 bis 80% steigt, wenn Sie mehr Last hinzufügen, dann kann man mit Sicherheit sagen, dass die CPU ausgelastet ist. Je nach CPU-Architektur erreicht sie möglicherweise nie 100%. Gehen Sie beispielsweise davon aus, dass die Speicherauslastung zunimmt, wenn Sie mehr Last hinzufügen, und Ihre Anwendung dann plötzlich abstürzt, wenn sie das Speicherlimit für Aufgaben oder EC2 Amazon-Instances erreicht. In dieser Situation ist es wahrscheinlich der Fall, dass der Speicher vollständig verbraucht wurde. Möglicherweise werden von Ihrer Anwendung mehrere Ressourcen verbraucht. Wählen Sie daher die Metrik aus, die die Ressource darstellt, die zuerst erschöpft ist.
Versuchen Sie abschließend erneut, die Auslastung zu testen, nachdem Sie die Anzahl der Aufgaben oder EC2 Amazon-Instances verdoppelt haben. Gehen Sie davon aus, dass die Schlüsselkennzahl halb so schnell steigt oder sinkt wie zuvor. Wenn dies der Fall ist, ist die Metrik proportional zur Kapazität. Dies ist eine gute Nutzungsmetrik für Auto Scaling.
Betrachten Sie nun dieses hypothetische Szenario. Nehmen wir an, Sie führen einen Lasttest für eine Anwendung durch und stellen fest, dass die CPU-Auslastung bei 100 Anfragen pro Sekunde irgendwann 80% erreicht. Wenn Sie mehr Last hinzufügen, erhöht sich die CPU-Auslastung nicht mehr. Dadurch reagiert Ihre Anwendung jedoch langsamer. Dann führen Sie den Auslastungstest erneut durch und verdoppeln dabei die Anzahl der Aufgaben, halten aber die Geschwindigkeit auf dem vorherigen Spitzenwert. Wenn Sie feststellen, dass die durchschnittliche CPU-Auslastung auf etwa 40% sinkt, ist die durchschnittliche CPU-Auslastung ein guter Kandidat für eine Skalierungsmetrik. Bleibt die CPU-Auslastung dagegen bei 80%, nachdem die Anzahl der Aufgaben erhöht wurde, ist die durchschnittliche CPU-Auslastung keine gute Skalierungsmetrik. In diesem Fall benötigen Sie weitere Nachforschungen, um eine geeignete Metrik zu finden.
Allgemeine Anwendungsmodelle und Skalierungseigenschaften
Sie können Software aller Art darauf ausführen AWS. Viele Workloads sind selbst entwickelt, während andere auf beliebter Open-Source-Software basieren. Unabhängig davon, woher sie stammen, haben wir einige gängige Entwurfsmuster für Dienste beobachtet. Wie Sie effektiv skalieren, hängt zu einem großen Teil vom Muster ab.
Der effiziente CPU-gebundene Server
Der effiziente CPU-gebundene Server nutzt fast keine anderen Ressourcen als den CPU- und Netzwerkdurchsatz. Jede Anfrage kann von der Anwendung alleine bearbeitet werden. Anfragen hängen nicht von anderen Diensten wie Datenbanken ab. Die Anwendung kann Hunderttausende von gleichzeitigen Anfragen verarbeiten und dafür mehrere CPUs effizient nutzen. Jede Anfrage wird entweder von einem dedizierten Thread mit geringem Speicheraufwand bedient, oder es gibt eine asynchrone Ereignisschleife, die auf jeder CPU läuft, die Anfragen bearbeitet. 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-gebundenen Diensten macht die Speicherauslastung selbst bei Spitzendurchsatz nur einen Bruchteil der verfügbaren Ressourcen aus.
Sie können CPU-basiertes Auto Scaling für diese Art von Anwendung verwenden. Die Anwendung bietet maximale Flexibilität in Bezug auf die Skalierung. Sie können es vertikal skalieren, indem Sie größere EC2 Amazon-Instances oder Fargate V CPUs bereitstellen. Und Sie können es auch horizontal skalieren, indem Sie weitere Replikate hinzufügen. Wenn Sie mehr Replikate hinzufügen oder die Instanzgröße verdoppeln, wird die durchschnittliche CPU-Auslastung im Verhältnis zur Kapazität um die Hälfte reduziert.
Wenn Sie EC2 Amazon-Kapazität für diese Anwendung verwenden, sollten Sie erwägen, sie auf rechenoptimierten Instances wie der c5
c6g
OR-Familie zu platzieren.
Der effiziente speichergebundene Server
Der effiziente speichergebundene Server weist pro Anforderung eine beträchtliche Menge an Speicher zu. Bei maximaler Parallelität, aber nicht unbedingt bei Durchsatz, wird der Arbeitsspeicher erschöpft, bevor die CPU-Ressourcen aufgebraucht sind. Der einer Anforderung zugeordnete Speicher wird freigegeben, wenn die Anforderung endet. Zusätzliche Anfragen können akzeptiert werden, solange Speicherplatz verfügbar ist.
Sie können speicherbasiertes Auto Scaling für diese Art von Anwendung verwenden. Die Anwendung bietet maximale Flexibilität in Bezug auf die Skalierung. Sie können es sowohl vertikal skalieren, indem Sie ihm größere Amazon EC2 - oder Fargate-Speicherressourcen zur Verfügung stellen. Und Sie können es auch horizontal skalieren, indem Sie weitere Replikate hinzufügen. Durch das Hinzufügen weiterer Replikate oder die Verdoppelung der Instance-Größe kann die durchschnittliche Speicherauslastung im Verhältnis zur Kapazität um die Hälfte reduziert werden.
Wenn Sie EC2 Amazon-Kapazität für diese Anwendung verwenden, sollten Sie erwägen, sie auf speicheroptimierten Instances wie der r5
r6g
OR-Familie zu platzieren.
Einige speichergebundene Anwendungen geben den Speicher, der einer Anforderung zugeordnet ist, nicht frei, wenn diese beendet wird, sodass eine Verringerung der Parallelität nicht zu einer Verringerung des verwendeten Speichers führt. Aus diesem Grund empfehlen wir nicht, die speicherbasierte Skalierung zu verwenden.
Der Worker-basierte Server
Der Worker-basierte Server verarbeitet nacheinander eine Anfrage für jeden einzelnen Worker-Thread. Bei den Worker-Threads kann es sich um Lightweight-Threads wie POSIX-Threads handeln. Sie können auch Threads mit höherem Gewicht sein, wie z. B. UNIX-Prozesse. Unabhängig davon, um welchen Thread es sich handelt, gibt es 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, platziert die Anwendung zusätzliche Anfragen in einer Backlog-Warteschlange. Wenn die Backlog-Warteschlange überläuft, lehnt die Anwendung sofort weitere eingehende Anfragen ab. Zu den gängigen Anwendungen, die diesem Muster entsprechen, gehören der Apache Webserver und Gunicorn.
Die Parallelität von Anfragen ist normalerweise die beste Metrik für die Skalierung dieser Anwendung. Da es für jedes Replikat ein Limit für die Parallelität gibt, ist es wichtig, eine Skalierung vorzunehmen, bevor das durchschnittliche Limit erreicht wird.
Der beste Weg, Metriken zur Parallelität von Anfragen zu erhalten, besteht darin, sie von Ihrer Anwendung melden zu lassen. CloudWatch Jedes Replikat Ihrer Anwendung kann die Anzahl der gleichzeitigen Anfragen als benutzerdefinierte Metrik mit hoher Frequenz veröffentlichen. Wir empfehlen, die Frequenz auf mindestens einmal pro Minute einzustellen. Nachdem mehrere Berichte gesammelt wurden, können Sie die durchschnittliche Parallelität als Skalierungsmetrik verwenden. Sie berechnen diese Metrik, indem Sie die gesamte Parallelität durch die Anzahl der Replikate dividieren. Wenn beispielsweise die Gesamtzahl der Parallelität 1000 beträgt und die Anzahl der Replikate 10 beträgt, beträgt die durchschnittliche Parallelität 100.
Wenn Ihre Anwendung hinter einem Application Load Balancer steht, können Sie die ActiveConnectionCount
Metrik für den Load Balancer auch als Faktor in der Skalierungsmetrik verwenden. Sie müssen die ActiveConnectionCount
Metrik durch die Anzahl der Replikate dividieren, um einen Durchschnittswert zu erhalten. Sie müssen den Durchschnittswert für die Skalierung verwenden und nicht den reinen Zählwert.
Damit dieses Design optimal 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, deren Beantwortung deutlich länger als der Durchschnitt dauert. Die durchschnittliche Antwortzeit sollte nahe dem 95. Perzentil der Antwortzeit liegen. Andernfalls kann es zu Warteschlangenüberläufen kommen. Dies führt zu Fehlern. Wir empfehlen, dass Sie bei Bedarf zusätzliche Replikate bereitstellen, um das Risiko eines Überlaufs zu minimieren.
Der wartende Server
Der wartende Server verarbeitet jede Anfrage in gewissem Maße, ist jedoch in hohem Maße von einem oder mehreren nachgelagerten Diensten abhängig, damit er funktioniert. Containeranwendungen nutzen häufig stark 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. Dies liegt daran, dass diese Anwendungen in der Regel nur wenige CPU-Ressourcen verwenden und gleichzeitig den verfügbaren Arbeitsspeicher maximal ausnutzen.
Der Wartedienst eignet sich entweder für das speichergebundene Servermuster oder das Worker-basierte Servermuster, je nachdem, wie die Anwendung konzipiert ist. Wenn die Parallelität der Anwendung nur durch den Arbeitsspeicher begrenzt ist, sollte die durchschnittliche Speicherauslastung als Skalierungsmetrik verwendet werden. Wenn die Parallelität der Anwendung auf einem Worker-Limit 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 den CPU-Ressourcen skaliert, ist er möglicherweise für das effiziente CPU-gebundene Servermuster geeignet. Wenn das der Fall ist, könnte die durchschnittliche CPU-Auslastung als Skalierungsmetrik geeignet sein. Viele Java-Anwendungen sind jedoch nicht CPU-gebunden, was ihre Skalierung schwierig macht.
Für eine optimale Leistung empfehlen wir, dem Java Virtual Machine (JVM) -Heap so viel Speicher wie möglich zuzuweisen. Neuere Versionen der JVM, einschließlich Java 8 Update 191 oder höher, legen die Heap-Größe automatisch so groß wie möglich fest, damit sie in den Container passt. Das bedeutet, dass in Java die Speicherauslastung selten proportional zur Anwendungsauslastung ist. Mit steigender Anforderungsrate und Parallelität bleibt die Speicherauslastung konstant. Aus diesem Grund empfehlen wir nicht, Java-basierte Server auf der Grundlage der Speicherauslastung zu skalieren. Stattdessen empfehlen wir in der Regel, je nach CPU-Auslastung zu skalieren.
In einigen Fällen kommt es bei Java-basierten Servern vor der CPU-Auslastung zu einer Heap-Erschöpfung. Wenn Ihre Anwendung bei hoher Parallelität zur Heap-Erschöpfung neigt, sind durchschnittliche Verbindungen die beste Skalierungsmetrik. Wenn Ihre Anwendung bei hohem Durchsatz zur Heap-Erschöpfung neigt, ist die durchschnittliche Anforderungsrate die beste Skalierungsmetrik.
Server, die andere Laufzeiten verwenden, bei denen Müll gesammelt wurde
Viele Serveranwendungen wie .NET und Ruby basieren auf Laufzeiten, die Garbage-Collection durchführen. Diese Serveranwendungen passen möglicherweise in eines der zuvor beschriebenen Muster. Wie bei Java empfehlen wir jedoch nicht, diese Anwendungen auf der Grundlage des Speichers zu skalieren, da ihre beobachtete durchschnittliche Speicherauslastung oft nicht mit dem Durchsatz oder der Parallelität korreliert.
Für diese Anwendungen empfehlen wir, die CPU-Auslastung entsprechend zu skalieren, wenn die Anwendung CPU-gebunden ist. Andernfalls empfehlen wir, die Skalierung auf der Grundlage Ihrer Lasttestergebnisse auf der Grundlage des durchschnittlichen Durchsatzes oder der durchschnittlichen Parallelität durchzuführen.
Jobprozessoren
Viele Workloads beinhalten asynchrone Auftragsverarbeitung. Dazu gehören Anwendungen, die Anfragen nicht in Echtzeit empfangen, sondern stattdessen eine Arbeitswarteschlange abonnieren, um Jobs zu erhalten. Für diese Art von Anwendungen ist die richtige Skalierungsmetrik fast immer die Warteschlangentiefe. Ein Anstieg der Warteschlange ist ein Hinweis darauf, dass die ausstehende Arbeit die Verarbeitungskapazität übersteigt, wohingegen eine leere Warteschlange darauf hindeutet, dass mehr Kapazität als zu erledigende Arbeit vorhanden ist.
AWS Messaging-Dienste wie Amazon SQS und Amazon Kinesis Data Streams bieten CloudWatch Metriken, die für die Skalierung verwendet werden können. Für Amazon SQS ApproximateNumberOfMessagesVisible
ist dies die beste Metrik. Für Kinesis Data Streams sollten Sie die MillisBehindLatest
Metrik verwenden, die von der Kinesis Client Library (KCL) veröffentlicht wurde. Diese Metrik sollte für alle Verbraucher gemittelt werden, bevor sie für die Skalierung verwendet wird.