サーバーの負荷状態を調査する(vmstat,free,top,proc)

レンタルサーバーでもWebサーバーでも日々運用していると、急にレスポンスが悪くなったり、タイムアウトしたりでページの閲覧が遅く(重く)なったりします。

今回は、サーバーの負荷状態について調査する方法を解説します。

原因の仮説を立てられるようになると素早く対応することもできます。

サーバーの負荷状態の調査方法

「何が原因で処理が遅延しているのか?」

まずは切り分けをする必要があります。

大雑把にカテゴリ分けをしてみました。

サーバーの負荷状態の調査方法

上図ですが以下のようにカテゴライズできます。

  • ネットワークの遅延
  • アプリの不具合
  • CPUの処理能力が低い
  • メモリ&ディスクのI/Oの遅延

 

原因が分かれば対処ができます。

例えば「メモリを増設する」「ディスクをSSDに変更してみる」「CPUを高性能なものに変える」など具体的な対処ができます。

その原因の特定を以下のコマンドで見つけていきます。

 

ロードアベレージ(Load Average)

まずはロードアベレージで「システム全体の負荷状況」を見ます。

ただしロードアベレージだけで「ボトルネックの原因」は分かりません。

本当にサーバーに負荷が掛かっているのか?それともネットワークなど外的要因なのか?ロードアベレージを確認してあたりをつけます。

 

ロードアベレージは低いがシステムは遅い場合

サーバーに原因はなく、「ソフトウェア」「ネットワーク」「リモートホスト」の原因を疑います。

 

ロードアベレージが高くシステムが遅い場合

「CPU」「I/O」か切り分けをします。

 

topコマンドを実行する

まずは top コマンドを実行します。

オプション、引数なしで top コマンドを実行します。

コマンドを実行すると、実行中のプロセスで CPU の負荷が大きいものから順に表示され、情報は自動的に更新されます。

初期設定では 5秒ごとに表示が更新されますが、[SPACE] キーを押下することにより表示を更新することができます。

表示を終了するには [q] または [Ctrl] + [c] を押してください。

top - 20:39:08 up 33 days, 23:48,  1 user,  load average: 0.01, 0.04, 0.05
Tasks: 111 total,   2 running, 109 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   500452 total,    17196 free,   185996 used,   21 297260 buff/cache
22 KiB Swap:  4194300 total,  23 4070152 free,   24 124148 used.   25 246412 avail Mem

 

  26  27           28  29   30        31      32   33   34      35           36       37
  PID USER      PR  NI    VIRT    RES    SHR  S   %CPU %MEM     TIME+ COMMAND
28684 root      20   0       0      0      0 S  0.3  0.0   0:00.16 kworker/0:1
28688 masato    20   0  157716   2224   1536 R  0.3  0.4   0:00.07 top
    1 root      20   0  125196   3048   1912 S  0.0  0.6   4:46.86 systemd
    2 root      20   0       0      0      0 S  0.0  0.0   0:01.12 kthreadd
    3 root      20   0       0      0      0 S  0.0  0.0   0:07.18 ksoftirqd/0
    7 root      rt   0       0      0      0 S  0.0  0.0   0:00.00 migration/0
    8 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcu_bh
    9 root      20   0       0      0      0 R  0.0  0.0   0:24.83 rcu_sched
   10 root      rt   0       0      0      0 S  0.0  0.0   0:26.67 watchdog/0
   12 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kdevtmpfs
   13 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 netns
   14 root      20   0       0      0      0 S  0.0  0.0   0:05.45 khungtaskd
   15 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 writeback
   16 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kintegrityd
   17 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 bioset
   18 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kblockd
   19 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 md
   28 root      20   0       0      0      0 S  0.0  0.0   0:02.36 kswapd0
   29 root      25   5       0      0      0 S  0.0  0.0   0:00.00 ksmd
   30 root      20   0       0      0      0 S  0.0  0.0   0:00.04 fsnotify_mark

 

①topコマンドが実行された時刻(up 33daysは33日間システムが起動しているということ)

②稼働時間(コマンド実行からの表示時問)

③ログインユーザ数

④実行待ちジョブ(プロセス)の平均数(直前1分間/直前5分問/直前15分間の平均数)

この数値が多いということは、何かが原因で実行を待たされているプロセスが多いということです。

その原因は「予想1.他のプロセスにCPUが取られている」「予想2.I/Oが遅くて待たされている」などが考えられます。

※1CPUでロードアベレージ1と、4CPUでロードアベレージ4は論理的には同じ負荷。つまり、きっちりリソースを使っている(100%)ということになる。CPUの1コア数に対する数値であることに注意。

※プロセス、タスク、ジョブ様々な呼び方がある。

⑤Tasks プロセス総数

⑥running 稼働プロセス数

⑦sleeping 待機プロセス数

⑧stopped 停止プロセス数

⑨zombie ゾンビプロセス数

⑩us ユーザに費やされたCPU時間の比率

Time spent in user space

⑪sy systemプログラムによる使用率

Time spent in kernel space

⑫ni 優先プロセスに費やされたCPU時間の比率

Time spent on low priority processes

⑬id 持機となっているCPU時間の比率

Time spent in idle operations

⑭wa I/O 処理の完了を待っていた時間

