発展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

🔗 次のステップ