見出し画像

CPU使用率の求め方は正しいですか?


1.はじめに


こんにちは。株式会社SHIFT ITソリューション部の力石です。主にお客さまのアプリケーション開発プロジェクトで、性能改善、品質向上などの非機能関連のコンサルティングをしています。

システムの性能分析をする際にCPU使用率は最も重要な項目となります。Linux環境でCPU使用率を求める時、vmstatコマンドなどで取得したどの項目を使っていますか?

多くの人が間違った求め方をしていますので、この記事では実験結果もあわせて説明をしていきます。

執筆者プロフィール:力石 知也
大手SIなどでアプリケーション開発からインフラ関連まで幅広く約30年経験。現在は性能改善、品質向上などの非機能関連のコンサルティングを実施。

2.いきなり結論


Linux環境でCPU使用率を調べるときに、どの項目を使用していますか?
インターネット検索をしますと、CPU使用率は「100 - %idle」と書いてある記事が散見されますが、 皆さんが求めたいと考えているCPU使用率はこの式では求められません。 正しい式は、「100 - %idle - %iowait」となります。

3.CPU使用率を求めるのはどのようなとき


皆さんがCPU使用率を求めたいと考えるのは、次のような場合ではないでしょうか?

状況1:アプリの性能が悪いため、CPUがボトルネックになっているか調査
状況2:処理量が今後増える予測となっている。その時にCPUがボトルネックにならないか確認

このような状況でCPU使用率を求めるときは、%iowaitの値も考慮する必要があります。

4.iowaitとはどのような状態か


今回の記事を理解するために、まずはiowaitとはどのような状態かを説明します。

iowaitとは、ディスクやネットワークなどのI/Oデバイスからの応答を待っている状態のことを指します。 この状態では、CPUは計算などの処理を行っていません。もし他のCPUを必要とするプロセスがあれば、 そのプロセスがCPUを使用することができます。

一言でいいますと、「iowaitは待ち状態ですので、他のプロセスが処理で使用可能」です。

他にも状態はいくつかありますが、主なものとして %usr(us、%user)、%sys(sy、%system)、%iowait(wa、%iowait)、 %idle(id、%idle)があります。(括弧内はコマンドによる表記違いです)

5.実測内容


これまでの内容に納得できない方も多いと思います。
そのために実測し、iowaitの部分が他のプロセスで処理できるか確認していきます。

今回実測するサーバーは20vCPU(論理プロセッサ)です。
1プロセスでI/O待ちが発生してもサーバー全体から見ると最大で5%です(100% ÷ 20 = 5%)。 今回サーバー全体でiowaitを増やすため、ディスクI/Oが発生する処理を20多重で動かします。

この記事ではこれを「ディスク処理」と呼びます。 この状態で、CPUを多く使う処理の多重度を上げていきます。これを「CPU処理」と呼びます。

6.実測コマンド


ここでは、実測時のコマンドについて説明しています。興味のない方は読み飛ばしてください。

6.1 ディスク処理


dd if=/dev/zero of=<出力ファイル> bs=32k count=51 oflag=direct

約1.6MBを出力ファイルに書き出します。
書き出し時にキャッシュを使用しないようにoflag=directを指定します。これにより、 ディスクへの書き込みが完了するまで待機状態となり、iowaitの状態となります。

6.2 CPU処理


zcat <入力圧縮ファイル> > /dev/null

time出力例
real    0m4.540s   
user    0m4.540s   
sys     0m0.000s   

入力ファイルとして約1.6MBのファイルを用意します。
多重度を上げても同じファイルを読み込むため キャッシュに載っているファイルを使用しますので、ディスクI/Oは不要となり、処理時間のほとんどがCPU使用となります。
timeコマンド付きで実行しますと、処理時間(real)とuserの値が一緒となり100%userの使用となっていることが分かります。

6.3 CPU使用率の取得


mpstat 1
出力例
	20時23分24秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
	20時23分25秒  all    0.05    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.95

今回は、mpstatコマンドで状態ごとのCPU使用率を取得します。
mpstat以外にも、CPU使用率が取得できるコマンドには、vmstat、iostat、topなどいくつかあります。 どのコマンドにも共通して以下の項目は存在しています。

実際にコマンドを実行するとわかりますが、この4つ以外の値は小さいことが多いため今回は検討対象外とします。

7.実測結果


7.1「CPU処理」とusrの関係


「CPU処理」の多重度を1分ごとに1から23まで上げていき、サーバー全体の%usrをグラフにしたものが以下です。

多重度(緑線 右軸)を上げるごとに%usr(青線 左軸)も使用率が上がり、20多重にした時に%usrは100%になっています。サーバーのvCPU数(論理プロセッサ数)が 20のため、20多重で100%になっており、21多重以上で100%のままになっています。