wa: is meaning of "iowait" 

Time spent on waiting on IO peripherals (eg. disk)

⑮hi ハードウェア割込み要求処理に費やされたCPU 時間

Time spent handling hardware interrupt routines

⑯si ソフトウェア割込み要求処理に費やされたCPU 時間

Time spent handling software interrupt routines

⑰st タイムスタンプを使用したカーネル内のsoftirqタイム処理に費やされたCPU時間の比率

Time in spent on involuntary waits by virtual cpu while hypervisor is servicing another processor (stolen from a virtual machine)

⑱total 全メモリ容量(単位:キロバイト)

⑲free 使用中のメモリ容量(単位:キロバイト)

⑳used 空きメモリ容量(単位:キロバイト)

21 buff/cache バッファメモリ容量(単位:キロバイト)

22 Swap 全スワップメモリ容量(単位:キロバイト)

23 free 使用中スワップメモリ容量(単位:キロバイト)

24 used 空きスワップメモリ容量(単位:キロバイト)

25 avail Mem キャッシュメモリ容量(単位:キロバイト)

26 PlD  プロセス番号

27 USER  プロセス実行ユーザ名

28 PR  プロセスの優先順位

29 NI  プロセスの実行優先度(ナイス値)

30 VIRT(SIZE)  タスクコード、データ、スタックスペースのサイズ

31 RSS(RES)  プロセスの物理メモリ使用量(単位:キロバイト)

32 SHR (SHARE)  プロセスの共有メモリ使用量(単位:キロバイト)

33 S(TAT)  プロセスのステータスを表示

  S 停止状態(スリープ中)

  D 継続停止状態(割り込み不可能なスリープ中)

  P 稼働状態(実行中)

  Z ゾンビ状態(ゾンビブロセス)

  T 停止またはトレース状態

  < ナイス値が - で実行中(負のナイス値を持つプロセス)

  N ナイス値が + で実行中(正のナイス値をもつプロセス)

  W スワップアウト状態(カーネルプロセスに対しては正しく動作しない)

  LIB 共有ライブラリが使用するページサイズ

34 %CPU  CPU占有率(表示が更新されてからタスクがCPUを占有していた割合)を表示

35 %MEM  実メモリ占有率(表示が更新されてから物理メモリを占有していた割合)を表示

36 TIME+(TIME)  プロセス開始からの経過時間(単位:秒)を表示

37 COMMAND  実行コマンド名を表示

 

ロードアベレージの見方

man uptime コマンドの抜粋です。

現在時刻、システム起動からの時間、システム上にいるユーザ数、および直近1、5、15分間の実行キューに存在するジョブの平均数を表示します。

割り込み不可のスリープ状態にあるプロセス数も平均負荷率に数えられます。
FILE を指定しない場合、/var/run/utmp    が使用されます。   

FILE としては   /var/log/wtmp が一般的です。

 

日本語だと説明が端折りすぎなので英語で「man uptime」の結果を表示させます。

DESCRIPTION
uptime gives a one line display of the following information.  The current time, how long the system has been running, how many users are currently logged on, and the system load averages for the past 1, 5, and 15 minutes.

This is the same information contained in the header line displayed by w(1).

System load averages is the average number of processes that are either in a runnable  or  uninterruptable  state.  

A process  in a runnable state is either using the CPU or waiting to use the CPU. 

A process in uninterruptable state is waiting for some I/O access, eg waiting for disk. 

The averages are taken over the three time intervals.  

Load  averages are not normalized for the number of CPUs in a system, so a load average of 1 means a single CPU system is loaded all the time while on a 4 CPU system it means it was idle 75% of the time.

緑色の部分ですが、負荷平均はシステム内のCPU数に対して正規化されていないため、1つのCPUでロードアベレージが1の場合は、常にプロセスがCPUにロードされることを意味し、4CPUでロードアベレージが1の場合は、75%のアイドル時間を意味します。と読めます。

つまり、ロードアベレージの数値は「1つのCPU」に対するロードアベレージを表しています。

だから、CPUが4コアでロードアベレージが4だとしても、直ちに「ロードアベレージが高い」とは言えません。

 

man top

manコマンドでtopコマンドの勉強をします。

TOP(1)                                                                                                    Linux User's Manual                                                                                                    TOP(1)

名前
       top - Linux のタスクを表示する

書式
        -hv | -bcisS -d delay -n iterations -p pid [, pid ...]

       昔からのスイッチ '-' と空白の指定は任意である。

説明
         プログラムは稼働中のシステムの動的なリアルタイムの概要を報告する。      

   Linuxカーネルが現在管理しているタスクの一覧だけでなく、システムの概要情報も表示できる。     

   表示されるシステムの概要情報のタイプと各タスクについて表示される情報のタイプ・順序・サイズは、 ユーザーが全て設定可能で、その設定は次に起動したときにも保存できる。

         このプログラムはプロセスの操作に関する限定された対話型インタフェースだけでなく、個人用の設定についての特に拡張されたインタフェースも提供している。   

    --    操作の全ての面についての包括的なインタフェースを提供している。
         このプログラムは、この文書を通して .ie 0 . br という名前で呼ばれているが、 希望する任意の名前にすることができる。

   新しい名前 (エイリアスでもよい) は、top の表示に反映され、 設定ファイルを読み書きの際に使用される。

