Für unterschiedliche Leistungsprobleme sollten unterschiedliche Leistungsanalysetools ausgewählt werden. Im Folgenden werden häufig verwendete Linux-Leistungstools und die entsprechenden Arten von Leistungsproblemen analysiert. Bilder von: www.ctq6.cn Wie sollen wir „durchschnittliche Auslastung“ verstehen? Zeiteinheitszahl, die die durchschnittliche Anzahl aktiver Prozesse angibt. Es steht nicht in direktem Zusammenhang mit der CPU-Auslastung, wie wir es traditionell verstehen.
Der unterbrechungsfreie Prozess ist ein Prozess, der sich im Kernelstatus in einem kritischen Prozess befindet (z. B. die allgemeine E/A-Antwort, die auf das Gerät wartet). Der unterbrechungsfreie Zustand ist eigentlich ein Schutzmechanismus des Systems für Prozesse und Hardwaregeräte.
Was ist die angemessene durchschnittliche Auslastung?
Überwachen Sie in der tatsächlichen Produktionsumgebung die durchschnittliche Auslastung des Systems und beurteilen Sie den Laständerungstrend anhand historischer Daten. Wenn es einen offensichtlichen Aufwärtstrend bei der Auslastung gibt, führen Sie rechtzeitig eine Analyse und Untersuchung durch. Natürlich können Sie auch einen Schwellenwert festlegen (z. B. wenn die durchschnittliche Auslastung mehr als 70 % der CPU-Anzahl beträgt).
In der Praxis verwechseln wir häufig die Konzepte der durchschnittlichen Auslastung und der CPU-Auslastung. die beiden sind nicht völlig gleichwertig:
CPU-intensive Prozesse: Eine große CPU-Auslastung führt zu einem Anstieg der durchschnittlichen Last. Zu diesem Zeitpunkt sind die beiden konsistent Die CPU-Auslastung ist nicht unbedingt hoch
Eine große Anzahl von Prozessen, die auf die CPU-Planung warten, führt zu einem Anstieg der durchschnittlichen Last. Zu diesem Zeitpunkt ist auch die CPU-Auslastung relativ hoch
Wenn die durchschnittliche Auslastung hoch ist, kann es sein, dass die CPU durch intensive Prozesse oder ausgelastete E/A-Vorgänge verursacht wird. Während einer spezifischen Analyse können Sie das Tool mpstat/pidstat kombinieren, um die Analyse der Lastquelle zu unterstützen
2 CPU
CPU-Kontextwechsel (Teil 1)
CPU-Kontextwechsel besteht darin, den CPU-Kontext (CPU-Register und PC) der vorherigen Aufgabe zu speichern und dann die neue Aufgabe zu laden Kontext zu diesen Registern und dem Programmzähler und springt schließlich zu der Stelle, auf die der Programmzähler zeigt, um die neue Aufgabe auszuführen. Unter anderem wird der gespeicherte Kontext im Systemkernel gespeichert und bei einer Neuplanung der Aufgabe erneut geladen, um sicherzustellen, dass der ursprüngliche Aufgabenstatus nicht beeinträchtigt wird.
Je nach Aufgabentyp ist die CPU-Kontextumschaltung unterteilt in:
Kontextwechsel des Prozesses
Kontextwechsel des Threads
Kontextwechsel unterbrechen
Kontextwechsel Inux-Prozesse folgen Level-Berechtigungen, die den laufenden Bereich eines Prozesses aufteilen in den Kernel-Space und den User-Space. Der Übergang vom Benutzermodus zum Kernelmodus muss durch Systemaufrufe abgeschlossen werden.
Ein Systemaufrufprozess führt tatsächlich zwei CPU-Kontextwechsel durch:
Der Speicherort der Benutzermodusanweisung im CPU-Register wird zuerst gespeichert, das CPU-Register wird auf den Speicherort des Kernelmodusbefehls aktualisiert und springt zum Kernelstatus, um die Kernelaufgabe auszuführen Nachdem der Systemaufruf beendet ist, kehrt das CPU-Register in seinen ursprünglichen Zustand zurück. Speichern Sie die Benutzermodusdaten und wechseln Sie dann zum Benutzerbereich, um die Ausführung fortzusetzen.
Der Systemaufrufprozess umfasst keine Prozessbenutzermodusressourcen wie virtuellen Speicher und wechselt auch nicht den Prozess. Es unterscheidet sich vom Prozesskontextwechsel im herkömmlichen Sinne. Daher wird der Systemaufruf oft als privilegierter Moduswechsel bezeichnet .
Der Prozess wird vom Kernel verwaltet und geplant, und der Prozesskontextwechsel kann nur im Kernel-Status erfolgen. Daher müssen im Vergleich zu Systemaufrufen vor dem Speichern des Kernelstatus und der CPU-Register des aktuellen Prozesses zunächst der virtuelle Speicher und der Stapel des Prozesses gespeichert werden. Nach dem Laden des Kernelstatus des neuen Prozesses müssen der virtuelle Speicher und der Benutzerstapel des Prozesses aktualisiert werden.
Der Prozess muss nur dann den Kontext wechseln, wenn die Ausführung auf der CPU geplant ist. Es gibt die folgenden Szenarien: CPU-Zeitscheiben werden abwechselnd zugewiesen, unzureichende Systemressourcen führen dazu, dass der Prozess hängt, der Prozess bleibt aktiv hängen Schlaffunktion und Prozesse mit hoher Priorität. Zeitscheibe zur Vorbelegung: Wenn die Hardware unterbricht, wird der Prozess auf der CPU angehalten und führt stattdessen den Interrupt-Dienst im Kernel aus.
Thread-Kontextwechsel
Der Thread-Kontextwechsel ist in zwei Typen unterteilt:
Die virtuellen Speicherressourcen bleiben während des Wechsels unverändert und nur die privaten Daten des Threads , Register usw. müssen gewechselt werden;
Der vordere und hintere Thread gehören zu unterschiedlichen Prozessen, was dem Wechsel des Prozesskontexts entspricht.
Thread-Wechsel im selben Prozess verbraucht weniger Ressourcen, was auch der Vorteil von Multithreading ist.
Interrupt-Kontextwechsel
Der Interrupt-Kontextwechsel betrifft nicht den Benutzerstatus des Prozesses, sodass der Interrupt-Kontext nur den Status enthält, der für die Ausführung des Kernel-Status-Interrupt-Dienstprogramms erforderlich ist (CPU-Register, Kernel-Stack, Hardware-Interrupt). Parameter usw.).
Die Priorität der Interrupt-Verarbeitung ist höher als die des Prozesses, sodass Interrupt-Kontextwechsel und Prozesskontextwechsel nicht gleichzeitig stattfinden
Docker+K8s+Jenkins Mainstream-Technologie umfassendes Erklärungsvideomaterial
CPU-Kontextwechsel (Teil 2)
Sie können die allgemeine Kontextwechselsituation des Systems über vmstat überprüfen
vmstat 5 #每隔5s输出一组数据
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 103388 145412 511056 0 0 18 60 1 1 2 1 96 0 0
0 0 0 103388 145412 511076 0 0 0 2 450 1176 1 1 99 0 0
0 0 0 103388 145412 511076 0 0 0 8 429 1135 1 1 98 0 0
0 0 0 103388 145412 511076 0 0 0 0 431 1132 1 1 98 0 0
0 0 0 103388 145412 511076 0 0 0 10 467 1195 1 1 98 0 0
1 0 0 103388 145412 511076 0 0 0 2 426 1139 1 0 99 0 0
4 0 0 95184 145412 511108 0 0 0 74 500 1228 4 1 94 0 0
0 0 0 103512 145416 511076 0 0 0 455 723 1573 12 3 83 2 0 Nach dem Login kopieren
cs (Kontextwechsel) Anzahl der Kontextwechsel pro Sekunde in (Interrupt) Anzahl der Interrupts pro Sekunde r (runnning oder runnable) Die Länge der Bereitschaftswarteschlange, Laufen und Warten Die Anzahl der Prozesse in der CPU b (Blockiert) Die Anzahl der Prozesse im ununterbrochenen Ruhezustand Um die Details jedes Prozesses anzuzeigen, müssen Sie zum Anzeigen pidstat verwenden der Kontextwechsel jedes Prozesses
pidstat -w 5
14时51分16秒 UID PID cswch/s nvcswch/s Command
14时51分21秒 0 1 0.80 0.00 systemd
14时51分21秒 0 6 1.40 0.00 ksoftirqd/0
14时51分21秒 0 9 32.67 0.00 rcu_sched
14时51分21秒 0 11 0.40 0.00 watchdog/0
14时51分21秒 0 32 0.20 0.00 khugepaged
14时51分21秒 0 271 0.20 0.00 jbd2/vda1-8
14时51分21秒 0 1332 0.20 0.00 argusagent
14时51分21秒 0 5265 10.02 0.00 AliSecGuard
14时51分21秒 0 7439 7.82 0.00 kworker/0:2
14时51分21秒 0 7906 0.20 0.00 pidstat
14时51分21秒 0 8346 0.20 0.00 sshd
14时51分21秒 0 20654 9.82 0.00 AliYunDun
14时51分21秒 0 25766 0.20 0.00 kworker/u2:1
14时51分21秒 0 28603 1.00 0.00 python3 Nach dem Login kopieren
cswch 每秒自愿上下文切换次数 (进程无法获取所需资源导致的上下文切换) nvcswch 每秒非自愿上下文切换次数 (时间片轮流等系统强制调度) vmstat 1 1 #首先获取空闲系统的上下文切换次数
sysbench --threads=10 --max-time=300 threads run #模拟多线程切换问题
vmstat 1 1 #新终端观察上下文切换情况
此时发现cs数据明显升高,同时观察其他指标:
r列: 远超系统CPU个数,说明存在大量CPU竞争
us和sy列:sy列占比80%,说明CPU主要被内核占用
in列: 中断次数明显上升,说明中断处理也是潜在问题 Nach dem Login kopieren
说明运行/等待CPU的进程过多,导致大量的上下文切换,上下文切换导致系统的CPU占用率高
pidstat -w -u 1 #查看到底哪个进程导致的问题 Nach dem Login kopieren
从结果中看出是sysbench导致CPU使用率过高,但是pidstat输出的上下文次数加起来也并不多。分析sysbench模拟的是线程的切换,因此需要在pidstat后加-t参数查看线程指标。
另外对于中断次数过多,我们可以通过/proc/interrupts文件读取
watch -d cat /proc/interrupts Nach dem Login kopieren
发现次数变化速度最快的是重调度中断(RES),该中断用来唤醒空闲状态的CPU来调度新的任务运行。分析还是因为过多任务的调度问题,和上下文切换分析一致。
某个应用的CPU使用率达到100%,怎么办? Linux作为多任务操作系统,将CPU时间划分为很短的时间片,通过调度器轮流分配给各个任务使用。为了维护CPU时间,Linux通过事先定义的节拍率,触发时间中断,并使用全局变了jiffies记录开机以来的节拍数。时间中断发生一次该值+1.
CPU使用率 ,除了空闲时间以外的其他时间占总CPU时间的百分比。可以通过/proc/stat中的数据来计算出CPU使用率。因为/proc/stat时开机以来的节拍数累加值,计算出来的是开机以来的平均CPU使用率,一般意义不大。可以间隔取一段时间的两次值作差来计算该段时间内的平均CPU使用率。性能分析工具给出的都是间隔一段时间的平均CPU使用率,要注意间隔时间的设置。
CPU使用率可以通过top 或 ps来查看。分析进程的CPU问题可以通过perf,它以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以用来分析指定应用程序的性能问题。
perf top / perf record / perf report (-g 开启调用关系的采样)
sudo docker run --name nginx -p 10000:80 -itd feisky/nginx
sudo docker run --name phpfpm -itd --network container:nginx feisky/php-fpm
ab -c 10 -n 100 http://XXX.XXX.XXX.XXX:10000/ #测试Nginx服务性能 Nach dem Login kopieren
发现此时每秒可承受请求给长少,此时将测试的请求数从100增加到10000。在另外一个终端运行top查看每个CPU的使用率。发现系统中几个php-fpm进程导致CPU使用率骤升。
接着用perf来分析具体是php-fpm中哪个函数导致该问题。
perf top -g -p XXXX #对某一个php-fpm进程进行分析 Nach dem Login kopieren
发现其中sqrt和add_function占用CPU过多, 此时查看源码找到原来是sqrt中在发布前没有删除测试代码段,存在一个百万次的循环导致。将该无用代码删除后发现nginx负载能力明显提升
系统的CPU使用率很高,为什么找不到高CPU的应用? sudo docker run --name nginx -p 10000:80 -itd feisky/nginx:sp
sudo docker run --name phpfpm -itd --network container:nginx feisky/php-fpm:sp
ab -c 100 -n 1000 http://XXX.XXX.XXX.XXX:10000/ #并发100个请求测试 Nach dem Login kopieren
实验结果中每秒请求数依旧不高,我们将并发请求数降为5后,nginx负载能力依旧很低。
此时用top和pidstat发现系统CPU使用率过高,但是并没有发现CPU使用率高的进程。
出现这种情况一般时我们分析时遗漏的什么信息,重新运行top命令并观察一会。发现就绪队列中处于Running状态的进行过多,超过了我们的并发请求次数5. 再仔细查看进程运行数据,发现nginx和php-fpm都处于sleep状态,真正处于运行的却是几个stress进程。
下一步就利用pidstat分析这几个stress进程,发现没有任何输出。用ps aux交叉验证发现依旧不存在该进程。说明不是工具的问题。再top查看发现stress进程的进程号变化了,此时有可能时以下两种原因导致:
进程不停的崩溃重启(如段错误/配置错误等),此时进程退出后可能又被监控系统重启; 短时进程导致,即其他应用内部通过exec调用的外面命令,这些命令一般只运行很短时间就结束,很难用top这种间隔较长的工具来发现 可以通过pstree来查找 stress的父进程,找出调用关系。
pstree | grep stress Nach dem Login kopieren
发现是php-fpm调用的该子进程,此时去查看源码可以看出每个请求都会调用一个stress命令来模拟I/O压力。之前top显示的结果是CPU使用率升高,是否真的是由该stress命令导致的,还需要继续分析。代码中给每个请求加了verbose=1的参数后可以查看stress命令的输出,在中断测试该命令结果显示stress命令运行时存在因权限问题导致的文件创建失败的bug。
此时依旧只是猜测,下一步继续通过perf工具来分析。性能报告显示确实时stress占用了大量的CPU,通过修复权限问题来优化解决即可.
Was soll ich tun, wenn es im System eine große Anzahl unterbrechungsfreier Prozesse und Zombie-Prozesse gibt? Prozessstatus R Wird ausgeführt/ausführbar, was darauf hinweist, dass sich der Prozess in der Bereitschaftswarteschlange der CPU befindet, ausgeführt wird oder auf die Ausführung wartet; ein Prozess Es interagiert mit der Hardware und darf während der Interaktion nicht von anderen Prozessen unterbrochen werden. Z Zombie, ein Zombie-Prozess, bedeutet, dass der Prozess tatsächlich beendet wurde, der übergeordnete Prozess jedoch nicht wiederhergestellt wurde seine Ressourcen; S Unterbrechbarer Schlaf, der den Schlafzustand unterbrechen kann, bedeutet, dass der Prozess vom System angehalten wird, weil es auf ein Ereignis wartet, es wird geweckt und tritt ein R-Zustand; I Leerlauf, Ruhezustand, wird in unterbrechungsfreien Kernel-Threads verwendet.该状态不会导致平均负载升高; T Stop/Traced,表示进程处于暂停或跟踪状态(SIGSTOP/SIGCONT, GDB调试); X Dead,进程已经消亡,不会在top/ps中看到。 对于不可中断状态,一般都是在很短时间内结束,可忽略。但是如果系统或硬件发生故障,进程可能会保持不可中断状态很久,甚至系统中出现大量不可中断状态,此时需注意是否出现了I/O性能问题。
僵尸进程一般多进程应用容易遇到,父进程来不及处理子进程状态时子进程就提前退出,此时子进程就变成了僵尸进程。大量的僵尸进程会用尽PID进程号,导致新进程无法建立。
磁盘O_DIRECT问题 sudo docker run --privileged --name=app -itd feisky/app:iowait
ps aux | grep '/app' Nach dem Login kopieren
可以看到此时有多个app进程运行,状态分别时Ss+和D+。其中后面s表示进程是一个会话的领导进程,+号表示前台进程组。
其中进程组 表示一组相互关联的进程,子进程是父进程所在组的组员。会话 指共享同一个控制终端的一个或多个进程组。
用top查看系统资源发现:1)平均负载在逐渐增加,且1分钟内平均负载达到了CPU个数,说明系统可能已经有了性能瓶颈;2)僵尸进程比较多且在不停增加;3)us和sys CPU使用率都不高,iowait却比较高;4)每个进程CPU使用率也不高,但有两个进程处于D状态,可能在等待IO。
分析目前数据可知:iowait过高导致系统平均负载升高,僵尸进程不断增长说明有程序没能正确清理子进程资源。
用dstat来分析,因为它可以同时查看CPU和I/O两种资源的使用情况,便于对比分析。
dstat 1 10 #间隔1秒输出10组数据 Nach dem Login kopieren
可以看到当wai(iowait)升高时磁盘请求read都会很大,说明iowait的升高和磁盘的读请求有关。接下来分析到底时哪个进程在读磁盘。
之前top查看的处于D状态的进程号,用pidstat -d -p XXX 展示进程的I/O统计数据。发现处于D状态的进程都没有任何读写操作。在用pidstat -d 查看所有进程的I/O统计数据,看到app进程在进行磁盘读操作,每秒读取32MB的数据。进程访问磁盘必须使用系统调用处于内核态,接下来重点就是找到app进程的系统调用。
sudo strace -p XXX #对app进程调用进行跟踪 Nach dem Login kopieren
报错没有权限,因为已经时root权限了。所以遇到这种情况,首先要检查进程状态是否正常。ps命令查找该进程已经处于Z状态,即僵尸进程。
这种情况下top pidstat之类的工具无法给出更多的信息,此时像第5篇一样,用perf record -d和perf report进行分析,查看app进程调用栈。
看到app确实在通过系统调用sys_read()读取数据,并且从new_sync_read和blkdev_direct_IO看出进程时进行直接读操作,请求直接从磁盘读,没有通过缓存导致iowait升高。
通过层层分析后,root cause是app内部进行了磁盘的直接I/O。然后定位到具体代码位置进行优化即可。
Zombie-Prozesse Nach der oben genannten Optimierung ist Iowait deutlich zurückgegangen, aber die Anzahl der Zombie-Prozesse nimmt immer noch zu. Suchen Sie zunächst den übergeordneten Prozess des Zombie-Prozesses. Drucken Sie mit pstree -aps XXX den Aufrufbaum des Zombie-Prozesses aus und stellen Sie fest, dass der übergeordnete Prozess der App-Prozess ist.
Überprüfen Sie den App-Code, um zu sehen, ob das Ende des untergeordneten Prozesses korrekt behandelt wird (ob wait()/waitpid() aufgerufen wird, ob eine SIGCHILD-Signalverarbeitungsfunktion registriert ist usw.).
Wenn Sie auf einen Anstieg von Iowait stoßen, überprüfen Sie zunächst mit Tools wie dstat und pidstat, ob ein Festplatten-E/A-Problem vorliegt, und finden Sie dann heraus, welche Prozesse das E/A verursachen. Wenn Sie strace nicht verwenden können Um den Prozessaufruf direkt zu analysieren, können Sie ihn mit dem Perf-Tool analysieren.
Für das Zombie-Problem verwenden Sie pstree, um den übergeordneten Prozess zu finden, und sehen Sie sich dann den Quellcode an, um die Verarbeitungslogik für das Ende des untergeordneten Prozesses zu überprüfen.
CPU-Leistungsmetriken Benutzer-CPU-Auslastung, einschließlich Benutzermodus (Benutzer) und Benutzermodus mit niedriger Priorität (nice). Wenn dieser Indikator zu hoch ist, zeigt dies an, dass die Anwendung ausgelastet ist , CPU ist Der Prozentsatz der Zeit, in der der Kernelmodus ausgeführt wird (ohne Unterbrechungen). Ein hoher Indikator zeigt an, dass der Kernel relativ ausgelastet ist /O-Interaktionszeit zwischen dem System und dem Hardwaregerät. Relativ lang / Gast-CPU gibt den Prozentsatz der von der virtuellen Maschine belegten CPU an Wenn es größer ist, bedeutet dies, dass die Systemlast höher istEinschließlich des freiwilligen Wechsels, wenn keine Ressourcen abgerufen werden können, und des unfreiwilligen Wechsels, wenn das System die Planung selbst erzwingt, ist eine Kernfunktion, um den normalen Betrieb von Linux sicherzustellen. Übermäßiger Wechsel verbraucht die CPU-Zeit des ursprünglich laufenden Prozesses im Register. Kernel- und virtueller Speicher sowie andere Datenspeicherung und -wiederherstellung. Durchsuchen Sie außerdem den Backstagebereich des Programmierers Xiaole für öffentliche Konten, um auf „Interviewfragen“ zu antworten und ein Überraschungsgeschenkpaket zu erhalten.
CPU-Cache-Trefferquote
CPU-Cache-Wiederverwendung: Je höher die Trefferquote, desto besser ist die Leistung. Unter diesen wird L1/L2 häufig im Single-Core-Bereich und L3 im Multi-Core-Bereich verwendet -Kern
Leistungstools Durchschnittlicher Lastfall Verwenden Sie zunächst die Betriebszeit, um die durchschnittliche Systemlast zu überprüfen. Verwenden Sie mpstat und. pid nach der Beurteilung der Lastprüfungen CPUs und CPU-Auslastung pro Prozess. Finden Sie heraus, welche Prozesse eine höhere durchschnittliche Auslastung verursachen Verwenden Sie pidstat, um den freiwilligen und unfreiwilligen Kontextwechsel des Prozesses zu beobachtenBeobachten Sie abschließend den Kontextwechsel des Threads über pidstat Bei hoher Prozess-CPU-Auslastung Verwenden Sie zuerst top, um die CPU-Auslastung des Systems und des Prozesses anzuzeigen und zu lokalisieren den Prozess Dann verwenden Sie perf top, um die Prozessaufrufkette zu beobachten und die spezifische Funktion zu finden Auslastung des Systems und des Prozesses, top/ Sogar pidstat kann keine Prozesse mit hoher CPU-Auslastung finden. Überprüfen Sie die Top-Ausgabe noch einmal Perf-Aufzeichnung/Bericht über kurzlebige Prozesse (Execsnoop-Tool)