Linuxパフォーマンス最適化のナレッジポイントまとめ・実践+集編
#
#パート 1Linux パフォーマンスの最適化
##1 パフォーマンス最適化
パフォーマンス指標
高い同時実行性と高速応答は、パフォーマンス最適化メトリクスの 2 つのコアに対応します:スループットおよびレイテンシー
#アプリケーション負荷角度: 製品端末のユーザー エクスペリエンスに直接影響します。 システム リソース視点: リソースの使用状況、飽和など
パフォーマンス問題の本質つまり、システム リソースがボトルネックに達していますが、リクエストの処理速度が十分ではないため、さらに多くのリクエストをサポートできません。パフォーマンス分析は実際には、アプリケーションまたはシステムのボトルネックを見つけて、それらを回避または軽減することを目的としています。
アプリケーションとシステムのパフォーマンスを評価するためのメトリクスを選択する アプリケーションとシステムのパフォーマンス目標を設定する パフォーマンスを推進するベンチマーク テスト ボトルネックを特定するためのパフォーマンス分析 パフォーマンスの監視とアラーム
さまざまなパフォーマンスの場合この問題を解決するには、さまざまなパフォーマンス分析ツールを選択する必要があります。以下は、一般的に使用される Linux パフォーマンス ツールと、分析された対応するタイプのパフォーマンス問題です。