概要
   ドキュメント
       これ以降の目次
           1. コマンドラインオプション
           2. フィールド / カラム
              a. フィールドの説明
              b. カラムの選択と順序指定
           3. 対話的コマンド
              a. グローバルなコマンド
              b. サマリーエリアのコマンド
              c. タスクエリアのコマンド
              d. カラーマップ
           4. 別形式の表示モード
              a. ウィンドウの概要
              b. ウィンドウのコマンド
           5. ファイル
              a. システム設定ファイル
              b. 個人設定ファイル
           6. くだらないトリックの例
              a. カーネルのトリック
              b. バウンドするウィンドウ
              c. 大きな雛鳥のようなウィンドウ
           7. バグ, 8. 以前の top の履歴, 9. 著者, 10. 関連項目

   操作
      top を操作するときの最も重要な 2 つのキーは、 ヘルプ ('h' または '?') と終了 ('q') キーである。

  終了させるときには、代わりとして、 単純に昔からの割り込みキー ('^C') を使うこともできる。

      最初に top を起動する場合、 昔からの以下のスクリーンの要素が表示される:

  1) サマリーエリア;

  2) メッセージ/プロンプト行

  3) カラムヘッダ;

  4) タスクエリア。

  しかし、以前の top と比較すると、いくつかの違いがある。

       ハイライト
         サマリーエリア: 負荷 (load) / 稼働時間 (uptime) の値はハイライトされず、 その他の要素の値のみがハイライトされる。

         タスクエリア: 実行中 (または実行の準備がされている) のタスクがハイライトされる。

   これらのプロセスを強調する唯一の手段は太字で表示することである。

        内容/ラベル
         サマリーエリア: プログラム名が表示される。

   シンボリックリンク名またはエイリアスが表示される場合もある。

   Cpu(s) 状態ラベルは他のものが表示される可能性を暗に示している。

   メモリ統計では小文字 'k' が使用される。

         カラムヘッダ: 新しいフィールドといくつかの変更されたラベルが表示される。

   top をカスタマイズすれば新しいフィールドが更に表示される。

         注意: top の表示は 512 文字に制限される。

   全てのフィールドを表示するためには最低 160 文字が必要である。

   残りの幅は 'Command' カラムに使用できる。

   起動時のデフォルト値
      以下の起動時のデフォルトは、設定ファイルの使用を仮定していないので、 ユーザーはカスタマイズできない。

  しかし、アスタリスク ('*') の付いたコマンドはコマンドラインで上書きできる。

           全体のデフォルト
              'A' - 別形式表示       Off (全画面)
            * 'd' - 遅延時間         3.0 秒
              'I' - Irix モード      On  ('solaris' smp ではない)
            * 'p' - PID の監視       Off
            * 's' - セキュアモード     Off (非セキュアモード)
              'B' - 太字表示         Off

 

           サマリーエリアのデフォルト
              'l' - 負荷平均/稼働時間      On  (プログラム名が表示される)
              't' - タスク/Cpu 統計        On  (1+1 行。'1' を参照)
              'm' - メモリ/スワップ使用量  On  (2 行を使う)
              '1' - シングル Cpu           On  (smp の場合 1 行になる)

 

           タスクエリアのデフォルト
              'b' - 太字によるハイライト   On  (背景と前景を「反転」しない)
            * 'c' - コマンドライン         Off (コマンドラインではない名前)
            * 'i' - アイドルタスク         On  (全てのタスクを表示する)
              'R' - 逆順ソート             On  (pid の降順でソートする)
            * 'S' - 累積時間               Off (死んだ子プロセスを累積しない)
              'x' - カラムのハイライト     Off (フィールドをソートする)
              'y' - 行のハイライト         On  (実行中のタスクが表示される)
              'z' - カラー/単色            Off (カラー表示しない)

