インフラエンジニアのLinux負荷調査

はじめに

負荷調査をすることがあり調べることがあったので、備忘録的な記録。 基本的にはCPU,メモリ,ディスクIOに負荷がかかっているのでその切り分けをします。

sarコマンドのインストール

sarコマンドは負荷調査時に便利なのでインストールしておきます。

yum install sysstat
systemctl start sysstat.service

デフォルトで10分単位の計測なので1分単位に変更します。

cat /etc/cron.d/sysstat

Run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 1 1
↓
*/1 * * * * root /usr/lib64/sa/sa1 1 1

sarコマンドで調査していきます。

sar

07:31:01        CPU     %user     %nice   %system   %iowait    %steal     %idle
07:32:01        all      0.04      0.00      0.11      0.00      0.00     99.85
説明
%user ユーザプロセスがCPUを使用している割合
%nice 優先度(nice値)を変更したユーザプロセスがCPUを使用している割合
%system システムプロセスがCPUを使用している割合
%iowait I/OによるCPUの処理待ちになっている割合
%steal 仮想マシンがCPU割り当て要求を行って割り当てられなかった時間の割合(他の仮想マシンとのリソースの取り合い)
%idle CPUが割り当てられず待機していた割合(iowaitを除く)

マルチコアのCPUの場合にCPUごとに確認したい場合は以下のコマンドを使用

sar -P ALL

負荷の観点

%userが高い

  • CPUがボトルネックの可能性が高い
  • ps auxコマンドなどで%CPUが高いプロセスを特定する

対策

対象プロセスの処理アルゴリズムの見直し。CPUの増強

%systemが高い

  • 後述のI/O待ちの場合、read(),write()も時間がかかり一緒に高くなることが多い
  • 頻繁にプロセスをforkしているなど

%iowaitが高い

  • ディスクIOが処理不足の時に発生
  • メモリ不足によりSwapが発生してディクスIOの逼迫もありえる。sar -W,freeコマンドでSwapの発生を確認する。

対策

Swapが発生している場合はメモリ不足。 実メモリが空いていてSwapにたまり続けている場合は以下のコマンドで解消可能。実メモリが不足している場合エラーになります。

swapoff -a && swapon -a

メモリの調査

Memを溢れるた時にSwap(HDD領域)を使用します。 cache領域は新規に割り当てが必要な場合は解放されますので、使用可能なメモリ領域はavailable(free+buff/cache)になります。

free -h
              total        used        free      shared  buff/cache   available
Mem:           615M         73M        357M        8.6M        184M        435M
Swap:          999M          0B        999M
説明
total システムで使用できる最大メモリ容量
used 使用中のメモリ容量
free 割り当てられていないメモリ容量
shared 共有メモリに割り当てられたメモリ容量
buff/cache キャッシュとして利用しているメモリ容量(buffはバッファキャッシュ(ブロックデバイス用)。cacheはページキャッシュ(ファイル用))
available 割り当て可能なメモリ容量(free+buff/cache)
ps aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      7882  0.0  0.0   7256   148 pts/0    S    17:40   0:00 stress -m 1 --vm-bytes 1342177280 --vm-hang 0 -q
root      7883 23.2 76.9 1317980 484824 pts/0  S    17:40   0:07 stress -m 1 --vm-bytes 1342177280 --vm-hang 0 -q
説明
%MEM プロセスが使用しているメモリ割合
VSZ プロセスが使用している仮想メモリ
RSS プロセスが使用している物理メモリ

VSZとRSSの違い

プロセスが起動するとVSZ(仮想メモリ)を確保します。readであればRSS(物理メモリ)を使用しませんが、write処理が発生した時にRSS(物理メモリ)を確保します。 プログラム上でメモリが解放されたら確保したメモリ領域を解放します。

%iowaitの調査

sar -dp

14:16:01          DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
14:17:02          sda      0.18      0.00      1.07      5.82      0.00      0.91      0.91      0.02
14:17:02    centos-root      0.13      0.00      1.07      8.00      0.00      1.25      1.25      0.02
14:17:02    centos-swap      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
説明
tps I/Oリクエスト数(1秒あたり)
rd_sec/s 読み込みセクタ数(1秒あたり)(1セクタ512バイト)
wr_sec/s 1秒間の書き込みセクタ数(1秒あたり)(1セクタ512バイト)
avgrq-sz IOリクエストの平均セクタサイズ
avgqu-sz IOリクエストの待ち行列の平均セクタサイズ
await ユーザプロセスからカーネル経由してデバイスへのIOリクエストの平均待ち時間(単位msec)
svctm カーネルから物理ストレージへのIOリクエストの平均処理時間(単位msec)
%util デバイスへのIOリクエスト中のCPU使用率(ここが継続的に高いとディスク部分でボトルネックになっている可能性が高い)

awaitとsvctmの関係

誤字

画像中のatimeはawaitの誤字です。

awaitとsvctmの関係は基本的にawait(カーネル処理時間+svctm)となります。 sarの情報取得間隔でズレが生じることはあります。

await >>>>> svctmの場合

awaitにかなり時間を要していて、svctmが短い場合は物理ストレージに余裕があります。 OS側でのカーネル処理が追いついていません。

対策としては、ファイルシステムを増やしてカーネル処理を並列にします。 論理ボリュームを増やしたり、OS側でファイルシステムを分けるとかなり効果があります。

await>=svctmの場合

次はsvctmで処理時間がかかっている場合です。 OS側は処理できているのですが、物理ストレージ側で処理が追いついておらず、ユーザプロセスからは待ち時間が発生しています。

この場合対策は物理ストレージの増設、不要なアクセスの停止、FC,SAS接続の増設となります。 あまり有効的な対策が取りづらい状況です。 FC,SASの速度計測、ストレージのIOPSなど切り分けをしていく必要があります。

プロセスごとの読み書き容量

プロセス単位で読み書きが発生しているプロセスを特定します。


pidstat -dhIl <秒数>
      Time   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
説明
kB_rd/s 読み出し量KB(1秒あたり)
kB_wr/s 書き込み量KB(1秒あたり)
kB_ccwr/s キャンセルされた書き込み量KB(1秒あたり)
iodelay ioの遅延(pidstatバージョン10.2.1以降のみ)

ネットワークの速度

切り分けとしてネットワークの使用容量もOS側から確認できます。 ここが逼迫しているとiowaitが発生します。

sar -n DEV

16:38:01        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
説明
rxpck/s 受信パケット数(1秒あたり)
txpck/s 送信パケット数(1秒あたり)
rxkB/s 受信バイト数(1秒あたり)
txkB/s 送信バイト数(1秒あたり)
rxcmp/s 圧縮受信パケット数(1秒あたり)
txcmp/s 圧縮送信パケット数(1秒あたり)
rxmcst/s マルチキャスト受信パケット数(1秒あたり)

さいごに

ざっくりですが、こんな感じで調査をします。 CPU、メモリ、カーネル、ネットワーク、物理ストレージかの切り分けはできそうです。 各詳細の調査はstraceコマンドなどシステムコールレベルでの調査などになっていくかと思います。