Wir stoßen auf ein merkwürdiges Verhalten, bei dem wir eine hohe CPU-Auslastung, aber einen recht niedrigen Lastdurchschnitt feststellen.
Das Verhalten wird am besten durch die folgenden Grafiken unseres Überwachungssystems veranschaulicht.
Gegen 11:57 Uhr steigt die CPU-Auslastung von 25% auf 75%. Der Lastdurchschnitt wird nicht wesentlich verändert.
Wir betreiben Server mit 12 Cores mit jeweils 2 Hyper-Threads. Das Betriebssystem sieht dies als 24 CPUs.
Die CPU-Auslastungsdaten werden durch Ausführen /usr/bin/mpstat 60 1
jeder Minute erfasst . Die Daten für die all
Zeile und die %usr
Spalte werden in der obigen Tabelle angezeigt. Ich bin sicher, dass dies den Durchschnitt pro CPU-Daten zeigt, nicht die "gestapelte" Auslastung. Während wir in der Grafik eine Auslastung von 75% sehen, sehen wir einen Prozess, der zeigt, dass ungefähr 2000% "gestapelte" CPU verwendet werden top
.
Der Lastmittelwert wird aus /proc/loadavg
jeder Minute ermittelt.
uname -a
gibt:
Linux ab04 2.6.32-279.el6.x86_64 #1 SMP Wed Jun 13 18:24:36 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux
Linux dist is Red Hat Enterprise Linux Server release 6.3 (Santiago)
Wir betreiben einige Java-Webanwendungen unter ziemlich hoher Last auf den Maschinen, rechnen mit 100 Anfragen / s pro Maschine.
Wenn ich die CPU-Auslastungsdaten richtig interpretiere, bedeutet dies bei einer CPU-Auslastung von 75%, dass unsere CPUs durchschnittlich 75% der Zeit einen Prozess ausführen. Wenn unsere CPUs jedoch 75% der Zeit ausgelastet sind, sollten wir dann keinen höheren Auslastungsdurchschnitt sehen? Wie können die CPUs zu 75% ausgelastet sein, wenn sich nur 2-4 Jobs in der Ausführungswarteschlange befinden?
Interpretieren wir unsere Daten richtig? Was kann dieses Verhalten verursachen?
quelle
Antworten:
Zumindest unter Linux sind der Lastdurchschnitt und die CPU-Auslastung zwei verschiedene Faktoren. Der Lastdurchschnitt gibt an, wie viele Tasks über einen bestimmten Zeitraum in einer Kernel-Ausführungswarteschlange warten (nicht nur CPU-Zeit, sondern auch Festplattenaktivität). Die CPU-Auslastung ist ein Maß für die aktuelle Auslastung der CPU. Die höchste Auslastung, die ein einzelner CPU-Thread, der für eine Minute an 100% gebunden war, zum 1-Minuten-Durchschnitt "beitragen" kann, ist 1. Eine 4-Kern-CPU mit Hyperthreading (8 virtuelle Kerne), die für 1 Minute an 100% gebunden war, würde 8 dazu beitragen der 1-Minuten-Lastdurchschnitt.
Oft haben diese beiden Zahlen Muster, die miteinander korrelieren, aber man kann sie nicht als gleich ansehen. Sie können eine hohe Auslastung mit einer CPU-Auslastung von nahezu 0% haben (z. B. wenn viele E / A-Daten im Wartezustand hängen bleiben) und Sie können eine CPU-Auslastung von 1 und 100% haben, wenn ein einzelner Thread-Prozess ausgeführt wird volle Neigung. Auch für kurze Zeit können Sie die CPU bei fast 100% sehen, aber die Last ist immer noch unter 1, weil die durchschnittlichen Metriken noch nicht "aufgeholt" haben.
Ich habe gesehen, dass ein Server eine Auslastung von über 15.000 hat (ja, das ist wirklich kein Tippfehler) und eine CPU von fast 0%. Es geschah, weil eine Samba-Freigabe Probleme hatte und viele, viele Clients in einem E / A-Wartezustand stecken blieben. Wenn Sie regelmäßig eine hohe Auslastung ohne entsprechende CPU-Aktivität feststellen, liegt möglicherweise ein Speicherproblem vor. Auf virtuellen Maschinen kann dies auch bedeuten, dass andere VMs auf demselben VM-Host um Speicherressourcen kämpfen.
Hohe Auslastung ist auch nicht unbedingt eine schlechte Sache. In den meisten Fällen bedeutet dies lediglich, dass das System voll ausgelastet ist oder möglicherweise nicht mehr mithalten kann (wenn die Auslastungszahl höher ist als die Anzahl der Prozessorkerne). An einem Ort, an dem ich ein Systemadministrator war, hatte er jemanden, der die durchschnittliche Auslastung seines Primärsystems genauer beobachtete als Nagios. Wenn die Last hoch war, riefen sie mich 24/7 schneller an, als Sie SMTP sagen könnten. Die meiste Zeit war nichts wirklich falsch, aber sie verbanden die Ladungsnummer mit etwas Falschem und beobachteten es wie ein Falke. Nach der Überprüfung antwortete ich normalerweise, dass das System gerade seinen Job erledigt. Natürlich war dies derselbe Ort, an dem die Last über 15000 anstieg (nicht derselbe Server), und manchmal bedeutet dies, dass etwas nicht stimmt. Sie müssen den Zweck Ihres Systems berücksichtigen. Wenn es sich um ein Arbeitstier handelt, ist mit einer natürlich hohen Belastung zu rechnen.
quelle
Last ist eine sehr irreführende Zahl. Nimm es mit einem Körnchen Salz.
Wenn Sie viele Aufgaben in sehr schneller Folge erstellen, die sehr schnell abgeschlossen werden, ist die Anzahl der Prozesse in der Ausführungswarteschlange zu gering, um die Last für sie zu registrieren (der Kernel zählt die Last alle fünf Sekunden).
Betrachten Sie dieses Beispiel: Auf meinem Host mit 8 logischen Kernen registriert dieses Python-Skript eine hohe CPU-Auslastung (ca. 85%), jedoch kaum Auslastung.
Eine andere Implementierung vermeidet diese
wait
in Gruppen von 8 (was den Test verzerren würde). Hier versucht das übergeordnete Element immer, die Anzahl der untergeordneten Elemente auf der Anzahl der aktiven CPUs zu halten, sodass es viel beschäftigter als die erste Methode und hoffentlich genauer ist.Der Grund für dieses Verhalten ist, dass der Algorithmus mehr Zeit für das Erstellen von untergeordneten Prozessen benötigt als für das Ausführen der eigentlichen Aufgabe (bis 10000). Noch nicht erstellte Tasks können nicht in den Status 'ausführbar' gezählt werden, beanspruchen jedoch% sys an CPU-Zeit, da sie erzeugt werden.
Die Antwort könnte also in Ihrem Fall sein, dass bei jeder Arbeit eine große Anzahl von Aufgaben in schneller Folge (Threads oder Prozesse) anfällt.
quelle
Wenn sich der Lastdurchschnitt nicht wesentlich erhöht, bedeutet dies lediglich, dass Ihre Hardwarespezifikationen und die Art der zu verarbeitenden Aufgaben einen guten Gesamtdurchsatz ergeben, sodass sie für einige Zeit nicht in der Aufgabenwarteschlange angehäuft werden.
Wenn es ein Konfliktphänomen gibt, weil beispielsweise die durchschnittliche Taskkomplexität zu hoch ist oder die durchschnittliche Taskverarbeitungszeit zu viele CPU-Zyklen in Anspruch nimmt, würde der Lastdurchschnitt steigen.
UPDATE:
In meiner ursprünglichen Antwort ist es möglicherweise nicht klar, daher erkläre ich jetzt:
Die genaue Formel der Lastdurchschnittsberechnung ist:
loadvg = tasks running + tasks waiting (for cores) + tasks blocked
.Sie können auf jeden Fall einen guten Durchsatz erzielen und sich einem Lastdurchschnitt von 24 annähern, ohne die Bearbeitungszeit der Aufgaben zu beeinträchtigen. Auf der anderen Seite können auch 2-4 periodische Aufgaben nicht schnell genug erledigt werden, dann wird die Anzahl der wartenden Aufgaben (für CPU-Zyklen) zunehmen und Sie werden schließlich einen hohen Lastdurchschnitt erreichen. Eine andere Möglichkeit besteht darin, dass Aufgaben ausstehende synchrone E / A-Vorgänge ausführen und dann einen Kern blockieren, den Durchsatz verringern und die Warteschlange für wartende Aufgaben vergrößern (in diesem Fall kann sich die
iowait
Metrik ändern).quelle
Der Lastdurchschnitt umfasst Aufgaben, die auf Datenträger-E / A blockiert sind, sodass Sie problemlos eine CPU-Auslastung von Null und einen Lastdurchschnitt von 10 erreichen können, indem Sie 10 Aufgaben ausführen, die alle versuchen, von einem sehr langsamen Datenträger zu lesen. Daher ist es üblich, dass ein ausgelasteter Server die Festplatte auslastet und alle Suchvorgänge viele blockierte Aufgaben verursachen, wodurch die durchschnittliche Auslastung steigt, während die CPU-Auslastung sinkt, da alle Aufgaben auf der Festplatte blockiert sind.
quelle
Die Antwort von Matthew Ife war zwar sehr hilfreich und führte uns in die richtige Richtung, aber es war nicht genau das, was das Verhalten in unserem Fall verursachte. In unserem Fall haben wir eine Java-Anwendung mit mehreren Threads, die Thread-Pooling verwendet, weshalb beim Erstellen der eigentlichen Aufgaben keine Arbeit geleistet wird.
Die eigentliche Arbeit der Threads ist jedoch kurzlebig und umfasst E / A-Wartezeiten oder Synchronisierungswartezeiten. Wie Matthew in seiner Antwort erwähnt, wird der Lastdurchschnitt vom Betriebssystem abgetastet, sodass kurzlebige Aufgaben übersehen werden können.
Ich habe ein Java-Programm erstellt, das das Verhalten reproduziert. Die folgende Java-Klasse generiert auf einem unserer Server eine CPU-Auslastung von 28% (650% gestapelt). Dabei liegt der Lastdurchschnitt bei ca. 1,3. Der Schlüssel hier ist der sleep () innerhalb des Threads, ohne ihn ist die Lastberechnung korrekt.
Zusammenfassend lässt sich sagen, dass die Threads in unseren Anwendungen häufig inaktiv sind und dann eine kurzlebige Arbeit verrichten, weshalb die Aufgaben bei der Berechnung des Lastdurchschnitts nicht korrekt erfasst werden.
quelle
Lastdurchschnitt ist die durchschnittliche Anzahl von Prozessen in der CPU-Warteschlange. Es ist systemspezifisch. Sie können nicht sagen, dass ein LA auf allen Systemen generisch hoch und ein anderer niedrig ist. Sie haben also 12 Kerne, und um LA signifikant zu steigern, muss die Anzahl der Prozesse wirklich hoch sein.
Eine andere Frage ist, was mit dem Diagramm "CPU-Auslastung" gemeint ist. Wenn es aus SNMP stammt, wie es sein sollte und Ihre SNMP-Implementierung es ist
net-snmp
, dann stapelt es die CPU-Last von jeder Ihrer 12 CPUs. Also fürnet-snmp
die Gesamtmenge der CPU - Auslastung beträgt 1200%.Wenn meine Annahmen stimmen, hat sich die CPU-Auslastung nicht wesentlich erhöht. Somit hat LA nicht signifikant zugenommen.
quelle
all
Zeile, übernommen. Ich bin ziemlich sicher, dass es ein Durchschnitt über alle CPUs ist, es ist nicht gestapelt. Wenn das Problem auftritt, zeigt oben beispielsweise die CPU-Auslastung von 2000% für einen Prozess. Das ist Stapelverwendung.Das Szenario hier ist nicht besonders unerwartet, obwohl es ein wenig ungewöhnlich ist. Was Xavier anspricht, aber nicht viel entwickelt, ist, dass Linux (standardmäßig) und die meisten Unix-Varianten auf einem fehlerfreien Computer präventives Multitasking implementieren, Aufgaben jedoch selten vorbelegt werden. Jeder Task ist eine Zeitscheibe für die Belegung der CPU zugeordnet. Sie wird nur dann vorbelegt, wenn diese Zeit überschritten wird und andere Tasks ausgeführt werden müssen (beachten Sie, dass beim Laden die durchschnittliche Anzahl der Prozesse in der CPU sowie die Anzahl der ausgeführten Prozesse angegeben wird). . In den meisten Fällen wird ein Prozess nicht unterbrochen, sondern erbracht.
(Im Allgemeinen müssen Sie sich nur Gedanken über die Auslastung machen, wenn die Anzahl der CPUs knapp wird - dh wenn der Scheduler mit dem Vorauslesen von Aufgaben beginnt.)
Es dreht sich alles um das Aktivitätsmuster, die deutlich erhöhte Auslastung der CPU durch einige Tasks (höchstwahrscheinlich eine kleine Minderheit) wirkte sich nicht negativ auf die Verarbeitung anderer Tasks aus. Wenn Sie die verarbeiteten Transaktionen isolieren könnten, würde sich während der Verlangsamung vermutlich eine neue Gruppe bilden, während die vorhandene Aufgabengruppe nicht betroffen war.
aktualisieren
Ein häufiges Szenario, in dem eine hohe CPU-Auslastung ohne großen Anstieg der Auslastung auftreten kann, besteht darin, dass eine Aufgabe eine (oder eine Sequenz) anderer Aufgaben auslöst, z. B. beim Empfang einer Netzwerkanforderung, leitet der Handler die Anforderung an einen separaten Thread, den separaten Thread Dann werden einige asynchrone Aufrufe an andere Prozesse gesendet. Durch das Abtasten der Runqueue wird die Last als niedriger gemeldet, als sie tatsächlich ist. Sie steigt jedoch nicht linear mit der CPU-Auslastung an. Die ausgelöste Taskkette wäre ohne die nicht ausführbar gewesen Anfangsereignis und weil sie (mehr oder weniger) sequentiell auftreten, wird die Ausführungswarteschlange nicht aufgeblasen.
quelle
all
Zeile wird weiterhin der Durchschnitt pro CPU angezeigt . Ich werde die Frage klären.