1. コマンドラインオプション
       top のコマンドラインの書式は、以下のように構成される:

            -hv | -bcisS -d delay -n iterations -p pid [,pid...]

       一般には必須とされているスイッチ ('-') と空白でさえ、完全にオプションである。

       -b : バッチモード 操作
            top を「バッチモード」で起動する。  

    top の出力を他のプログラムやファイルに送る場合に役立つ。  

    このモードでは、top は入力を受け付けず、'-n' コマンドラインオプションで設定された繰り返し回数に達するか、kill されるまで実行を続ける

       -c : コマンドライン/プログラム名 トグル
            最後に記録された 'c' の状態を逆にして、top を起動する。     

    よって、top がコマンドラインを表示していた場合は、プログラム名を表示する。     

    プログラム名を表示していた場合は、コマンドラインを表示する。
            より詳しい情報は対話的コマンド 'c' を参照すること。

       -d : 遅延時間 間隔:  -d ss.tt (秒.1/10秒)
            スクリーンを更新する間隔を指定する。

    ユーザー個人の設定ファイルにあるこれに対応する値、または起動時のデフォルトの値を上書きする。

    実行後に対話的コマンド 'd' または 's' で変更できる。

            小数点以下の秒も指定できるが、負数は許可されない。 

    しかし全ての場合において、top が「セキュアモード」で実行されているときには、このような変更は禁止されている。 

    ただし root の場合 (かつコマンドラインオプション 's' が使われていない場合) は除く。

    「セキュアモード」についてのより詳しい情報は、「5a. システム設定ファイル」の話題を参照すること。

       -h : ヘルプ
            ライブラリのバージョンと使用法のプロンプトを表示して、終了する。

       -i : アイドルプロセス トグル
            最後に記録された 'i' の状態を逆にして、top を起動する。

    トグルが Off の場合、アイドルタスクまたはゾンビタスクは表示されない。

       -n : 繰り返し回数 制限:  -n number
            top が終了するまでの繰り返し回数またはフレームの最大数を指定する。

       -u : ユーザーを指定して監視する:  -u somebody
            指定された実効 UID または実効ユーザー名にマッチするプロセスのみを監視する。

       -U : ユーザーを指定して監視する:  -U somebody
            指定された UID またはユーザー名にマッチするプロセスのみを監視する。

    実・実効・保存・ファイルシステム UID とマッチするものが選ばれる。

 

       -p : PID を指定して監視する:  -pN1 -pN2 ...  または  -pN1, N2 [,...]
            指定されたプロセス ID とマッチするプロセスのみを監視する。

    このオプションを 20 個まで指定するか、コンマで区切った 20 個までのプロセス ID を指定することができる。

    両方を混ぜて使用することもできる。

            これはコマンドラインオプションでのみ指定できる。

    通常の操作に戻したい場合は、top を終了して再起動する必要はなく  --  対話的コマンド '=' を実行するだけでよい。

       -s : セキュアモード 操作
            たとえ root であっても、強制的にセキュアモードにして top を起動する。

    このモードはシステムの設定ファイルで制御する方が、更に良い。 (「5. ファイル」の話題を参照すること)。

       -S : 累積時間モード トグル
            最後に記録された 'S' の状態を逆にして、top を起動する。    

    「累積モード」が On の場合、各プロセスはそのプロセスとそのプロセスの終了した子プロセスで使われた cpu 時間とともに表示される。
            このモードのより詳しい情報については、対話的コマンド 'S' を参照すること。

       -v : バージョン
            ライブラリのバージョンと使用法のプロンプトを表示して、終了する。

       -M : メモリ単位を検出
            メモリ単位(k/M/G)を検出し浮動小数点をメモリ概要に表示する。

