質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.11%

CPU使用率には余力があるのにLoad Averageが高くなる時の対処方法

受付中

回答 3

投稿

  • 評価
  • クリップ 9
  • VIEW 36K+

score 104

Postgresqlののサーバでpgbenchを実行しています。 その時、cpu使用率が50%程度で、cpu割り込みも発生せず、ioの値も5いくかどうかで推移しています。 メモリ使用率においても20%弱で推移して、swapも使用されていません

このような状態の時、OSはマルチタスクを実行するためにプロセスの切替が間に合っていない状態のようですが、 Load Averageを低減させる手段としてどのような対処方法がありますでしょうか

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+6

サーバーのボトルネック切り分けは、かなり奥深い問題なので、ご提示頂いた情報だけでは何とも言えません・・・

一般論からすると以下のページの説明が簡潔で分かりやすいです。

    システムの負荷の原因を切り分ける方法

TaichiYanagiya さんもご回答頂いているように、Disk I/O がボトルネックになっている可能性も高いです。これはDBのベンチマークという目的からすると、むしろ当然かもしれません。

また、最近では メニーCPU/メニーコア が当たり前の時代となりましたが、もし稼働しているプロセスが未対応だと 1CPU/コア のみしか利用されないので、たとえば4コアの場合、CPU使用率が 25% で頭打ちになってしまいます。これは、対応が未済みというよりも、処理の内容によっては メニーCPU/メニーコア 対応が難しいという場合もあります。 このような場合、見かけ上のCPU使用率は低いとしても、実質的にはCPUの処理能力がボトルネックになっていることになります。

いずれにしても、何がボトルネックになっているのかを、もっと綿密に調査・切り分けしないと、具体的な対策は決められません。たとえば linux ボトルネック 調査 のようなキーワードでググると色々な調査・分析方法が紹介されていますので、もう少し踏み込んで調査されることをオススメいたします。ご参考までに以下のページのリンクを貼り付けておきます。

  OS コマンドによるボトルネック調査

  sarによるボトルネック発見の手順(というかsysstatの使用法)をまとめてみた

  最大の課題「I/Oボトルネック」の原因と分析法


さて、ようやくここから本論ですが、

Load Averageを低減させる手段としてどのような対処方法がありますでしょうか

ボトルネックが分かれば具体的な対策の検討に入る訳ですが、実は「Load Average」が高いこと自体がいけない訳でもありません。

まず、「Load Average」については下記ページが詳しいですが

  マルチコア時代のロードアベレージの見方

Linux のロードアベレージは「ロードアベレージは過去1分、5分、15分の間の実行待ちプロセス数の平均数 = 実行したくても他のプロセスが実行中で実行できないプロセスが平均で何個ぐらい存在してるか」を示す値です。

サーバーで実行されるプロセスの中には、目的によって以下のように幾つかに分類されます。

  1. それ自体は軽い処理だが、なるべくたくさんのプロセスを短時間に処理したいもの
  2. それ自体が重い処理で、なるべく早く処理を完了したいもの
  3. 重たい処理だが急がないので、バックグラウンドでゆっくり処理をすれば良いのも

重たい処理を同時にたくさん実行しようとすると、サーバー全体の応答が極端に悪くなってしまうのですが、3. のように重いけれども急がないプロセスは プロセスの優先度を下げる 事によって、サーバー全体の応答性を損なうこと無く同時に多数のプロセスを稼働させることが可能です。 具体的には、nice(renice)コマンドやioniceコマンドを使用することで、プロセスの優先度を調整します。

  Linux の nice / renice コマンドを覚えた

  大量・巨大なファイル操作を低負荷で行う方法

このようにすると、サーバー全体の応答性をあまり犠牲にすることなく大量のプロセスを稼働させる(つまり、急がないプロセスは優先度を下げて稼働させておき、サーバーリソースに空きのできた時にちょっとずつ処理を進める)ことも可能なのですが、そうすると たくさんのプロセスがキューに溜まっている状態 になるため Load Average の高い状態が続く事になります。 しかし、これは意図的に作り出している状況であり、サーバー全体の稼働状況に問題はない訳です。

一方、重たい処理だが、それ自体をなるべく早く完了させたい という場合は、そのプロセス自体のボトルネックを特定して対策を講じる必要があります。 この場合は自プロセスの内部の問題なので、やはり Load Average の大きさは直接関係ありません。 たくさんのプロセスがキューに溜まっていても、自プロセスの実行優先度を高くすると優先的に処理されるようになるため、自分自身は長い時間順番待ちすること無く処理が進みます。

とはいえ、もともと重たい処理なので、単純に優先度を上げただけではやはり処理の完了までに長い時間が掛かってしまいます。

ですので、必要に応じて以下の対策を組み合わせて実施します。

1)サーバー自体のリソースを増強する(スケールアップ)

  • CPU(コア)を増やす
  • メモリーの搭載量を増やす
  • 外部ストレージを高速なものに交換する、RAMディスクを活用する
  • ネットワーク機器を高速なものに交換する

2)サーバーやストレージを複数用意し負荷分散する(スケールアウト)

3)OS(カーネルパラメータ)を調整してサーバーリソースをもっと効率的に利用できるようにする

4)プロセス自体を改善して負荷を下げる

これら一つ一つについて書き出すと、ポイントを箇条書きにするだけでも膨大な量になってしまうので、ボトルネックを特定し具体的な対策の「方針」が決まった時点で、必要に応じて再度ご質問ください。


《追記:2015/12/08 14:00》

 PostgreSQLのMax_connection数を現行の100から少しでも上げる必要がある事から
