遅いという報告を割る
目標
「サーバーが遅い」を、CPU・メモリ・I/Oのどれなのかに切り分けます。数字を自分で読み、リークなのかキャッシュなのかを、傾きで見分けます。
なぜ重要なのか
遅いという報告への最もよくある対応は、「スペックを上げよう」です。ところが、D状態のプロセスが20個あってloadが20になっているマシンにCPUを増やしても、何も起きません。症状と原因をつなぐ数字を探すことが、このラボのすべてです。
この環境の制約が、そのまま訓練です
このPodはカーネルの権限がすべて取り除かれているので、perf・strace・bpftraceを使えません。代わりに、/procと/sys/fs/cgroupを直接読みます。それはそれらのツールが内部でしていることで、ツールをインストールできない顧客企業のサーバーで、実際にすることになることでもあります。
ステップ
- 60秒で分類する →
/root/perf/01-triage.txt /proc/statを2回読んで、CPU使用率を計算する →/root/perf/02-cpu.txt- CPU 1位のプロセス →
/root/perf/03-top.txt - RSS・PSS・Private_Dirty →
/root/perf/04-mem.txt - リークを作って、傾きで確認する →
/root/perf/05-slope.txt - cgroupの上限 →
/root/perf/06-cgroup.txt - anonとfileを分ける →
/root/perf/07-split.txt - 結論3行 →
/root/perf/08-verdict.md
参考
topの%CPUが100を超えても正常です。コア1つが基準だからです。freeで見る値は、freeではなくavailableです。- 複数のプロセスのメモリを合計するときは、RSSではなくPSSを使います。
60秒で分類する
60秒で分類する → /root/perf/01-triage.txt
/root/perf/01-triage.txtに4行を書きます。loadavgの3つの数字 / プロセスの状態別の個数(R,D,S) / コア数 / availableメモリ。コマンドはcat /proc/loadavg、ps -eo state --no-headers | sort | uniq -c、nproc、free -mです。何を見るかを決めるステップです。
CPU使用率を手で計算する
/proc/statを2回読んで、CPU使用率を計算する → /root/perf/02-cpu.txt
/proc/statのcpu の行を1秒間隔で2回読んで使用率を求め、/root/perf/02-cpu.txtに数字だけを書いてください(0–100)。busy=user+nice+system+irq+softirq+steal、idle=idle+iowaitです。topがしている計算が、これです。
誰がCPUを使っているかを探す
CPU 1位のプロセス → /root/perf/03-top.txt
ps -eo pid,pcpu,comm --sort=-pcpu | headで、1位のプロセスの名前を、/root/perf/03-top.txtに1行で書きます。負荷がなければ、python3 -c 'while True: pass' &で1つ作っておいて、見てください。
RSS・PSS・Private_Dirtyを区別する
RSS・PSS・Private_Dirty → /root/perf/04-mem.txt
任意のプロセスを1つ選んで、grep -E '^(Rss|Pss|Private_Dirty):' /proc/<PID>/smaps_rollupの結果を、/root/perf/04-mem.txtにそのまま保存してください。3行がすべてある必要があります。
リークを作って傾きで捉える
リークを作って、傾きで確認する → /root/perf/05-slope.txt
わざと漏らすプログラムを動かします。python3 -c "import time;L=[];\nwhile True: L.append(bytearray(1024*1024)); time.sleep(0.2)" &のような形です。そのPIDのPrivate_Dirtyを5秒間隔で4回記録して、/root/perf/05-slope.txtに1行ずつ保存してください。値が単調に増加している必要があります。
コンテナの本当の上限を見る
cgroupの上限 → /root/perf/06-cgroup.txt
/root/perf/06-cgroup.txtに、memory.max、memory.current、cpu.maxの3つの値を書きます。cgroup v2は/sys/fs/cgroup/の直下にあります。hostのfreeとは違う数字だということが、核心です。
ヒープかキャッシュか
anonとfileを分ける → /root/perf/07-split.txt
grep -E '^(anon|file) ' /sys/fs/cgroup/memory.statを、/root/perf/07-split.txtに保存してください。memory.currentが上限に達しても、大部分がfileならキャッシュなので回収可能で、anonなら本当の圧迫です。
結論を3行で
結論3行 → /root/perf/08-verdict.md
/root/perf/08-verdict.mdに3行を書きます。1行目は症状がCPUなのか、メモリなのか、I/Oなのか、2行目はそう判断した根拠の数字、3行目は次に確認することです。数字のない結論は推測です。