2. フィールド / カラム
   2a. フィールドの説明
      top で表示可能なフィールドを以下にリストする。

  これらのフィールドは、対話的コマンド 'o' (フィールドの順序変更) で指定できる位置に関わらず、以下で示す文字と常に関連付けられている。

      全てのフィールドはソート対象として選択可能であり、降順でソートするか昇順でソートするかを制御できる。

  ソート機能についての詳しい情報は「3c. タスクエリアコマンド」の話題を参照すること。

       a: PID  --  プロセス ID
         タスクの一意なプロセス ID。

   定期的に同じ番号が使われるが、0 から再スタートすることはない。

       b: PPID  --  親プロセスのプロセス ID
         タスクの親タスクのプロセス ID。

       c: RUSER  --  実ユーザー名
         タスクの所有者の実ユーザー名。

       d: UID  --  ユーザー ID
         タスクの所有者の実効ユーザー ID。

       e: USER  --  ユーザー名
         タスクの所有者の実効ユーザー名。

       f: GROUP  --  グループ名
         タスクの所有者の実効グループ名。

       g: TTY  --  制御端末
         制御端末の名前。

   通常はプロセスが開始されたデバイス (シリアルポート、疑似端末 (pty) など) であり、入出力に使われる。

   しかしタスクは端末に関連付ける必要はなく、その場合は '?' が表示される。

       h: PR  --  優先度
         タスクの優先度

       i: NI  --  nice 値
         タスクの nice 値。

   負の nice 値は高い優先度を意味し、正の nice 値は低い優先度を意味する。

   このフィールドが 0 の場合、タスクの割り当て (dispatchability) を決定する際に 優先度を調整していないこと意味する。

       j: P  --  最後に使用された CPU (SMP)
         最後に利用されたプロセッサを表す値。

   カーネルはわざと weak affinity を使っているので、本当の SMP 環境では、この値は頻繁に変わりやすくなる。

   また実行中の top の動作そのものが (cpu 時間に対する余分な要求となることによって) weak affinity を壊すかもしれず、プロセスの CPU 変更がより多くなるかもしれない。

 

       k: %CPU  --  CPU 使用率
         前回のスクリーン更新からの、タスクの所要 CPU 時間の占有率。

   総 CPU 時間のパーセンテージで表される。

   本当の SMP 環境では、「Irix モード」が Off の場合、top は「Solaris  モード」で操作し、タスクの  cpu  使用率は総  CPU 数で割り算される。

   ´Irix/Solaris' モードは対話的コマンド 'I' でトグルできる。

       l: TIME  --  CPU 時間
         タスクが開始してから利用した CPU 時間の総計。  

   「累積モード」が   On  の場合、  各プロセスは終了した子プロセスが使った  cpu  時間とともにリストされる。 

   「累積モード」はコマンドラインオプションと対話的コマンドの  'S' でトグルできる。

   このモードについての更なる情報は、対話的コマンド 'S' を参照すること。

       m: TIME+  --  CPU 時間 (1/100 単位)
         TIME' と同じであるが、精度を 1/100 秒単位まで反映させる。

       n: %MEM  --  メモリ使用率 (RES)
         タスクが現在使用している利用可能な物理メモリの占有率。

       o: VIRT  --  仮想イメージ (kb)
         タスクが使用している仮想メモリの総量。

   コード・データ・共有ライブラリ・スワップアウトされているページが含まれる。

         VIRT = SWAP + RES.

       p: SWAP  --  スワップされたサイズ (kb)
         タスクの総仮想メモリイメージのうちスワップアウトされた部分。

       q: RES  --  常駐サイズ (kb)
         タスクが使用しているスワップされていない物理メモリ。

         RES = CODE + DATA.

         TP 3 r: CODE  --  コードサイズ (kb) 実行可能コードに割かれる物理メモリの総量。

   「テキスト常駐サイズ (text resident set)」または TRS とも呼ばれる。

       s: DATA  --  「データ+スタック」のサイズ (kb)
         実行可能コード以外に割かれる物理メモリの総量。

   「データ常駐サイズ (data resident set)」または DRS とも呼ばれる。

       t: SHR  --  共有メモリサイズ (kb)
         タスクが利用している共有メモリの総量。

   他のプロセスと共有される可能性のあるメモリを単純に反映している。

       u: nFLT  --  ページフォールト回数
         あるタスクに対して起こったメジャーページフォールトの回数。                           

   ページフォールトは、現在、アドレス空間にない仮想ページに対してプロセスが読み書きしようとしたときに起こる。
         メジャーページフォールトとは、あるページを利用可能にするためにディスクアクセスが起こる場合のことである。

       v: nDRT  --  ダーティページ数
         最後に書き込まれてから変更されたページの数。

   ダーティページは、対応する物理メモリの場所が他の仮想ページで使用される前に、ディスクに書き込まれなければならない。

       w: S  --  プロセス状態
         タスクの状態は以下のいずれかである:
             'D' = 割り込み不可能なスリープ状態
             'R' = 実行中
             'S' = スリープ状態
             'T' = トレース中/停止された
             'Z' = ゾンビ

         実行中と表示されるタスクは「実行準備済み」と考えるのがより正しいだろう。   

   --    タスクの task_struct は Linux の実行キューで表現されている。 

   本当の  SMP  マシン以外でさえ、top  の遅延間隔と  nice  値に依っては、この状態のタスクを非常に多く目にするだろう。

 

       x: Command  --  コマンドラインまたはプログラム名
         タスクを開始するのに使ったコマンドライン、 またはタスクに関連づけられたプログラムの名前を表示する。

   コマンドラインとプログラム名は、 コマンドラインオプションと対話的コマンドの 'c' でトグルできる。

         コマンドラインの表示を選択した場合、 (カーネルスレッドのように) コマンドラインのないプロセスは、 以下の例のように、プログラム名だけが括弧で括られて表示される。
         ( mdrecoveryd )

         コマンドライン・プログラム名の表示が現在のフィールド幅に対して長すぎる場合は、切り詰められる場合がある。

   フィールド幅はその他に選択されているフィールド・フィールドの順番・ 現在のスクリーン幅に依存する。

         注意: 'Command' フィールド/カラムは固定幅でないという点が特殊である。  

   表示の際、このカラムは残りの全てのスクリーン幅   (最大   512   文字)   が割り当てられる。   

   これは、プログラム名からコマンドラインへの切り替えで文字数が増える場合に備えるためである。

       y: WCHAN  --  スリープしている関数
         カーネルリンクマップ ('System.map') が利用可能かに否かによって、タスクが現在スリープしているカーネル関数の名前またはアドレスが表示される。

   実行中のタスクでは、このカラムにダッシュ ('-') が表示される。

         注意: このフィールドを表示すると、top 自身のワーキングセットが 700Kb 増加する。

   このオーバーヘッドを減らす唯一の方法は、top を停止して再起動することである。

       z: Flags  --  タスクフラグ
         このカラムにはタスクの現在のスケジューリングフラグが 0 を省略した 16 進数で表示される。   

   これらのフラグは公式には <linux/sched.h> に書かれている。  

   公式なものではないが、「フィールド選択」スクリーンと「フィールド順序指定」スクリーンにも説明がある。

 

topコマンドを「回数指定」&「回数指定」して実行する(例:5秒間隔で1時間topコマンドを実行したい)

たとえば、負荷調査をする時に、深夜帯のバッチ処理時に top コマンドを5秒おきに1時間実行して、その結果をファイルに保存して後から調査したい場合などあります。

以下例としての要件です。

  • 深夜0:00~1:00までの1時間
  • 5秒間隔でtopコマンドを実行
  • cronでキックしたい
  • 結果をファイルに保存したい

 

コマンド自体は以下のようになります。

# top -d 5 -n 720 -b > top1h.txt

-d:

topコマンドを実行する間隔を(秒)で指定します。

今回は5秒間隔なので「-d 5」を指定します。

-n:

繰り返し回数を指定します。 

top が終了するまでの繰り返し回数を指定します。

今回は5秒間隔で1時間なので、「60(秒)×60(分)÷5(秒)=720回」になります。