このグラフから 「CPU処理」は処理時間の全てをusrで使用していることが分かります。

7.2「ディスク処理」とiowaitの関係


同じ期間の%usr(青線)、%iowait(緑線)、%idle(ピンク線)、「ディスク処理 処理量」(黄破線)、「CPU処理 処理量」(赤破線)をグラフにしたものが以下です。

「CPU処理 処理量」は赤破線で示され、1分間に何回処理を実行できたかを示しており、目盛は右軸です。
「ディスク処理 処理量」は黄破線で示され、1分間に何回処理を実行できたかを示しており、目盛は右軸です。
「CPU処理」を開始する前から「ディスク処理」は20多重で動かしています。

「CPU処理」の多重度を増やし%usrが増えると処理量はそれにつれて増え、多重度が8を超えるあたりから徐々に飽和し始め※、20を超えた段階で頭打ちとなっています。
「CPU処理」の多重度を増やしても「ディスク処理」の処理量に大きな変化はありません。
※飽和する理由が気になる方は CPU使用率と処理能力の関係は比例ではない 参照

先の説明で%iowait分は他のプロセスでCPUを必要としている場合、割り当てることが可能と説明したとおり、%iowaitの値は減っても「ディスク処理」処理量は減っていません。また「CPU処理」が20多重で動いている場合は %iowaitは0%となっていますが、「ディスク処理」の処理量は減っていません。これは%iowaitと「ディスク処理」の処理量に相関がないことを示しています。
00:10以降はidleがほぼゼロにもかかわらず、「CPU処理」の多重度増加につれてCPU処理量は増えている(若干飽和するが)、これは、iowaitの時間が「CPU処理」で必要とする%usrの時間に充てられていることを示しています。

7.3 %usr、%iowait、%idleの推移


CPUの%usr(青)、%iowait(緑)、%idle(ピング)を積み上げグラフにしたものが以下です。

%usr、%iowait、%idleを合計するとほぼ100%となっています。

「ディスク処理」で%iowaitを使用している場合も、「CPU処理」で%usrが必要な場合は%iowaitから%usrに充てられています。したがって%iowaitはCPUを使っていないのと同じことになります。グラフでいうと %idle(ピンク)と%iowait(緑)が未使用部分となります。

7.4結論


上記の結果より、%iowaitはCPU使用率には含めないのが妥当です。 CPU使用率は、「100 - %idle - %iowait」で求まることが分かります。

8. なぜ間違った情報があふれているのか


「CPU使用率を求める」というマシンリソースや性能問題についての基本的なことについて、なぜこんなに間違った情報があふれているのか調べてみました。私の推測では次の理由と考えられます。

man vmstat コマンドでCPUの項目について調べてみると次のように表示されます。

us: カーネルコード以外の実行に使用した時間 (ユーザー時間、nice 時間を含む)。
sy: カーネルコードの実行に使用した時間 (システム時間)。
id: アイドル時間。Linux 2.5.41 以前では、IO 待ち時間を含んでいる。
wa: IO 待ち時間。Linux 2.5.41 以前では、0 と表示される。

Linux 2.5.41以前だとwaは0と表示され、idにはwaの値も含まれていいるとなっています。 この場合CPU使用率は「100 - id」で求めることができます。

Linux 2.5.41がいつ頃のバージョンか調べるため、Red Hat のサイトを参照すると次のようになっています。

idとwaの表示内容が変わったのはLinux 2.5.41以後ですので、Red Hat Enterprise Linux 4以降となります。
提供時期は2005年なので今から20年近く前です。 この頃の知識を基に書かれた記事などが引用され続けていると思われます。

また、HP-UX 11i v3(B.11.31)のvmstatだとCPUの表示項目はus、sy、idの3つだけで、Linuxで表示されるwaがありません。この場合CPU使用率は「100 - id」で求めることができます。

以前はUNIXを使用していた人がLinuxを使うようになり、UNIX使用時の知識を元に書かれた記事が引用され続けていると思われます。

9.まとめ


CPU使用率は、「100 - %idle - %iowait」で求めます。

CPU使用率に限らず新たに知識を得る際は、気になる点は納得するまで調査すべきです。 今回の件も、mpstat、vmstat、topなどコマンドの出力にはいろいろな項目があります。その中でiowaitの値が無視できないほど大きく、この値は何を意味しているか調べたり実験したりすることで新たな知識を得ることができます。みなさんもこのような小さな疑問や気になったことを調べることを通して、技術的に成長につなげていただけると良いのではないかなと思います。

|あわせて読みたい関連記事

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/

PHOTO:UnsplushRyan