発展LESSON 05
この教材で学ぶこと CPU・メモリ・I/Oのボトルネックを体系的に特定します。Linux パフォーマンスチューニング
前提知識: Linux の基本操作。本教材ではボトルネックの特定手順と対策を扱います。
1. パフォーマンス調査の進め方(USE メソッド)
USE(Utilization・Saturation・Errors)メソッド
各リソースについて:
U: 使用率(何%使っているか)
S: 飽和度(キューや待ちが発生しているか)
E: エラー数(エラーが発生しているか)
対象リソース:
├── CPU
├── メモリ
├── ディスク I/O
└── ネットワーク
2. CPU ボトルネックの特定
# CPU 使用率の確認
top -bn1 | grep "Cpu(s)"
# %us=ユーザー, %sy=カーネル, %wa=I/O待ち, %si=ソフト割り込み
# I/O 待ちが高い(%wa > 10%)→ ディスク/ネットワーク I/O が問題
# %sy が高い → カーネル処理が多い(コンテキストスイッチ等)
# ロードアベレージ確認
uptime
# 例: load average: 4.0, 3.5, 3.0
# → CPU コア数を超えていると飽和状態
# コンテキストスイッチ数(高すぎると問題)
vmstat 1 10
# cs(context switches)列を確認
# CPU プロファイリング(どの関数が重いか)
perf top -p $(pgrep myapp)
3. メモリ不足の特定
# メモリ使用状況
free -h
# available が少ない(全体の10%以下)→ 危険
# プロセス別メモリ使用量
ps aux --sort=-%rss | head -11
# RSS(実メモリ使用量), VSZ(仮想メモリ)
# OOM Killer の発動確認
dmesg | grep -i "oom\|killed"
journalctl -k | grep -i oom
# メモリリーク調査(時系列で増加しているプロセス)
watch -n 5 'ps aux --sort=-%mem | head -5'
# スワップの使用状況
vmstat 1 | awk '{print $7, $8}' # si=スワップイン, so=スワップアウト
# so > 0 が続く → メモリ不足でスワップ中
# 大量のメモリを消費しているページキャッシュを確認
cat /proc/meminfo | grep -E "Buffers|Cached|SwapTotal|SwapFree"
4. ディスク I/O ボトルネック
# I/O 統計(iostat)
iostat -x 1 5
# 重要な列:
# %util: ディスク使用率(100%→飽和)
# await: I/O待ち時間(ミリ秒)
# r/s, w/s: 読み書き回数/秒
# I/O を発生させているプロセスを特定
iotop -ao -n 10
# -a: 累積、-o: I/O 発生中のプロセスのみ、-n 10: 10回サンプル
# ファイルシステム別の I/O
df -h && iostat -xz 1
# ファイルに対するアクセスを監視
inotifywait -m /var/log/app/ -e modify,create
# ディスクの read/write 速度計測(ベースライン確認)
dd if=/dev/zero of=/tmp/test bs=1M count=1024 oflag=direct
dd if=/tmp/test of=/dev/null bs=1M iflag=direct
rm /tmp/test
5. ネットワーク I/O ボトルネック
# 帯域使用量(iftop or nethogs)
iftop -n -N -i eth0 # インターフェース別
nethogs eth0 # プロセス別
# ネットワーク統計
ss -s # ソケット統計サマリ
ss -tn | awk '{print $1}' | sort | uniq -c # ステータス別カウント
# TCP 再送信(ネットワーク品質の問題)
ss -tin | grep retrans
netstat -s | grep -i retransmit
# 接続数が上限に達していないか
cat /proc/sys/net/core/somaxconn
ss -tnlp | grep :8080 | awk '{print $2}' # Recv-Q が多い → バックログ溢れ
6. プロファイリングツール
# strace — システムコールのトレース(本番では慎重に)
strace -p $(pgrep myapp) -c # サマリモード(-c)は比較的安全
strace -p $(pgrep myapp) -e trace=network # ネットワーク系のみ
# lsof — プロセスが開いているファイル・ソケット
lsof -p $(pgrep myapp) | wc -l # FD 数の確認
lsof -p $(pgrep myapp) -i # ネットワーク接続のみ
# tcpdump — パケットキャプチャ
tcpdump -i eth0 -n "host 10.0.1.100 and port 5432" -w /tmp/db.pcap
# → Wireshark で解析
# BPF/eBPF(Linux 5.x 以降、本番でも安全)
bpftrace -e 'tracepoint:syscalls:sys_enter_read { @[comm] = count(); }'
7. チューニングのまとめ(設定値一覧)
# 確認・変更するカーネルパラメータ
sysctl -a | grep -E "
net.core.somaxconn| # TCPバックログキュー
net.ipv4.tcp_max_syn_backlog| # SYNバックログ
net.core.netdev_max_backlog| # パケットキュー
vm.swappiness| # スワップ閾値(10推奨)
vm.dirty_ratio| # メモリへの書き込みキャッシュ上限
fs.file-max" # システム全体のFD上限
# プロセスのファイルディスクリプタ上限
ulimit -n # 現在のプロセスの上限(通常1024)
# /etc/security/limits.conf で永続化
echo "myapp soft nofile 65536" >> /etc/security/limits.conf
echo "myapp hard nofile 65536" >> /etc/security/limits.conf
🔗 次のステップ
- ../Networking/01_TCP_IP詳解.md — ネットワーク調査の詳細
- ../../06_DevOps/Docker/01_Docker実践.md — コンテナでのリソース制限(cgroup)