##「平均負荷」をどのように理解すればよいか #平均負荷:
単位時間あたりのシステムの実行可能および中断不可能な状態にあるプロセスの平均数、つまりアクティブなプロセスの平均数。これは、私たちが従来理解しているように、CPU 使用率とは直接関係しません。中断不可能なプロセスは、カーネル状態で重要なプロセスにあるプロセスです (デバイスを待っている共通 I/O 応答など)。 無停電状態は、実際には、プロセスとハードウェア デバイスに対するシステムの保護メカニズムです。
妥当な平均負荷はどれくらいですか?
実際の運用環境では、システムの平均負荷を監視し、履歴に基づいて負荷の変化傾向を判断します。データ。負荷が明らかに増加傾向にある場合は、タイムリーに分析と調査を実施します。もちろん、しきい値を設定することもできます (平均負荷が CPU 数の 70% を超える場合など)
実際の作業では、平均負荷と CPU 使用率の概念が混同されることがよくあります。実際、この 2 つは完全に同等ではありません。 :
CPU を大量に使用するプロセス、大量の CPU 使用率により平均負荷が増加しますが、現時点では 2 つは一貫しています - #I/O 集中型のプロセスでは、I/O を待機しているため、平均負荷も増加します。現時点では、CPU 使用率は必ずしも高いわけではありません。
- CPU を待機するプロセス スケジューリングが多数発生すると、平均負荷が増加し、CPU 使用率も比較的高くなります。
平均負荷が高い場合は、CPU を集中的に使用するプロセスまたはビジーな I/O が原因である可能性があります。特定の分析中に、mpstat/pidstat ツールを組み合わせて負荷ソースの分析を支援できます
2CPU
CPU コンテキストの切り替え (パート 1)
CPU コンテキストの切り替え は、前のタスクの CPU コンテキスト (CPU レジスタと PC) を保存し、新しいタスクのコンテキストをこれらのレジスタとプログラム カウンタにロードします。そして最後に、プログラムカウンターが指す場所にジャンプし、新しいタスクを実行します。このうち、保存されたコンテキストはシステム カーネルに保存され、元のタスクのステータスが影響を受けないように、タスクの実行が再スケジュールされるときに再度ロードされます。 Linux 中国語コミュニティをフォローしてください
タスクの種類に応じて、CPU コンテキストの切り替えは次のように分類されます:
- #プロセス コンテキストの切り替え #スレッド コンテキストの切り替え
- #割り込みコンテキストの切り替え
- #プロセス コンテキストの切り替え
Linux プロセスは、アクセス許可のレベルに応じて、プロセスの実行領域をカーネル領域とユーザー領域に分割します。ユーザーモードからカーネルモードへの移行は、システムコールを通じて完了する必要があります。 システム コール プロセスは、実際には 2 つの CPU コンテキスト スイッチを実行します。
CPU レジスタ内のユーザー モード命令位置が最初に保存され、CPU レジスタがカーネル モード命令位置に更新され、カーネル モードにジャンプしてカーネル タスクを実行します。
システムコールが完了すると、CPU レジスタは最初に保存されたユーザー状態データを復元し、ユーザー空間に切り替えて実行を継続します。
システムコール処理には、仮想メモリなどのプロセスのユーザーモードリソースは関与せず、プロセスの切り替えも行いません。これは、従来の意味でのプロセス コンテキストの切り替えとは異なります。したがって、 システム コールは特権モード スイッチ と呼ばれることがよくあります。
プロセスはカーネルによって管理およびスケジュールされ、プロセス コンテキストの切り替えはカーネル状態でのみ発生します。したがって、システムコールと比較して、現在のプロセスのカーネル状態と CPU レジスタを保存する前に、プロセスの仮想メモリとスタックを最初に保存する必要があります。新しいプロセスのカーネル状態をロードした後、プロセスの仮想メモリとユーザー スタックを更新する必要があります。
プロセスは、CPU 上で実行するようにスケジュールされている場合にのみコンテキストを切り替える必要があります。次のシナリオがあります: CPU タイム スライスが順番に割り当てられる、システム リソースが不十分なためにプロセスがハングする、プロセスがアクティブにハングするスリープ機能により、高優先度の第 1 レベルのプロセスがタイム スライスを捕捉し、ハードウェアによる割り込みが発生すると、CPU 上のプロセスが一時停止され、代わりにカーネル内の割り込みサービスが実行されます。
スレッド コンテキストの切り替え
スレッド コンテキストの切り替えは 2 つのタイプに分かれています:
フロント スレッドとリア スレッドは同じプロセスに属します。切り替え時に仮想メモリ リソースは変更されません。スレッドのプライベート データ、レジスタなどを切り替えるだけで済みます。 前スレッドと後スレッドは同じプロセスに属しており、異なるプロセス、プロセスコンテキストの切り替えと同じです。
同じプロセス内でスレッドを切り替えると、消費するリソースが少なくなります。これは、マルチスレッドの利点でもあります。
割り込みコンテキストの切り替え
割り込みコンテキストの切り替えにはプロセスのユーザー モードが関与しないため、割り込みコンテキストにはカーネル モードの実行に必要な状態のみが含まれます。割り込みサービス プログラム (CPU レジスタ、カーネル スタック、ハードウェア割り込みパラメータなど)。
割り込み処理の優先順位はプロセスよりも高いため、割り込みコンテキストの切り替えとプロセスのコンテキスト切り替えが同時に発生することはありません
#CPU コンテキスト スイッチング (パート 2)
vmstatvmstat 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
- # cs (コンテキスト スイッチ) 1 秒あたりのコンテキスト スイッチの数
- in (割り込み) 1 秒あたりの割り込み数
- r ( running または runnable) Ready queue の長さ 各プロセスの詳細については、pidstat を使用して各プロセスのコンテキスト切り替えを表示する必要があります
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
ログイン後にコピー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列: 中断次数明显上升,说明中断处理也是潜在问题
ログイン後にコピー说明运行/等待CPU的进程过多,导致大量的上下文切换,上下文切换导致系统的CPU占用率高
pidstat -w -u 1 #查看到底哪个进程导致的问题
ログイン後にコピー从结果中看出是sysbench导致CPU使用率过高,但是pidstat输出的上下文次数加起来也并不多。分析sysbench模拟的是线程的切换,因此需要在pidstat后加-t参数查看线程指标。
另外对于中断次数过多,我们可以通过/proc/interrupts文件读取
watch -d cat /proc/interrupts
ログイン後にコピー发现次数变化速度最快的是重调度中断(RES),该中断用来唤醒空闲状态的CPU来调度新的任务运行。分析还是因为过多任务的调度问题,和上下文切换分析一致。
アプリケーションの CPU 使用率が 100% に達しました。どうすればよいですか?
Linux は、マルチタスク オペレーティング システムとして、CPU 時間を短いタイム スライスに分割し、スケジューラを通じて順番に各タスクに割り当てます。 CPU 時間を維持するために、Linux は事前定義されたビート レートを通じて時間割り込みをトリガーし、グローバル ジフィーを使用して起動後のビート数を記録します。時間割り込みは 1 回発生します。この値は 1.
CPU 使用率 (アイドル時間を除く合計 CPU 時間の割合) です。 CPU 使用率は /proc/stat のデータから計算できます。 /proc/stat での起動以降のビート数の累積値は、起動以降の平均 CPU 使用率として計算されるため、一般的にはあまり重要ではありません。一定期間ごとに取得した 2 つの値の差を取ることで、その期間の平均 CPU 使用率を計算できます。 パフォーマンス分析ツールでは、一定期間の平均 CPU 使用率が得られます。間隔の設定に注意してください。
CPU 使用率は、top または ps で表示できます。パフォーマンス イベント サンプリングに基づくパフォーマンスを通じてプロセスの CPU 問題を分析できます。システムやカーネル パフォーマンスのさまざまなイベントを分析するだけでなく、指定したアプリケーションのパフォーマンス問題の分析にも使用できます。
パフォーマンス トップ / パフォーマンス レコード / パフォーマンス レポート (-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服务性能
ログイン後にコピー发现此时每秒可承受请求给长少,此时将测试的请求数从100增加到10000。在另外一个终端运行top查看每个CPU的使用率。发现系统中几个php-fpm进程导致CPU使用率骤升。
接着用perf来分析具体是php-fpm中哪个函数导致该问题。
perf top -g -p XXXX #对某一个php-fpm进程进行分析
ログイン後にコピー发现其中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个请求测试
ログイン後にコピー实验结果中每秒请求数依旧不高,我们将并发请求数降为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
ログイン後にコピー发现是php-fpm调用的该子进程,此时去查看源码可以看出每个请求都会调用一个stress命令来模拟I/O压力。之前top显示的结果是CPU使用率升高,是否真的是由该stress命令导致的,还需要继续分析。代码中给每个请求加了verbose=1的参数后可以查看stress命令的输出,在中断测试该命令结果显示stress命令运行时存在因权限问题导致的文件创建失败的bug。
これはまだ単なる推測です。次のステップでは、perf ツールを使用して分析を続けます。パフォーマンス レポートには、ストレスによって実際に多くの CPU が消費されることが示されています。権限の問題を修正することで最適化および解決できます。
システム内に多数の中断不可能なプロセスやゾンビ プロセスが存在する場合はどうすればよいですか?
プロセス ステータス
R 実行中/実行可能。プロセスが CPU の準備完了キューにあり、実行中であることを示します。実行を待っています; D ディスク スリープ (中断不可能な状態のスリープ) は、通常、プロセスがハードウェアと対話中であることを示し、対話中に他のプロセスによって中断されることは許可されません。 Z Zombie (ゾンビ プロセス) は、プロセスが実際には終了したが、親プロセスがリソースを再利用していないことを意味します; Sスリープ状態を中断できる中断可能なスリープは、プロセスが何かを待っていることを意味します。イベントのためにシステムによって中断され、イベントの発生を待っているときにプロセスが目覚めて R 状態に入ります。 - #I アイドル、アイドル状態。スリープを中断できないカーネル スレッドで使用されます。この状態によって平均負荷が増加することはありません;
- 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'
ログイン後にコピー可以看到此时有多个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组数据
ログイン後にコピー可以看到当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进程调用进行跟踪
ログイン後にコピー报错没有权限,因为已经时root权限了。所以遇到这种情况,首先要检查进程状态是否正常。ps命令查找该进程已经处于Z状态,即僵尸进程。
这种情况下top pidstat之类的工具无法给出更多的信息,此时像第5篇一样,用perf record -d和perf report进行分析,查看app进程调用栈。
看到app确实在通过系统调用sys_read()读取数据,并且从new_sync_read和blkdev_direct_IO看出进程时进行直接读操作,请求直接从磁盘读,没有通过缓存导致iowait升高。
レイヤーごとの分析の結果、根本原因はアプリ内の直接のディスク I/O であることがわかりました。次に、最適化のために特定のコードの場所を見つけます。
ゾンビ プロセス
上記の最適化後、iowait は大幅に減少しましたが、ゾンビ プロセスの数は依然として増加しています。まず、ゾンビ プロセスの親プロセスを見つけます。pstree -aps XXX を使用してゾンビ プロセスの呼び出しツリーを出力し、親プロセスがアプリ プロセスであることを確認します。
アプリのコードをチェックして、子プロセスの終了が正しく処理されているかどうか (wait()/waitpid() が呼び出されているかどうか、SIGCHILD 信号処理関数が登録されているかどうかなど) を確認します。
iowait の増加が発生した場合は、まず dstat pidstat などのツールを使用してディスク I/O の問題があるかどうかを確認し、次に I/O の原因となっているプロセスを特定します。 strace を使用してプロセス呼び出しを直接分析することはできませんが、perf ツールを使用して分析できます。
ゾンビの問題の場合は、pstree を使用して親プロセスを見つけ、ソース コードを参照して子プロセスの最後までの処理ロジックを確認します。
CPU パフォーマンス インジケーター
CPU 使用率
-
ユーザー モード (ユーザー) および低優先ユーザー モード (良好) を含むユーザーの CPU 使用率。このインジケーターが高すぎる場合は、アプリケーションがビジーであることを示します。 システム CPU 使用率。CPU がカーネル モードで実行されている時間の割合 (割り込みを除く)。高いインジケータは、カーネルが比較的ビジーであることを示します。 I/ を待機している CPU 使用率O、iowait、高いインジケーター システムとハードウェア デバイス間の I/O 対話時間が比較的長いことを示します。 ソフト/ハード割り込み CPU 使用率。高いインジケーターは、それを示します。システム内で多数の割り込みが発生していることを示します。 スチール CPU / ゲスト CPU。仮想マシンが占有する CPU の割合を示します。 平均負荷理想的な平均負荷 論理 CPU の数と同じであれば、各 CPU が十分に利用されていることを意味し、その数より大きい場合はシステム負荷が低いことを意味します重い。 プロセス コンテキストの切り替え リソースを取得できない場合の自発的な切り替えと、システムがスケジュールを強制する場合の非自発的な切り替えが含まれます。コンテキストの切り替え自体は、Linux の通常の動作を保証するためのコア機能です。過度の切り替えは、レジスタ内の元の実行プロセスの CPU 時間を消費します。 、カーネル占有率、仮想メモリ、その他のデータの保存と回復
CPU キャッシュ ヒット率
CPU キャッシュの再利用状況、ヒット率が高くなります。パフォーマンスが高いほど優れています。L1/L2 はシングルコアでよく使用され、L3 はマルチコアで使用されます
#パフォーマンス ツール
- 負荷平均ケース
- まずuptimeでシステムの平均負荷を確認します
- 負荷が増加していると判断したら、mpstatとpidstatで各CPUのCPU使用率を確認し、さらに、パブリック アカウント Linux を検索し、バックグラウンドで「git Books」と返信すると、サプライズ ギフト パッケージを入手できます。
- #コンテキスト切り替えのケース
- 最初に vmstat を使用してシステム コンテキストの切り替えと割り込み時間を確認します
- pidstat を使用してプロセスの自発的および非自発的コンテキスト切り替えを観察します ##最後に、pidstat を使用してスレッドのコンテキスト切り替えを観察します
- #perf top を使用してプロセス呼び出しチェーンを観察し、特定の関数を見つけます
- システム CPU 使用率が高い場合
- # #まず、top を使用して、システムとプロセスの CPU 使用率を確認します。top/pidstat のどちらも、CPU 使用率が高いプロセスを見つけることができません。
Re-一番上の出力を調べます。 -
CPU 使用率は低いが、実行状態にあるプロセスから開始します。 パフォーマンス レコード/レポートで、短いことが判明しました。発生したタームプロセス (execsnoop ツール) - 中断不可能なゾンビプロセスのケース
- まず、top を使用して増加を観察します。の iowait を実行すると、多数の中断不可能なゾンビ プロセスが見つかります
strace ではプロセスのシステム コールを追跡できません パフォーマンス分析コール チェーンにより、根本原因がディスク ダイレクト I/O にあることが判明しました ソフト割り込みケース topシステム ソフト割り込みの高い CPU 使用率を観察します /proc/softirqs をチェックして、レートが急速に変化するいくつかのソフト割り込みを見つけます sar コマンドにより、ネットワーク パケットの問題であることが判明しました。 tcpdump により、ネットワーク フレームのタイプとソースが判明し、SYN FLOOD 攻撃が原因であることが判明しました
- まず、top を使用してシステムとプロセスの CPU 使用率を確認し、プロセスを見つけます
さまざまなパフォーマンス インジケーターを使用して、適切なツールを見つけてください:
画像の出典: www.ctq6.cn 運用環境では、開発者に新しいツールをインストールする権限がないことがよくあります。ツールキットは、システムにすでにインストールされているツールを最大限に活用することしかできません。したがって、一部の主流ツールがどのような指標分析を提供できるかを理解する必要があります。
画像は www.ctq6.cn からの画像です。まず、top/vmstat/pidstat など、より多くのインジケーターをサポートするいくつかのツールを実行します。その出力に基づいて、パフォーマンスの問題の種類を調べます。プロセスを特定した後、strace/perf を使用して呼び出し状況を分析し、さらに分析します。ソフト割り込みが原因の場合は、/proc/softirqs
# を使用します。 ##画像の出典: www .ctq6.cn
CPU 最適化
アプリケーションの最適化 - #コンパイラの最適化: gcc -O2
- アルゴリズム最適化
## など、コンパイル フェーズ中に最適化オプションを有効にします。 #非同期処理: 特定のリソースを待ってプログラムがブロックされることを回避し、プログラムの同時処理能力を向上させます (ポーリングをイベント通知に置き換えます) - #マルチスレッド置換 マルチプロセス: コンテキストスイッチングコストの削減
- キャッシュを有効活用: プログラム処理の高速化
-
- CPU 排他: プロセスを割り当てる CPU アフィニティ メカニズム
- #優先度調整: nice を使用して非コア アプリケーションの優先度を適切に下げる
- プロセスのリソース表示を設定します。cgroups は、アプリケーションがシステム リソースを使い果たさないように使用制限を設定します。
- NUMA 最適化: CPU がローカル メモリにアクセスします。可能な限り
- 割り込み負荷分散: irpbalance、割り込み処理プロセスを各 CPU に自動的に負荷分散します
同時実行数
応答時間
QPS(TPS)=数値同時実行数 / 平均応答時間
ユーザー リクエスト サーバー
サーバー内部処理
##サーバーはクライアントに戻りますQPS は TPS に似ていますが、ページへの訪問によって TPS が形成されますが、ページ リクエストには以下が含まれる場合があります。サーバーへの複数のリクエスト。複数回カウントされる場合があります。 QPS QPS (Queries Per Second) 1 秒あたりのクエリ レート、サーバーが応答できるクエリの数 TPS (Transactions Per Second) 1 秒あたりのトランザクション数、ソフトウェア テストの結果。 -
##システム スループット (いくつかの重要なパラメータを含む):
#3メモリ
Linux メモリの仕組み
メモリ マッピング
ほとんどのコンピュータで使用されるメイン メモリはダイナミック ランダム アクセス メモリ (DRAM) です。カーネルのみが物理メモリに直接アクセスできます。 Linux カーネルはプロセスごとに独立した仮想アドレス空間を提供し、このアドレス空間は連続的です。このようにして、プロセスはメモリ (仮想メモリ) に簡単にアクセスできます。 仮想アドレス空間の内部はカーネル空間とユーザー空間に分かれており、ワード長の異なるプロセッサではアドレス空間の範囲が異なります。 32 ビット システムのカーネル空間は 1G を占有し、ユーザー空間は 3G を占有します。 64 ビット システムのカーネル空間とユーザー空間は両方とも 128T で、それぞれメモリ空間の最高位と最低位の部分を占め、中間部分は未定義です。すべての仮想メモリが物理メモリを割り当てるわけではなく、実際に使用される場合のみ割り当てられます。割り当てられた物理メモリは、メモリ マッピングを通じて管理されます。メモリ マッピングを完了するために、カーネルはプロセスごとにページ テーブルを維持し、仮想アドレスと物理アドレス間のマッピング関係を記録します。ページ テーブルは実際には CPU のメモリ管理ユニット MMU に格納されており、プロセッサはハードウェアを介してアクセスするメモリを直接見つけることができます。
プロセスによってアクセスされた仮想アドレスがページ テーブルで見つからない場合、システムはページ フォールト例外を生成し、カーネル空間に入って物理メモリを割り当て、プロセスのページ テーブルを更新してから、元の状態に戻ります。ユーザー空間を使用してプロセスの操作を再開します。
MMU は、ページ サイズが 4KB のページ単位でメモリを管理します。ページ テーブル エントリが多すぎる問題を解決するために、Linux は マルチレベル ページ テーブル および HugePage メカニズムを提供します。
仮想メモリ空間の分散
ユーザー空間メモリには、低位から高位まで 5 つの異なるメモリ セグメントがあります。
#読み取り専用セグメント コードや定数など ##データセグメント グローバル変数など ヒープ 動的に割り当てられたメモリは、低いアドレスから始まり、上に向かって増加します ファイル マッピング 動的ライブラリ、共有メモリ 待機、上位アドレスから下に向かって成長 #スタック ローカル変数や関数呼び出しのコンテキストなどを含む、スタックのサイズ固定されています。一般に 8MB
メモリの割り当てとリサイクル
Allocation
malloc はシステム コールに相当します。実装方法:brk() メモリの小さなブロック (<128K) の場合は、ヒープの先頭位置を移動して割り当てます。メモリは解放後すぐには返されず、キャッシュされます。 **mmap()**大きなメモリ ブロック (>128K) の場合は、メモリ マッピングを使用して直接割り当てます。つまり、ファイル マッピング セグメントで空きメモリ割り当てを見つけます。
前者のキャッシュは、ページ フォールト例外の発生を減らし、メモリ アクセス効率を向上させることができます。ただし、メモリはシステムに返されないため、メモリがビジー状態のときにメモリの割り当て/解放が頻繁に行われると、メモリの断片化が発生します。
後者は解放時にシステムに直接返されるため、mmap が発生するたびにページフォールト例外が発生します。メモリ作業がビジーな場合、メモリ割り当てが頻繁に行われると、大量のページ フォールト例外が発生し、カーネル管理の負担が増加します。
#上記の 2 つの呼び出しでは、実際にはメモリが割り当てられません。これらのメモリは、最初にアクセスされたときにページ フォルト例外を通じてカーネルにのみ入力され、カーネルによって割り当てられます。 #Recycling
メモリが不足している場合、システムは次の方法でメモリを再利用します。回收缓存:LRU算法回收最近最少使用的内存页面;
回收不常访问内存:把不常用的内存通过交换分区写入磁盘
杀死进程:OOM内核保护机制 (进程消耗内存越大oom_score越大,占用CPU越多oom_score越小,可以通过/proc手动调整oom_adj)
echo -16 > /proc/$(pidof XXX)/oom_adj
ログイン後にコピー
如何查看内存使用情况
free来查看整个系统的内存使用情况
top/ps来查看某个进程的内存使用情况
VIRT プロセスの仮想メモリ サイズ RES 常駐メモリのサイズ。プロセスの実際の使用量 スワップおよび共有メモリを除く物理メモリ サイズ SHR 共有メモリ サイズ、他のプロセスと共有されるメモリ、ロードされたダイナミック リンクライブラリとプログラム コード セグメント #%MEM システム メモリ全体に対するプロセスによって使用される物理メモリの割合
# #メモリ内のバッファとキャッシュを理解するにはどうすればよいですか?
buffer はディスク データのキャッシュ、cache はファイル データのキャッシュです。これらは読み取りリクエストと書き込みリクエストの両方で使用されます
システム キャッシュを使用してプログラムの実行効率を最適化する方法
キャッシュ ヒット率
キャッシュ ヒット率は、キャッシュを介して直接データを取得するリクエストの数を指し、すべてのリクエストの割合を占めます。 ヒット率が高いほど、キャッシュによってもたらされる利点が大きくなり、アプリケーションのパフォーマンスが向上します。
bcc パッケージをインストールした後は、cachestat および cachetop を通じてキャッシュの読み取りおよび書き込みヒットを監視できます。
pcstat をインストールすると、メモリ内のファイルのキャッシュ サイズとキャッシュ率を表示できます
#首先安装Go
export GOPATH=~/go
export PATH=~/go/bin:$PATH
go get golang.org/x/sys/unix
go ge github.com/tobert/pcstat/pcstat
ログイン後にコピーdd缓存加速
dd if=/dev/sda1 of=file bs=1M count=512 #生产一个512MB的临时文件
echo 3 > /proc/sys/vm/drop_caches #清理缓存
pcstat file #确定刚才生成文件不在系统缓存中,此时cached和percent都是0
cachetop 5
dd if=file of=/dev/null bs=1M #测试文件读取速度
#此时文件读取性能为30+MB/s,查看cachetop结果发现并不是所有的读都落在磁盘上,读缓存命中率只有50%。
dd if=file of=/dev/null bs=1M #重复上述读文件测试
#此时文件读取性能为4+GB/s,读缓存命中率为100%
pcstat file #查看文件file的缓存情况,100%全部缓存
ログイン後にコピーO_DIRECT选项绕过系统缓存
cachetop 5
sudo docker run --privileged --name=app -itd feisky/app:io-direct
sudo docker logs app #确认案例启动成功
#实验结果表明每读32MB数据都要花0.9s,且cachetop输出中显示1024次缓存全部命中
ログイン後にコピー但是凭感觉可知如果缓存命中读速度不应如此慢,读次数时1024,页大小为4K,五秒的时间内读取了1024*4KB数据,即每秒0.8MB,和结果中32MB相差较大。说明该案例没有充分利用缓存,怀疑系统调用设置了直接I/O标志绕过系统缓存。因此接下来观察系统调用.
strace -p $(pgrep app)
#strace 结果可以看到openat打开磁盘分区/dev/sdb1,传入参数为O_RDONLY|O_DIRECT
ログイン後にコピー这就解释了为什么读32MB数据那么慢,直接从磁盘读写肯定远远慢于缓存。找出问题后我们再看案例的源代码发现flags中指定了直接IO标志。删除该选项后重跑,验证性能变化。
内存泄漏,如何定位和处理?
对应用程序来说,动态内存的分配和回收是核心又复杂的一个逻辑功能模块。管理内存的过程中会发生各种各样的“事故”:
- #割り当てられたメモリが適切に再利用されず、リークが発生します。
- 割り当てられたメモリ境界外のアドレスがアクセスされ、プログラムが異常終了します
##メモリの割り当てとリサイクル仮想メモリの分散は低位から高位まで、
読み取り専用セグメント、データ セグメント、ヒープ、メモリ マッピング セグメントになります。 , スタック5つのパーツ。
ヒープ: アプリケーション自体によって割り当ておよび管理されます。プログラムが終了しない限り、これらのヒープ メモリはシステムによって自動的に解放されません。 。 メモリ マッピング セグメント: ダイナミック リンク ライブラリと共有メモリを含み、共有メモリはプログラムによって自動的に割り当てられ、管理されます。
メモリ リーク 解放し忘れられたメモリには、アプリケーション自身がアクセスできなくなるだけでなく、システムが他のアプリケーションにメモリを再度割り当てることもできなくなり、被害はさらに大きくなります。 メモリ リークが蓄積し、システム メモリを使い果たす可能性もあります。如何检测内存泄漏
预先安装systat,docker,bcc
sudo docker run --name=app -itd feisky/app:mem-leak
sudo docker logs app
vmstat 3
ログイン後にコピー可以看到free在不断下降,buffer和cache基本保持不变。说明系统的内存一致在升高。但并不能说明存在内存泄漏。此时可以通过memleak工具来跟踪系统或进程的内存分配/释放请求
/usr/share/bcc/tools/memleak -a -p $(pidof app)
ログイン後にコピー从memleak输出可以看到,应用在不停地分配内存,并且这些分配的地址并没有被回收。通过调用栈看到是fibonacci函数分配的内存没有释放。定位到源码后查看源码来修复增加内存释放函数即可.
为什么系统的Swap变高
系统内存资源紧张时通过内存回收和OOM杀死进程来解决。其中可回收内存包括:
キャッシュ/バッファは再利用可能なリソースであり、通常、ファイル管理ではファイル ページと呼ばれます アプリケーションでは、fsync を使用してダーティを削除します。ファイル ページはディスク に同期され、システムに渡されます。カーネル スレッド pdflush は、これらのダーティ ページを更新する役割を果たします。 # # はアプリケーションによって変更されており、まだ書き込まれていません。メモリを解放するには、まずディスク データ (ダーティ ページ) をディスクに書き込む必要があります。メモリマッピングで取得したファイルマッピングページは、次回アクセス時にも解放することができます ファイルから再読み込み
- プログラムによって自動的に割り当てられたヒープメモリ(匿名)用メモリ管理のページで、このメモリを直接解放することはできませんが、Linux にはスワップ メカニズムが用意されています。頻繁にアクセスされないメモリはディスクに書き込まれてメモリが解放され、再度アクセスされたときにメモリをディスクから読み取ることができます。
スワップの原理
スワップの本質は、ディスク領域の一部またはローカル ファイルをメモリとして使用することです。これには、スワップインとスワップアウトの 2 つのプロセスが含まれます。 スワッピング アウト: プロセスが一時的に使用していないメモリ データをディスクに保存し、メモリを解放します。 スワッピング イン: プロセスが再度メモリにアクセスすると、これらはディスクからメモリに読み込まれます
#Linux はメモリ リソースが不足しているかどうかをどのように測定しますか?
ダイレクト メモリ リサイクル 新しい大きなブロック メモリ割り当て要求ですが、残りのメモリが不十分です。このとき、システムはメモリの一部を再利用します;
kswapd0 カーネル スレッドは定期的にメモリを再利用します。メモリ使用量を測定するために、pages_min、pages_low、pages_high の 3 つのしきい値が定義され、それらに基づいてメモリのリサイクル操作が実行されます。
残りのメモリ
pages_min <残りのメモリ pages_high になるまでメモリのリサイクルを実行します pages_low < 剩余内存 < pages_high,内存有一定压力,但可以满足新内存请求
剩余内存 > pages_high,说明剩余内存较多,无内存压力
pages_low = pages_min 5 / 4 pages_high = pages_min 3 / 2
NUMA 与 SWAP
很多情况下系统剩余内存较多,但SWAP依旧升高,这是由于处理器的NUMA架构。
在NUMA架构下多个处理器划分到不同的Node,每个Node都拥有自己的本地内存空间。在分析内存的使用时应该针对每个Node单独分析
numactl --hardware #查看处理器在Node的分布情况,以及每个Node的内存使用情况
ログイン後にコピー内存三个阈值可以通过/proc/zoneinfo来查看,该文件中还包括活跃和非活跃的匿名页/文件页数。
当某个Node内存不足时,系统可以从其他Node寻找空闲资源,也可以从本地内存中回收内存。通过/proc/sys/vm/zone_raclaim_mode来调整。
0表示既可以从其他Node寻找空闲资源,也可以从本地回收内存 1,2,4表示只回收本地内存,2表示可以会回脏数据回收内存,4表示可以用Swap方式回收内存。
swappiness
在实际回收过程中Linux根据/proc/sys/vm/swapiness选项来调整使用Swap的积极程度,从0-100,数值越大越积极使用Swap,即更倾向于回收匿名页;数值越小越消极使用Swap,即更倾向于回收文件页。
注意:这只是调整Swap积极程度的权重,即使设置为0,当剩余内存+文件页小于页高阈值时,还是会发生Swap。
Swap升高时如何定位分析
free #首先通过free查看swap使用情况,若swap=0表示未配置Swap
#先创建并开启swap
fallocate -l 8G /mnt/swapfile
chmod 600 /mnt/swapfile
mkswap /mnt/swapfile
swapon /mnt/swapfile
free #再次执行free确保Swap配置成功
dd if=/dev/sda1 of=/dev/null bs=1G count=2048 #模拟大文件读取
sar -r -S 1 #查看内存各个指标变化 -r内存 -S swap
#根据结果可以看出,%memused在不断增长,剩余内存kbmemfress不断减少,缓冲区kbbuffers不断增大,由此可知剩余内存不断分配给了缓冲区
#一段时间之后,剩余内存很小,而缓冲区占用了大部分内存。此时Swap使用之间增大,缓冲区和剩余内存只在小范围波动
停下sar命令
cachetop5 #观察缓存
#可以看到dd进程读写只有50%的命中率,未命中数为4w+页,说明正式dd进程导致缓冲区使用升高
watch -d grep -A 15 ‘Normal’ /proc/zoneinfo #观察内存指标变化
#发现升级内存在一个小范围不停的波动,低于页低阈值时会突然增大到一个大于页高阈值的值
ログイン後にコピー说明剩余内存和缓冲区的波动变化正是由于内存回收和缓存再次分配的循环往复。有时候Swap用的多,有时候缓冲区波动更多。此时查看swappiness值为60,是一个相对中和的配置,系统会根据实际运行情况来选去合适的回收类型.
#システム メモリの問題を迅速かつ正確に見つける方法
メモリ パフォーマンス インジケーター
システム メモリインジケーター
##使用済みメモリ/残りメモリ##共有メモリ (tmpfs 実装) - #利用可能なメモリ: 残りのメモリとリサイクル可能なメモリを含む
#キャッシュ: ディスク読み取りファイルのページ キャッシュ、スラブ アロケータのリサイクル可能な部分 バッファ: raw ディスク ブロックの一時ストレージ、ディスクに書き込まれるデータのキャッシュ- プロセス メモリ インジケーター
仮想メモリ: 最大 5 常駐メモリ: スワップ メモリと共有メモリを除く、プロセスによって実際に使用される物理メモリ 共有メモリ: 他のプロセスと共有されるメモリ、およびダイナミック リンク ライブラリやプログラムのコード セグメント さらに、パブリック アカウントのテクニカル コミュニティの背景を検索して、「」と返信してください。アルゴリズム」、サプライズギフトパッケージを入手してください。
スワップ メモリ: スワップを通じてメモリがディスクにスワップアウトされました
ページ フォールト例外
物理メモリから直接割り当てることができます。セカンダリ ページ フォールト例外 にはディスク IO 介入 (スワップなど)、プライマリ ページ フォールト例外が必要です。現時点では、メモリ アクセスが大幅に遅くなります
メモリ パフォーマンス ツール
さまざまなパフォーマンス指標に基づいて適切なツールを見つけてください:

画像: www.ctq6.cn メモリ分析ツールに含まれるパフォーマンス インジケーター:

画像: www .ctq6.cn メモリ パフォーマンスのボトルネックを迅速に分析する方法
通常は、まず、free、top、 vmstat 、 pidstat など
まず、free と top を使用してシステム全体のメモリ使用量を確認します。 次に、vmstat と pidstat を使用して、一定期間にわたる傾向を確認します。メモリ問題の種類を特定します。 - #最後に、メモリ割り当て分析、キャッシュ/バッファ分析、特定プロセスのメモリ使用量分析などの詳細な分析を実行します。
一般的な最適化のアイデア: 最好禁止Swap,若必须开启则尽量降低swappiness的值 减少内存的动态分配,如可以用内存池,HugePage等 尽量使用缓存和缓冲区来访问数据。如用堆栈明确声明内存空间来存储需要缓存的数据,或者用Redis外部缓存组件来优化数据的访问 cgroups等方式来限制进程的内存使用情况,确保系统内存不被异常进程耗尽 /proc/pid/oom_adj调整核心应用的oom_score,保证即使内存紧张核心应用也不会被OOM杀死
vmstat使用详解
vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。可以看到整个机器的CPU,内存,IO的使用情况,而不是单单看到各个进程的CPU使用率和内存使用率(使用场景不一样)。
vmstat 2
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 1379064 282244 11537528 0 0 3 104 0 0 3 0 97 0 0
0 0 0 1372716 282244 11537544 0 0 0 24 4893 8947 1 0 98 0 0
0 0 0 1373404 282248 11537544 0 0 0 96 5105 9278 2 0 98 0 0
0 0 0 1374168 282248 11537556 0 0 0 0 5001 9208 1 0 99 0 0
0 0 0 1376948 282248 11537564 0 0 0 80 5176 9388 2 0 98 0 0
0 0 0 1379356 282256 11537580 0 0 0 202 5474 9519 2 0 98 0 0
1 0 0 1368376 282256 11543696 0 0 0 0 5894 8940 12 0 88 0 0
1 0 0 1371936 282256 11539240 0 0 0 10554 6176 9481 14 1 85 1 0
1 0 0 1366184 282260 11542292 0 0 0 7456 6102 9983 7 1 91 0 0
1 0 0 1353040 282260 11556176 0 0 0 16924 7233 9578 18 1 80 1 0
0 0 0 1359432 282260 11549124 0 0 0 12576 5495 9271 7 0 92 1 0
0 0 0 1361744 282264 11549132 0 0 0 58 8606 15079 4 2 95 0 0
1 0 0 1367120 282264 11549140 0 0 0 2 5716 9205 8 0 92 0 0
0 0 0 1346580 282264 11562644 0 0 0 70 6416 9944 12 0 88 0 0
0 0 0 1359164 282264 11550108 0 0 0 2922 4941 8969 3 0 97 0 0
1 0 0 1353992 282264 11557044 0 0 0 0 6023 8917 15 0 84 0 0
# 结果说明
- r 表示运行队列(就是说多少个进程真的分配到CPU),我测试的服务器目前CPU比较空闲,没什么程序在跑,当这个值超过了CPU数目,就会出现CPU瓶颈了。这个也和top的负载有关系,一般负载超过了3就比较高,超过了5就高,超过了10就不正常了,服务器的状态很危险。top的负载类似每秒的运行队列。如果运行队列过大,表示你的CPU很繁忙,一般会造成CPU使用率很高。
- b 表示阻塞的进程,这个不多说,进程阻塞,大家懂的。
- swpd 虚拟内存已使用的大小,如果大于0,表示你的机器物理内存不足了,如果不是程序内存泄露的原因,那么你该升级内存了或者把耗内存的任务迁移到其他机器。
- free 空闲的物理内存的大小,我的机器内存总共8G,剩余3415M。
- buff Linux/Unix系统是用来存储,目录里面有什么内容,权限等的缓存,我本机大概占用300多M
- cache cache直接用来记忆我们打开的文件,给文件做缓冲,我本机大概占用300多M(这里是Linux/Unix的聪明之处,把空闲的物理内存的一部分拿来做文件和目录的缓存,是为了提高 程序执行的性能,当程序使用内存时,buffer/cached会很快地被使用。)
- si 每秒从磁盘读入虚拟内存的大小,如果这个值大于0,表示物理内存不够用或者内存泄露了,要查找耗内存进程解决掉。我的机器内存充裕,一切正常。
- so 每秒虚拟内存写入磁盘的大小,如果这个值大于0,同上。
- bi 块设备每秒接收的块数量,这里的块设备是指系统上所有的磁盘和其他块设备,默认块大小是1024byte,我本机上没什么IO操作,所以一直是0,但是我曾在处理拷贝大量数据(2-3T)的机器上看过可以达到140000/s,磁盘写入速度差不多140M每秒
- bo 块设备每秒发送的块数量,例如我们读取文件,bo就要大于0。bi和bo一般都要接近0,不然就是IO过于频繁,需要调整。
- in 每秒CPU的中断次数,包括时间中断
- cs 每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。
- us 用户CPU时间,我曾经在一个做加密解密很频繁的服务器上,可以看到us接近100,r运行队列达到80(机器在做压力测试,性能表现不佳)。
- sy 系统CPU时间,如果太高,表示系统调用时间长,例如是IO操作频繁。
- id 空闲CPU时间,一般来说,id + us + sy = 100,一般我认为id是空闲CPU使用率,us是用户CPU使用率,sy是系统CPU使用率。
- wt 等待IO CPU时间
ログイン後にコピーpidstat 使用详解
pidstat主要用于监控全部或指定进程占用系统资源的情况,如CPU,内存、设备IO、任务切换、线程等。
Usage:
pidstat –d 間隔時間は各プロセスの IO 使用量をカウントします pidstat –u 間隔時間は各プロセスの CPU をカウントします統計情報 pidstat -r 間隔回数は各プロセスのメモリ使用量情報をカウントします pidstat -w 間隔回数は各プロセスのコンテキストをカウントしますSwitch p PID PID を指定
1. 統計 IO 使用状況
pidstat -d 1 10
03:02:02 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command
03:02:03 PM 0 816 0.00 918.81 0.00 jbd2/vda1-8
03:02:03 PM 0 1007 0.00 3.96 0.00 AliYunDun
03:02:03 PM 997 7326 0.00 1904.95 918.81 java
03:02:03 PM 997 8539 0.00 3.96 0.00 java
03:02:03 PM 0 16066 0.00 35.64 0.00 cmagent
03:02:03 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command
03:02:04 PM 0 816 0.00 1924.00 0.00 jbd2/vda1-8
03:02:04 PM 997 7326 0.00 11156.00 1888.00 java
03:02:04 PM 997 8539 0.00 4.00 0.00 java
ログイン後にコピーUID PID kB_rd/s: 每秒进程从磁盘读取的数据量 KB 单位 read from disk each second KB kB_wr/s: 每秒进程向磁盘写的数据量 KB 单位 write to disk each second KB kB_ccwr/s: 每秒进程向磁盘写入,但是被取消的数据量,This may occur when the task truncates some dirty pagecache. iodelay: Block I/O delay, measured in clock ticks Command: 进程名 task name
2、统计CPU使用情况
# 统计CPU
pidstat -u 1 10
03:03:33 PM UID PID %usr %system %guest %CPU CPU Command
03:03:34 PM 0 2321 3.96 0.00 0.00 3.96 0 ansible
03:03:34 PM 0 7110 0.00 0.99 0.00 0.99 4 pidstat
03:03:34 PM 997 8539 0.99 0.00 0.00 0.99 5 java
03:03:34 PM 984 15517 0.99 0.00 0.00 0.99 5 java
03:03:34 PM 0 24406 0.99 0.00 0.00 0.99 5 java
03:03:34 PM 0 32158 3.96 0.00 0.00 3.96 2 ansible
ログイン後にコピーUID PID %usr: 进程在用户空间占用 cpu 的百分比 %system: 进程在内核空间占用 CPU 百分比 %guest: 进程在虚拟机占用 CPU 百分比 %wait: 进程等待运行的百分比 %CPU: 进程占用 CPU 百分比 CPU: 处理进程的 CPU 编号 Command: 进程名
3、统计内存使用情况
# 统计内存
pidstat -r 1 10
Average: UID PID minflt/s majflt/s VSZ RSS %MEM Command
Average: 0 1 0.20 0.00 191256 3064 0.01 systemd
Average: 0 1007 1.30 0.00 143256 22720 0.07 AliYunDun
Average: 0 6642 0.10 0.00 6301904 107680 0.33 java
Average: 997 7326 10.89 0.00 13468904 8395848 26.04 java
Average: 0 7795 348.15 0.00 108376 1233 0.00 pidstat
Average: 997 8539 0.50 0.00 8242256 2062228 6.40 java
Average: 987 9518 0.20 0.00 6300944 1242924 3.85 java
Average: 0 10280 3.70 0.00 807372 8344 0.03 aliyun-service
Average: 984 15517 0.40 0.00 6386464 1464572 4.54 java
Average: 0 16066 236.46 0.00 2678332 71020 0.22 cmagent
Average: 995 20955 0.30 0.00 6312520 1408040 4.37 java
Average: 995 20956 0.20 0.00 6093764 1505028 4.67 java
Average: 0 23936 0.10 0.00 5302416 110804 0.34 java
Average: 0 24406 0.70 0.00 10211672 2361304 7.32 java
Average: 0 26870 1.40 0.00 1470212 36084 0.11 promtail
ログイン後にコピーUID PID Minflt/s : 每秒次缺页错误次数 (minor page faults),虚拟内存地址映射成物理内存地址产生的 page fault 次数 Majflt/s : 每秒主缺页错误次数 (major page faults), 虚拟内存地址映射成物理内存地址时,相应 page 在 swap 中 VSZ virtual memory usage : 该进程使用的虚拟内存 KB 单位 RSS : 该进程使用的物理内存 KB 单位 %MEM : 内存使用率 Command : 该进程的命令 task name
4、查看具体进程使用情况
pidstat -T ALL -r -p 20955 1 10
03:12:16 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command
03:12:17 PM 995 20955 0.00 0.00 6312520 1408040 4.37 java
03:12:16 PM UID PID minflt-nr majflt-nr Command
03:12:17 PM 995 20955 0 0 java
ログイン後にコピー
回收缓存:LRU算法回收最近最少使用的内存页面;
回收不常访问内存:把不常用的内存通过交换分区写入磁盘
杀死进程:OOM内核保护机制 (进程消耗内存越大oom_score越大,占用CPU越多oom_score越小,可以通过/proc手动调整oom_adj)
echo -16 > /proc/$(pidof XXX)/oom_adj
#首先安装Go export GOPATH=~/go export PATH=~/go/bin:$PATH go get golang.org/x/sys/unix go ge github.com/tobert/pcstat/pcstat
dd if=/dev/sda1 of=file bs=1M count=512 #生产一个512MB的临时文件 echo 3 > /proc/sys/vm/drop_caches #清理缓存 pcstat file #确定刚才生成文件不在系统缓存中,此时cached和percent都是0 cachetop 5 dd if=file of=/dev/null bs=1M #测试文件读取速度 #此时文件读取性能为30+MB/s,查看cachetop结果发现并不是所有的读都落在磁盘上,读缓存命中率只有50%。 dd if=file of=/dev/null bs=1M #重复上述读文件测试 #此时文件读取性能为4+GB/s,读缓存命中率为100% pcstat file #查看文件file的缓存情况,100%全部缓存
cachetop 5 sudo docker run --privileged --name=app -itd feisky/app:io-direct sudo docker logs app #确认案例启动成功 #实验结果表明每读32MB数据都要花0.9s,且cachetop输出中显示1024次缓存全部命中
strace -p $(pgrep app) #strace 结果可以看到openat打开磁盘分区/dev/sdb1,传入参数为O_RDONLY|O_DIRECT
如何检测内存泄漏
预先安装systat,docker,bcc
sudo docker run --name=app -itd feisky/app:mem-leak sudo docker logs app vmstat 3
可以看到free在不断下降,buffer和cache基本保持不变。说明系统的内存一致在升高。但并不能说明存在内存泄漏。此时可以通过memleak工具来跟踪系统或进程的内存分配/释放请求
/usr/share/bcc/tools/memleak -a -p $(pidof app)
从memleak输出可以看到,应用在不停地分配内存,并且这些分配的地址并没有被回收。通过调用栈看到是fibonacci函数分配的内存没有释放。定位到源码后查看源码来修复增加内存释放函数即可.
为什么系统的Swap变高
系统内存资源紧张时通过内存回收和OOM杀死进程来解决。其中可回收内存包括:
キャッシュ/バッファは再利用可能なリソースであり、通常、ファイル管理ではファイル ページと呼ばれます アプリケーションでは、fsync を使用してダーティを削除します。ファイル ページはディスク に同期され、システムに渡されます。カーネル スレッド pdflush は、これらのダーティ ページを更新する役割を果たします。 # # はアプリケーションによって変更されており、まだ書き込まれていません。メモリを解放するには、まずディスク データ (ダーティ ページ) をディスクに書き込む必要があります。メモリマッピングで取得したファイルマッピングページは、次回アクセス時にも解放することができます ファイルから再読み込み - プログラムによって自動的に割り当てられたヒープメモリ(匿名)用メモリ管理のページで、このメモリを直接解放することはできませんが、Linux にはスワップ メカニズムが用意されています。頻繁にアクセスされないメモリはディスクに書き込まれてメモリが解放され、再度アクセスされたときにメモリをディスクから読み取ることができます。 スワップの原理
スワッピング アウト: プロセスが一時的に使用していないメモリ データをディスクに保存し、メモリを解放します。 スワッピング イン: プロセスが再度メモリにアクセスすると、これらはディスクからメモリに読み込まれます
#Linux はメモリ リソースが不足しているかどうかをどのように測定しますか?
ダイレクト メモリ リサイクル 新しい大きなブロック メモリ割り当て要求ですが、残りのメモリが不十分です。このとき、システムはメモリの一部を再利用します;
kswapd0 カーネル スレッドは定期的にメモリを再利用します。メモリ使用量を測定するために、pages_min、pages_low、pages_high の 3 つのしきい値が定義され、それらに基づいてメモリのリサイクル操作が実行されます。
残りのメモリ
pages_low < 剩余内存 < pages_high,内存有一定压力,但可以满足新内存请求
剩余内存 > pages_high,说明剩余内存较多,无内存压力
pages_low = pages_min 5 / 4 pages_high = pages_min 3 / 2
numactl --hardware #查看处理器在Node的分布情况,以及每个Node的内存使用情况
free #首先通过free查看swap使用情况,若swap=0表示未配置Swap #先创建并开启swap fallocate -l 8G /mnt/swapfile chmod 600 /mnt/swapfile mkswap /mnt/swapfile swapon /mnt/swapfile free #再次执行free确保Swap配置成功 dd if=/dev/sda1 of=/dev/null bs=1G count=2048 #模拟大文件读取 sar -r -S 1 #查看内存各个指标变化 -r内存 -S swap #根据结果可以看出,%memused在不断增长,剩余内存kbmemfress不断减少,缓冲区kbbuffers不断增大,由此可知剩余内存不断分配给了缓冲区 #一段时间之后,剩余内存很小,而缓冲区占用了大部分内存。此时Swap使用之间增大,缓冲区和剩余内存只在小范围波动 停下sar命令 cachetop5 #观察缓存 #可以看到dd进程读写只有50%的命中率,未命中数为4w+页,说明正式dd进程导致缓冲区使用升高 watch -d grep -A 15 ‘Normal’ /proc/zoneinfo #观察内存指标变化 #发现升级内存在一个小范围不停的波动,低于页低阈值时会突然增大到一个大于页高阈值的值
仮想メモリ: 最大 5 常駐メモリ: スワップ メモリと共有メモリを除く、プロセスによって実際に使用される物理メモリ 共有メモリ: 他のプロセスと共有されるメモリ、およびダイナミック リンク ライブラリやプログラムのコード セグメント さらに、パブリック アカウントのテクニカル コミュニティの背景を検索して、「」と返信してください。アルゴリズム」、サプライズギフトパッケージを入手してください。 スワップ メモリ: スワップを通じてメモリがディスクにスワップアウトされました
ページ フォールト例外
物理メモリから直接割り当てることができます。セカンダリ ページ フォールト例外 にはディスク IO 介入 (スワップなど)、プライマリ ページ フォールト例外が必要です。現時点では、メモリ アクセスが大幅に遅くなります
メモリ パフォーマンス ツール
さまざまなパフォーマンス指標に基づいて適切なツールを見つけてください:

メモリ分析ツールに含まれるパフォーマンス インジケーター:

メモリ パフォーマンスのボトルネックを迅速に分析する方法
通常は、まず、free、top、 vmstat 、 pidstat など
まず、free と top を使用してシステム全体のメモリ使用量を確認します。 次に、vmstat と pidstat を使用して、一定期間にわたる傾向を確認します。メモリ問題の種類を特定します。 - #最後に、メモリ割り当て分析、キャッシュ/バッファ分析、特定プロセスのメモリ使用量分析などの詳細な分析を実行します。
最好禁止Swap,若必须开启则尽量降低swappiness的值 减少内存的动态分配,如可以用内存池,HugePage等 尽量使用缓存和缓冲区来访问数据。如用堆栈明确声明内存空间来存储需要缓存的数据,或者用Redis外部缓存组件来优化数据的访问 cgroups等方式来限制进程的内存使用情况,确保系统内存不被异常进程耗尽 /proc/pid/oom_adj调整核心应用的oom_score,保证即使内存紧张核心应用也不会被OOM杀死
vmstat使用详解
vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。可以看到整个机器的CPU,内存,IO的使用情况,而不是单单看到各个进程的CPU使用率和内存使用率(使用场景不一样)。
vmstat 2 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 1379064 282244 11537528 0 0 3 104 0 0 3 0 97 0 0 0 0 0 1372716 282244 11537544 0 0 0 24 4893 8947 1 0 98 0 0 0 0 0 1373404 282248 11537544 0 0 0 96 5105 9278 2 0 98 0 0 0 0 0 1374168 282248 11537556 0 0 0 0 5001 9208 1 0 99 0 0 0 0 0 1376948 282248 11537564 0 0 0 80 5176 9388 2 0 98 0 0 0 0 0 1379356 282256 11537580 0 0 0 202 5474 9519 2 0 98 0 0 1 0 0 1368376 282256 11543696 0 0 0 0 5894 8940 12 0 88 0 0 1 0 0 1371936 282256 11539240 0 0 0 10554 6176 9481 14 1 85 1 0 1 0 0 1366184 282260 11542292 0 0 0 7456 6102 9983 7 1 91 0 0 1 0 0 1353040 282260 11556176 0 0 0 16924 7233 9578 18 1 80 1 0 0 0 0 1359432 282260 11549124 0 0 0 12576 5495 9271 7 0 92 1 0 0 0 0 1361744 282264 11549132 0 0 0 58 8606 15079 4 2 95 0 0 1 0 0 1367120 282264 11549140 0 0 0 2 5716 9205 8 0 92 0 0 0 0 0 1346580 282264 11562644 0 0 0 70 6416 9944 12 0 88 0 0 0 0 0 1359164 282264 11550108 0 0 0 2922 4941 8969 3 0 97 0 0 1 0 0 1353992 282264 11557044 0 0 0 0 6023 8917 15 0 84 0 0 # 结果说明 - r 表示运行队列(就是说多少个进程真的分配到CPU),我测试的服务器目前CPU比较空闲,没什么程序在跑,当这个值超过了CPU数目,就会出现CPU瓶颈了。这个也和top的负载有关系,一般负载超过了3就比较高,超过了5就高,超过了10就不正常了,服务器的状态很危险。top的负载类似每秒的运行队列。如果运行队列过大,表示你的CPU很繁忙,一般会造成CPU使用率很高。 - b 表示阻塞的进程,这个不多说,进程阻塞,大家懂的。 - swpd 虚拟内存已使用的大小,如果大于0,表示你的机器物理内存不足了,如果不是程序内存泄露的原因,那么你该升级内存了或者把耗内存的任务迁移到其他机器。 - free 空闲的物理内存的大小,我的机器内存总共8G,剩余3415M。 - buff Linux/Unix系统是用来存储,目录里面有什么内容,权限等的缓存,我本机大概占用300多M - cache cache直接用来记忆我们打开的文件,给文件做缓冲,我本机大概占用300多M(这里是Linux/Unix的聪明之处,把空闲的物理内存的一部分拿来做文件和目录的缓存,是为了提高 程序执行的性能,当程序使用内存时,buffer/cached会很快地被使用。) - si 每秒从磁盘读入虚拟内存的大小,如果这个值大于0,表示物理内存不够用或者内存泄露了,要查找耗内存进程解决掉。我的机器内存充裕,一切正常。 - so 每秒虚拟内存写入磁盘的大小,如果这个值大于0,同上。 - bi 块设备每秒接收的块数量,这里的块设备是指系统上所有的磁盘和其他块设备,默认块大小是1024byte,我本机上没什么IO操作,所以一直是0,但是我曾在处理拷贝大量数据(2-3T)的机器上看过可以达到140000/s,磁盘写入速度差不多140M每秒 - bo 块设备每秒发送的块数量,例如我们读取文件,bo就要大于0。bi和bo一般都要接近0,不然就是IO过于频繁,需要调整。 - in 每秒CPU的中断次数,包括时间中断 - cs 每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。 - us 用户CPU时间,我曾经在一个做加密解密很频繁的服务器上,可以看到us接近100,r运行队列达到80(机器在做压力测试,性能表现不佳)。 - sy 系统CPU时间,如果太高,表示系统调用时间长,例如是IO操作频繁。 - id 空闲CPU时间,一般来说,id + us + sy = 100,一般我认为id是空闲CPU使用率,us是用户CPU使用率,sy是系统CPU使用率。 - wt 等待IO CPU时间
pidstat 使用详解
pidstat主要用于监控全部或指定进程占用系统资源的情况,如CPU,内存、设备IO、任务切换、线程等。
Usage:
pidstat –d 間隔時間は各プロセスの IO 使用量をカウントします pidstat –u 間隔時間は各プロセスの CPU をカウントします統計情報 pidstat -r 間隔回数は各プロセスのメモリ使用量情報をカウントします pidstat -w 間隔回数は各プロセスのコンテキストをカウントしますSwitch p PID PID を指定
1. 統計 IO 使用状況
pidstat -d 1 10 03:02:02 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command 03:02:03 PM 0 816 0.00 918.81 0.00 jbd2/vda1-8 03:02:03 PM 0 1007 0.00 3.96 0.00 AliYunDun 03:02:03 PM 997 7326 0.00 1904.95 918.81 java 03:02:03 PM 997 8539 0.00 3.96 0.00 java 03:02:03 PM 0 16066 0.00 35.64 0.00 cmagent 03:02:03 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command 03:02:04 PM 0 816 0.00 1924.00 0.00 jbd2/vda1-8 03:02:04 PM 997 7326 0.00 11156.00 1888.00 java 03:02:04 PM 997 8539 0.00 4.00 0.00 java
UID PID kB_rd/s: 每秒进程从磁盘读取的数据量 KB 单位 read from disk each second KB kB_wr/s: 每秒进程向磁盘写的数据量 KB 单位 write to disk each second KB kB_ccwr/s: 每秒进程向磁盘写入,但是被取消的数据量,This may occur when the task truncates some dirty pagecache. iodelay: Block I/O delay, measured in clock ticks Command: 进程名 task name
2、统计CPU使用情况
# 统计CPU pidstat -u 1 10 03:03:33 PM UID PID %usr %system %guest %CPU CPU Command 03:03:34 PM 0 2321 3.96 0.00 0.00 3.96 0 ansible 03:03:34 PM 0 7110 0.00 0.99 0.00 0.99 4 pidstat 03:03:34 PM 997 8539 0.99 0.00 0.00 0.99 5 java 03:03:34 PM 984 15517 0.99 0.00 0.00 0.99 5 java 03:03:34 PM 0 24406 0.99 0.00 0.00 0.99 5 java 03:03:34 PM 0 32158 3.96 0.00 0.00 3.96 2 ansible
UID PID %usr: 进程在用户空间占用 cpu 的百分比 %system: 进程在内核空间占用 CPU 百分比 %guest: 进程在虚拟机占用 CPU 百分比 %wait: 进程等待运行的百分比 %CPU: 进程占用 CPU 百分比 CPU: 处理进程的 CPU 编号 Command: 进程名
3、统计内存使用情况
# 统计内存 pidstat -r 1 10 Average: UID PID minflt/s majflt/s VSZ RSS %MEM Command Average: 0 1 0.20 0.00 191256 3064 0.01 systemd Average: 0 1007 1.30 0.00 143256 22720 0.07 AliYunDun Average: 0 6642 0.10 0.00 6301904 107680 0.33 java Average: 997 7326 10.89 0.00 13468904 8395848 26.04 java Average: 0 7795 348.15 0.00 108376 1233 0.00 pidstat Average: 997 8539 0.50 0.00 8242256 2062228 6.40 java Average: 987 9518 0.20 0.00 6300944 1242924 3.85 java Average: 0 10280 3.70 0.00 807372 8344 0.03 aliyun-service Average: 984 15517 0.40 0.00 6386464 1464572 4.54 java Average: 0 16066 236.46 0.00 2678332 71020 0.22 cmagent Average: 995 20955 0.30 0.00 6312520 1408040 4.37 java Average: 995 20956 0.20 0.00 6093764 1505028 4.67 java Average: 0 23936 0.10 0.00 5302416 110804 0.34 java Average: 0 24406 0.70 0.00 10211672 2361304 7.32 java Average: 0 26870 1.40 0.00 1470212 36084 0.11 promtail
UID PID Minflt/s : 每秒次缺页错误次数 (minor page faults),虚拟内存地址映射成物理内存地址产生的 page fault 次数 Majflt/s : 每秒主缺页错误次数 (major page faults), 虚拟内存地址映射成物理内存地址时,相应 page 在 swap 中 VSZ virtual memory usage : 该进程使用的虚拟内存 KB 单位 RSS : 该进程使用的物理内存 KB 单位 %MEM : 内存使用率 Command : 该进程的命令 task name
4、查看具体进程使用情况
pidstat -T ALL -r -p 20955 1 10 03:12:16 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command 03:12:17 PM 995 20955 0.00 0.00 6312520 1408040 4.37 java 03:12:16 PM UID PID minflt-nr majflt-nr Command 03:12:17 PM 995 20955 0 0 java
以上がLinuxパフォーマンス最適化のナレッジポイントまとめ・実践+集編の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Apacheを開始する手順は次のとおりです。Apache(コマンド:sudo apt-get install apache2または公式Webサイトからダウンロード)をインストールします(linux:linux:sudo systemctl start apache2; windows:apache2.4 "serviceを右クリックして「開始」を右クリック) (オプション、Linux:Sudo SystemCtl

Apache 80ポートが占有されている場合、ソリューションは次のとおりです。ポートを占有するプロセスを見つけて閉じます。ファイアウォールの設定を確認して、Apacheがブロックされていないことを確認してください。上記の方法が機能しない場合は、Apacheを再構成して別のポートを使用してください。 Apacheサービスを再起動します。

Apacheサーバーを再起動するには、次の手順に従ってください。Linux/MacOS:sudo systemctl restart apache2を実行します。 Windows:Net Stop apache2.4を実行し、ネット開始apache2.4を実行します。 Netstat -A |を実行しますサーバーのステータスを確認するには、STR 80を見つけます。

Apacheは、次の理由で起動できません。構成ファイル構文エラー。他のアプリケーションポートとの競合。権限の問題。メモリから。デッドロックを処理します。デーモン障害。 Selinux許可の問題。ファイアウォールの問題。ソフトウェアの競合。

このガイドでは、Debian SystemsでSyslogの使用方法を学ぶように導きます。 Syslogは、ロギングシステムとアプリケーションログメッセージのLinuxシステムの重要なサービスです。管理者がシステムアクティビティを監視および分析して、問題を迅速に特定および解決するのに役立ちます。 1. syslogの基本的な知識Syslogのコア関数には以下が含まれます。複数のログ出力形式とターゲットの場所(ファイルやネットワークなど)をサポートします。リアルタイムのログ表示およびフィルタリング機能を提供します。 2。syslog(rsyslogを使用)をインストールして構成するDebianシステムは、デフォルトでrsyslogを使用します。次のコマンドでインストールできます:sudoaptupdatesud

インターネットは単一のオペレーティングシステムに依存していませんが、Linuxはその上で重要な役割を果たしています。 Linuxは、サーバーやネットワークデバイスで広く使用されており、安定性、セキュリティ、スケーラビリティに人気があります。

Apacheの脆弱性を修正する手順は次のとおりです。1。影響を受けるバージョンを決定します。 2。セキュリティの更新を適用します。 3。Apacheを再起動します。 4.修正を確認します。 5.セキュリティ機能を有効にします。

Linuxでnginxを開始する手順:nginxがインストールされているかどうかを確認します。 systemctlを使用して、nginxを開始してnginxサービスを開始します。 SystemCTLを使用して、NGINXがシステムスタートアップでNGINXの自動起動を有効にすることができます。 SystemCTLステータスNGINXを使用して、スタートアップが成功していることを確認します。 Webブラウザのhttp:// localhostにアクセスして、デフォルトのウェルカムページを表示します。