との事ですが、そうであればやはりロードアベレージは直接的には関係ないですね。
そして、この チューニングの目的 こそ、質問の最初に伝えるべきものです。

接続数を増やす最大のカギは Postgres 自体のパラメーター調整ですが、やはりただ闇雲に変更すれば良いでは無いです。既に色々調整済みとの事ですからご承知だろうとは思いますが、一応、下記ページを振り返って設定値を見直してみてください。
   PostgreSQLのチューニング事例 
   PostgreSQLのチューニング その1 

その上で、もしOS側のTCP同時接続数の上限がボトルネックになっているならばカーネルパラメーターを調整します。
   net.core.somaxconnについて調べてみた
関連するパラメーターは他にもあるので、必要なら追加で調べるか質問してください。

その上で更なる改善が必要ならば、pgpool の導入を検討されると良いかもしれません。
   PostgreSQLには絶対!pgpool-II

古い情報が多くて恐縮ですが、ご参考になれば幸いです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/08 13:07

    コメント欄は書きにくいので、解答欄に追記します。

    キャンセル

  • 2015/12/09 11:26

    ご回答ありがとうございます。

    net.core.somaxconnやtcp接続などについては継続して調査していきます。

    postgresql側でpgpool導入については調査していきまして
    コネクションプール+pgpoolで不明点などありましたら、
    改めて新規でトピックを上げさせて頂きます。

    キャンセル

  • 2016/08/18 11:01

    接続数を増やせばスレッドの数も増えるのでロードアベレージが増えます。ロードアベレージを減らすという目標自体が間違ってるのでは?と思いました。

    キャンセル

+2

Load Average は CPU負荷の他、ディスクI/O、(短時間での)プロセス生成が関わってきます。 pgbench 実行とのことですので、ディスクI/O、特に書き込み待ちが多くなっていると推測されます。 vmstat 5 で 5秒ごとの cpu wa の値が大きくなっていませんでしょうか?

ディスクへの書き込み待ちを低減するためには、速いストレージを使うとか、そもそも書き込むデータを少なくするとか、くらいでしょうか。

(2015/12/04 09:08 追記)
データベースであれば、I/Oスケジューラーを noop や deadline に変えると性能が上がるかもしれません。
設定方法は、kernel 起動パラメータで elevator=noop とするか、echo noop > /sys/block/sda/queue/scheduler (sda 箇所は環境に合わせて)。

pi-chan さんの回答のとおり、Load Average の値が高いこと自体は問題ないと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/05 09:15

    ご回答ありがとうございます。
    vmstat、sarを実行してのwa率は5%も行かない程度です
    I/Oスケジューラをcfqからdeadlineにしてみましたが、あまりload値の改善はありませんでした。
    サーバは仮想(VM)で稼働していますのでIO周りは他のホストに引きずられたりするのかもしれませんが。
    単純にcpuコアを上げたり、/var/lib/pgsqlのファイルシステムでnoatimeを付与する事でload値は少なからず改善はされました。
    また、pgbenchを実行しているのはpostgreのローカルサーバですので
    pgbench実行プロセスの優先度も下げてベンチを掛ける事でも、Load値を多少下げる事も出来ました。

    Load Average の値が高いこと自体は問題ない事は調べて掘り下げてみたいと考えています。

    ありがとうございました。

    キャンセル

  • 2015/12/05 09:26

    横から失礼します。
    仮想で動作しているなら、仮想のホスト側でもIOの待ち時間やスワップしていないかなどを見てみてください。ホスト側が負荷で一杯の状態でもゲスト側からは単に遅くなるだけで原因が見えにくい場合があります。

    キャンセル

  • 2015/12/06 11:40

    仮想マシンなのですね。
    VMware の Rawデバイスマッピングなどの場合は仮想マシンの I/Oスケジューラーが効きますが、VMDK などホストを介在する場合は noop でいいと思います。

    noatime → ファイルシステム側の設定もありましたね。意外と効くようですね。

    キャンセル

+1

他の方の回答で出尽くした感がありますが、一応以下も確認してみてください。

  • mpstat: コアごとの状況は偏っていないか、%irq%softはどうか
  • cat /proc/interrupt: 特定コアへの割り込み数が毎秒数十万単位になっていないか

idleがありながらのLoad Averageの異常な上昇は、割り込み不可能なタスクがたまっている証拠です。そのうちブロックデバイスの場合はiowaitに計上されますが、キャラクターデバイスやネットワークはiowaitに計上されません、というかできません。アフィニティを設定していないのにcpuがidleしていて、iowaitも低いとなると、候補はネットワークと・・あと何かありますか?

コア数8に対して、Load値が30といういうのも、各コアに平均3.75のタスクがたまっているとは考えずらいです(それならiowaitなりuserなりの値がもっと上昇します)。アフィニティが設定された1つのコアに30近いタスクが溜まってると考えた方が自然です。そしてアフィニティが最初から設定されているもので一番可能性が高いのがネットワークのPCI割り込みです。

ただ、ネットワークIOの割り込みを各コアに分散させるのは必ずしも良いことではないので、よく前例などを調べてから行ってください。

Red Hat Enterprise Linux 4.3. 割り込みおよび IRQ チューニング

あと、そもそもですが、同時接続200でフルロードというのは、実際に運用したときにはどの程度のユーザーベースなのか検討が必要ではないでしょうか(F5攻撃でも無い限り、200ユーザーではないでしょう)。そのユーザーベースを支えるために別の部分がボトルネックになるのなら、DBの負荷よりもそちらを先にやるべきです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る