「特定CPUコアでのボトルネック」と「リソースの奪い合い」が2大ボトルネック
第2回、第3回ではディスクI/Oボトルネックについて説明しました。レスポンスとスループットの関係を正しく理解し、I/Oスループットを最大化するようチューニングすれば、ほとんどの大規模処理は速くなります。ユーザもハッピー、皆さんもハッピー、さて家に帰りましょう。
……しかし、次はだれかからこう聞かれることでしょう。
- 「CPUの使用率が異様に低いままなんだけど……?」
- 「CPUの使用率がずっと100%で張り付いているんだけど……?」
どっちやねん!と思うでしょうが、どちらも大規模データを処理するときに特に起こりえる問題です。
ボトルネックは、1つが解消すると、新たなポイントが明らかになるものです。そして多くのケースにおいて、ディスクI/Oボトルネックが解消した場合、次に詰まるのはCPUなのです。
CPUボトルネックは、大きく2つに分類されます。「特定CPUコアでのボトルネック」と「リソースの奪い合い」です。
vmstatでCPU使用率を見てもわからない
まず、CPU使用率が低すぎるケースから見ていきましょう。CPU使用率が低すぎると、上司の方から「サーバリソースが無駄になっている!」と怒られてしまいますよね。
OSプロセスというのは、ボトルネックがない限りCPUを貪欲に利用する“生き物”です。I/O系のボトルネックが完全に解消すれば、基本的にCPU使用率は100%になるはずです。
しかし、「CPU使用率をvmstatで見る限りまだまだ余裕があるし、処理も速くならない……」というケースが発生することがあります。
こういった場合、Linuxではmpstatを見てみましょう。CPUコアごとの使用率が確認できます。
上記の例では、一定数のCPUコアのCPU使用率が100%で張り付いています。これは、最近ではあたりまえとなったマルチCPU・マルチコアをうまく利用できず、特定CPUコアに処理が閉じてしまっているパターンです。
なお、以下の場合、まだディスクI/OやネットワークI/O側のボトルネックが潜んでいる可能性があります。
- 複数のCPUコアのCPU使用率がまんべんなく低い場合
- 特定CPUコアに偏っていても使用率が低い場合
多くのSQLはマルチCPU・マルチコア環境に最適化されていない
根本的な話になりますが、1つのOSプロセスは、基本的には1つのCPUコアしか利用できません。アプリケーション側で並列処理を実装しているか、コンパイラ側の機能をうまく活用すれば、マルチスレッドで動くアプリケーションとなり、複数のコアを同時に利用できます。
こういった最適化を実施していないアプリケーションは、直列で動くため、1つのCPUコアしか利用できないのです。
Oracle Database上のSQLの多くは、意識して実装しない限りは、直列で処理されます。大規模データを効率的に処理し、マルチCPU・マルチコア環境を最大限活用するには、処理の並列化が必須となります(具体的な方法は次回説明します)。
リソースが足りないと処理速度や安定性に影響が
次に、CPU使用率が高すぎるケースについて考えてみましょう。
CPU使用率が高いのは良いことなのですが、高すぎる場合、今度は「サーバに余裕がなさすぎる!」と怒られてしまうことでしょう。
ディスクI/Oを含むすべてのボトルネックがすべて解消し、処理が限界まで並列化されれば、サーバのCPU使用率は100%になります。Oracle Databaseでは、AWR/Statspackの主要待機イベント一覧「Top5 Wait Events」からもおもだった待機イベントが消え、99%近くが「CPU Time(DBがCPUを利用していることを示す)」になることでしょう。
この状態になれば、チューニングは完了でしょうか?
この処理しか動かないDBであれば、そうかもしれませんが、「みんながハッピーか?」というと、そうはいきません。RDBMSを特定の処理で占有しているような贅沢な環境であれば良いのですが、汎用的なデータ処理・格納エンジンであるRDBMSの宿命でしょうか、多くの現場ではほかの処理も相乗りしてきます。処理間でCPUリソースの奪い合いが発生すると、それぞれの処理速度に被害が出て、共倒れになることがあります。
また、CPU使用率100%にてサーバを昼夜連続して稼働させていると、リソースの余裕がありません。たとえば4つのサーバで処理を動かしている場合、1つのサーバがダウンした際に、ほかのサーバの負荷は33%ずつ上がることになります。これに耐えきれるだけの余裕がないことになり、システム全体が不安定になる可能性があります。
つまり、今度は、CPU使用率を制限するチューニングが必要になります。
あえてI/Oボトルネックを残すようにチューニングする方法もあるけれど……
では、CPU使用率を下げるにはどうすれば良いのでしょうか?
1つのアプローチは、ほかにボトルネックを作ることです。たとえば、あえてI/Oボトルネックを残すようにチューニングする……といった職人芸も存在します。しかし、これはちょっと後ろ向きなチューニングなので、私は嫌いです。なるべく前向きに、前のめりに進むアプローチのほうが、汎用的ですし、周囲の方々の理解も得られます。
- 「ボトルネックをすべて解消した上で、CPU使用率を適切なレベルに抑える」
それが理想です。
次回は、その理想を実現する「リソース・マネジメント」の方法を紹介します。お楽しみに!