TT Lab
はじめる
学ぶ 学習パス コース

CPU・メモリリークの見極め

遅いという報告を割る

TT Labで続きを見る

目標

「サーバーが遅い」を、CPU・メモリ・I/Oのどれなのかに切り分けます。数字を自分で読み、リークなのかキャッシュなのかを、傾きで見分けます。

なぜ重要なのか

遅いという報告への最もよくある対応は、「スペックを上げよう」です。ところが、D状態のプロセスが20個あってloadが20になっているマシンにCPUを増やしても、何も起きません。症状と原因をつなぐ数字を探すことが、このラボのすべてです。

この環境の制約が、そのまま訓練です

このPodはカーネルの権限がすべて取り除かれているので、perf・strace・bpftraceを使えません。代わりに、/procと/sys/fs/cgroupを直接読みます。それはそれらのツールが内部でしていることで、ツールをインストールできない顧客企業のサーバーで、実際にすることになることでもあります。

ステップ

  1. 60秒で分類する → /root/perf/01-triage.txt
  2. /proc/statを2回読んで、CPU使用率を計算する → /root/perf/02-cpu.txt
  3. CPU 1位のプロセス → /root/perf/03-top.txt
  4. RSS・PSS・Private_Dirty → /root/perf/04-mem.txt
  5. リークを作って、傾きで確認する → /root/perf/05-slope.txt
  6. cgroupの上限 → /root/perf/06-cgroup.txt
  7. anonとfileを分ける → /root/perf/07-split.txt
  8. 結論3行 → /root/perf/08-verdict.md

参考

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行目は次に確認することです。数字のない結論は推測です。