-b:

top を「バッチモード」で起動します。

top の出力を他のプログラムやファイルに送る場合に役立ちます。

 

午前0:00から実行したいので、crontabには以下の設定を入れます。

$ crontab -e

 

0 0 * * * top -d 5 -n 720 -b >> top1h.txt

この設定は、毎日0:00からtopコマンドを実行して1時間後に終了します。

 

cronの詳しい解説です。

 

I/O負荷が高い場合

CPUに負荷が掛かっていない、しかしロードアベレージが高い場合は「I/O負荷」を疑います。

I/O負荷が高くなる原因

  • メモリが少なくてスワップが発生してディスクアクセスが頻発している
  • プログラムからの入出力が多くて負荷が高い

 

まずは、以下の2つのコマンドでスワップの発生状況を調べます。

  • free
  • vmstat

 

スワップとは?

スワップとは「実メモリ」「仮想メモリ」の入れ替え作業のことを言います。

「仮想メモリ」はHD(ハードディスク)上に作成されます。

仮想メモリを「スワップ領域」とも言います。

仮想メモリは、OS上で見える使用可能メモリを増やすために使われるディスク領域のことです。

Linux では、仮想メモリ(スワップ領域)は、いわゆるスワップ(実メモリと仮想メモリの総入れ換え)ではなくページングに使われます。

ページングとは、物理メモリが少なくなるとメモリページをページ単位でディスクに書き込み、必要に応じて物理メモリに読み戻す処理です。(ページインとページアウト)

 

freeコマンド

# free
              total            used           free           shared     buff/cache   available
Mem:     500452        172200       15676       28920      312576       260840
Swap:    4194300      126968       4067332

 

※freeコマンドの単位は「KB」がデフォルトです。

-k, --kilo

Display the amount of memory in kilobytes.  This is the default.

■Mem

total 全メモリ容量が表示されます。OSが認識している物理メモリサイズです。

Total installed memory (MemTotal and SwapTotal in /proc/meminfo)

used 使用中のメモリ容量が表示されます。OSが利用しているバッファ/キャッシュメモリ(buff/cache)は含まれません。

Used memory (calculated as total - free - buffers - cache)

total - free - buff - cache の計算が「used memory」になります。

【例】

500452 - 15676 - 312576(buff/cache合計) = 172200で used 172200 と同値になります。

free 空きメモリ容量が表示されます。

Unused memory (MemFree and SwapFree in /proc/meminfo)

使われていないメモリ容量です。

shared 共有メモリ容量が表示されます。

Memory used (mostly) by tmpfs (Shmem in /proc/meminfo, available on kernels 2.6.32, displayed as  zero  if  not available)

上記のコマンドは「CentOS7(3.10.0-514.16.1.el7.x86_64)」で実行したものなので、この数値は無視します。

buff/cache カーネルが使用するディスクバッファ容量とキャッシュメモリ容量の合計値表示されます。

Sum of buffers and cache

available

Estimation  of  how  much  memory is available for starting new applications, without swapping. Unlike the data provided by the cache or free fields, this  field  takes  into  account  page  cache  and  also  that  not  all reclaimable  memory slabs will be reclaimed due to items being in use (MemAvailable in /proc/meminfo, available on kernels 3.14, emulated on kernels 2.6.27+, otherwise the same as free)

スワップすることなく、新しいアプリケーションを開始するために使用できるメモリ量の見積もりです。このフィールドは、キャッシュまたは空きフィールドによって提供されるデータとは異なり、ページキャッシュを考慮し、使用中のアイテムで再利用可能なメモリスラブのすべてを再利用するわけではありません。(MemAvailable in /proc/meminfo、エミュレートされているためカーネル3.14で使用可能です。カーネル2.6.27+、それ以外はフリーと同じ値です)

■Swap

total スワップに割り当てたディスクサイズです。

used 割り当てたスワップの中で使用中のサイズ。

free 割り当てたスワップの中で使用していないサイズ。

 

※sharedの欄は無視するようにmanコマンドで書かれています。

説明
free はシステムの物理メモリとスワップメモリそれぞれに対して、使用量と空き容量を表示し、カーネルが用いているバッファも表示する。
共有メモリの欄は無視してほしい。これは古い機能の名残である。

 

freeのサイズが小さいとメモリ不足が発生している?

たとえば下記のfreeコマンドの結果を見てみましょう。

# free
              total            used           free           shared     buff/cache   available
Mem:     500452        172200       15676       28920      312576       260840
Swap:    4194300      126968       4067332

freeの値が 15676KB です。

→free の値は 15.6MBです。

一見すると少ないように見えますが、本当にメモリが不足しているのでしょうか?

実は Linuxは、残ったメモリを「バッファ」「キャッシュ」に利用しています。

そして Linux は稼働し続けると free の値はゼロに近づいていきます。

そのため空きメモリ(free)が少なく見えてしまいますが、実際にメモリが枯渇していると判断できません。

本当にメモリが不足しているかどうかは vmstat コマンドの結果と突き合わせて調査する必要があります。

バッファとは何か?

バッファは I/Oアクセスする時に、直接I/Oに行くのではなく、キャッシュ経由でアクセスさせる為のメモリです。

 

キャッシュとは何か?

ファイルのデータをメモリに入れておいて、再度アクセスがあった時に素早く返す為の領域です。

1度アクセスがあったファイルは、再度使われる可能性が高いので保持しています。

キャッシュを使うことでI/Oアクセス(データアクセス)を高速化しています。

 

 

vmstatコマンド

# vmstat 1
procs -----------memory----------    ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd     free         buff  cache       si   so    bi    bo     in    cs   us sy  id     wa st
 2  0 126968  19560      0      309952    0    0     1     1      3     12  0   0   100  0    0
 0  0 126968  19560      0      309964    0    0     0     0      44   62  0   1   99    0    0
 0  0 126968  19560      0      309964    0    0     0     0      51   67  0   0   100  0    0
 0  0 126968  19560      0      309964    0    0     0     0      54   66  0   0   100  0    0
 0  0 126968  19436      0      309964    0    0     0     0      58   62  0   0   100  0    0

■procs プロセスに関する情報が表示されます

r:実行中プロセス数、ランタイム待ちのプロセス数

The number of runnable processes (running or waiting for run time).→英語 man vmstat だと、ランナブルプロセス(実行中もしくはランタイム待ち状態のプロセス数となっている。

r 2→実行中もしくはランタイム待ちのプロセスが2つある。

※日本語 man vmstat だと「ランタイム待ちのプロセス数」のみになっている。

rは実行中プロセス数、ランタイム待ちのプロセス数なのでロードアベレージの計算ができます。

b割り込み不可能なスリープ状態にあるプロセス数(I/O待ちのプロセス数)

The number of processes in uninterruptible sleep.

本来ならば実行できるはずのプロセス数。(ディスクやネットワークからのI/O(入出力)を待っている)

このbの数値が大きい場合はI/Oが原因の可能性があります。

■memory メモリに関する情報が表示されます

swpd仮想メモリの総量(単位:キロバイト)

the amount of virtual memory used.

上の例では「126968KB」→「126MB」の仮想メモリ。

free空きメモリの量(単位:キロバイト)

the amount of idle memory.

buffバッファに使用されているメモリの量(単位:キロバイト/秒)

the amount of memory used as buffers.

cacheキャッシユメモリ容量が表示されます

the amount of memory used as cache.

inactアクティブでないメモリの量 (-a オプション)

the amount of inactive memory.  (-a option)

active アクティブなメモリの量 (-a オプション)

the amount of active memory.  (-a option)

■swap スワップメモリの情報が表示されます

siディスクからスワップインされているメモリの量(単位:キロバイト/秒)

Amount of memory swapped in from disk (/s).

soディスクにスワップしているメモリの量(単位:キロバイト/秒)

Amount of memory swapped to disk (/s).

※物理メモリが十分に足りていれば「si」「so」の数値はゼロになります。

ここの数値が多いということは物理メモリが不足している可能性があります。

※特にso(スワップアウト)の数値があまりにも多すぎる場合は物理メモリの不足が原因です。

■io ブロックデバイスに関する情報が表示されます

bi:ブロックデバイスから受け取ったブロック(単位:ブロック/秒)

Blocks received from a block device (blocks/s).

※サイトによってはbiとboの記載が逆の場合があります。しかし英語 man vmstat では「received」とあるので受け取ったブロックで正解か。

bo:ブロックデバイスに送られたブロック(単位:ブロック/秒

Blocks sent to a block device (blocks/s).

■system

システムに関する情報が表示されます

in1秒あたりの割り込み回数(クロック割り込みを含む)

The number of interrupts per second, including the clock.

cs1秒あたりのコンテキストスイッチの回数

The number of context switches per second.

■CPU

これらは CPU の総時間に対するパーセンテージです。

us:カーネル以外の実行に使用した時間 (ユーザー時間、nice 時間を含む)

Time spent running non-kernel code.  (user time, including nice time)

sy:カーネルの実行に使用した時間 (システム時間)

Time spent running kernel code.  (system time)

id:アイドル時間。Linux 2.5.41 以前では、IO 待ち時間を含んでいる

Time spent idle.  Prior to Linux 2.5.41, this includes IO-wait time.

wa:I/O 待ち時間。Linux 2.5.41 以前では、0 と表示される

Time spent waiting for IO.  Prior to Linux 2.5.41, included in idle.

st:仮想マシンから盗まれた時間。Linux 2.6.11より前では未知

Time stolen from a virtual machine.  Prior to Linux 2.6.11, unknown.

 

特定のプロセスがメモリを消費している。

→psコマンドで探す

 

CPUの使用率は低いが、スワップアウトが大量に発生している

→メモリ不足→メモリを増やす

メモリを増やさない・増やせない場合

→プログラムの改善

 

DB系→ディスクの中の膨大なデータの中から特定のデータを探す→ディスクI/Oの発生→SSDの導入など

アプリ系→処理が膨大(科学計算、統計データの算出など)→CPUへの負荷

 

/proc/[PID]/ioでプロセスごとのI/O情報が分かる

下記コマンドでプロセスごとのI/Oの統計情報が分かります。

# cat /proc/327/io
rchar: 231461
wchar: 233617
syscr: 130
syscw: 115
read_bytes: 0
write_bytes: 0
cancelled_write_bytes: 0

 

manコマンドを日本語訳しています。

/proc/[pid]/io (since kernel 2.6.20)

This file contains I/O statistics for the process, for example:
このファイルには、プロセスのI / O統計情報が含まれています。たとえば、次のようになります。

    # cat /proc/3828/io
    rchar: 323934931
    wchar: 323929600
    syscr: 632687
    syscw: 632675
    read_bytes: 0
    write_bytes: 323932160
    cancelled_write_bytes: 0

The fields are as follows:

rchar: characters read

読み込み文字
       The  number  of  bytes  which  this task has caused to be read from storage.  
       This is simply the sum of bytes which this process passed to read(2) and similar system calls.  
       It includes things such as terminal  I/O and is unaffected by whether or not actual physical disk I/O was required (the read might have been satisfied from pagecache).
このタスクがストレージから読み取られたバイト数。
これは単に、このプロセスがread(2)と同様のシステムコールに渡したバイトの合計です。
これには端末I / Oなどが含まれ、実際の物理ディスクI / Oが必要かどうか(読み込みはページキャッシュから満たされている可能性があります)の影響を受けません。

wchar: characters written

書き込み文字
       The number of bytes which this task has caused, or shall cause to be written to disk.  
       Similar  caveats apply here as with rchar.

このタスクが引き起こした、またはディスクに書き込まれる原因となるバイト数。
同様の警告がrcharの場合と同様に適用されます。

syscr: read syscalls

読み込まれたシステムコール
       Attempt to count the number of read I/O operations--that is, system calls such as read(2) and pread(2).

読み込みI / O操作の数、つまりread(2)やpread(2)などのシステムコールの数をカウントしようとします。

syscw: write syscalls

書き込まれたシステムコール
       Attempt  to  count  the  number  of  write  I/O  operations--that is, system calls such as write(2) and pwrite(2).

書き込みI / O操作の数、つまりwrite(2)やpwrite(2)などのシステムコールの数をカウントしようとします。

read_bytes: bytes read

読み込みバイト数
       Attempt to count the number of bytes which this process really did cause to be fetched from the storage layer.  This is accurate for block-backed filesystems.
このプロセスが実際に行ったバイト数をカウントして、ストレージレイヤーからフェッチしようとします。 これはブロックバックファイルシステムでは正確です。

write_bytes: bytes written

書き込まれたバイト数
       Attempt to count the number of bytes which this process caused to be sent to the storage layer.
このプロセスがストレージレイヤーに送信されたバイト数を数えようとします。

cancelled_write_bytes:
       The  big  inaccuracy here is truncate.  If a process writes 1MB to a file and then deletes the file, it will in fact perform no writeout.  
       But it will have been accounted as having caused 1MB of  write.   
       In other  words:  this  field  represents  the number of bytes which this process caused to not happen, by truncating pagecache.  
       A task can cause "negative" I/O too.  If this task truncates  some  dirty  pagecache, some I/O which another task has been accounted for (in its write_bytes) will not be happening.

ここで大きな不正確さは切り捨てられています。 プロセスが1MBをファイルに書き込んだ後にファイルを削除すると、実際には書き出しは実行されません。
しかし、それは1MBの書き込みを引き起こしたとみなされます。
言い換えれば、このフィールドは、pagecacheを切り捨てることによって、このプロセスが起こらなかったバイト数を表します。
タスクによって「負の」I / Oも発生する可能性があります。 このタスクがいくつかのダーティページキャッシュを切り捨てると、別のタスクが(write_bytes内で)処理されているI / Oが実行されません。

Note:  In  the current implementation, things are a bit racy on 32-bit systems: if process A reads process B's /proc/[pid]/io while process B is updating one of these 64-bit counters, process A could see  an  intermediate result.

プロセスAがプロセスBの/ proc / [pid] / ioを読み込み、プロセスBがこれらの64ビットカウンタの1つを更新している場合、プロセスAは32ビットシステム上で 中間結果。

 

 

まとめ

「スワップアウト」と「ページアウト」の違いは難しいですね。

スワップアウトは「広義的に実メモリからディスクに退避すること」を言います。

ページアウトは「実メモリから仮想メモリにページを退避すること」を言います。

まだまだ Linux カーネル内部について勉強が必要だと感じました。

 

manコマンド参考

manページの使い分け方法

$ man ls

LS(1)                                                  ユーザーコマンド                                                 LS(1)

名前
       ls - ディレクトリの内容をリスト表示する

書式
       ls [オプション]... [ファイル]...

manコマンドの結果を日本語で表示されると読みやすいですが、日本語の場合重要な情報が端折られていることがあります。

そのためmanコマンドの結果を英語で表示させたい時があります。

その場合は以下のコマンドを実行します。

$ LANG=C man ls

LS(1)                                                   User Commands                                                   LS(1)

NAME
       ls - list directory contents

SYNOPSIS
       ls [OPTION]... [FILE]...

DESCRIPTION
       List information about the FILEs (the current directory by default).  Sort entries alphabetically if none of -cftuvSUX
       nor --sort is specified.

       Mandatory arguments to long options are mandatory for short options too.

英語で表示されます。

Posted by 100%レンタルサーバーを使いこなすサイト管理人

コメントを残す

メールアドレスが公開されることはありません。