2012-03-02 14 views
4

私たちのサーバーのうちの1台で、アプリケーションに非常に高いCPU負荷が発生しています。私たちは様々な統計を見て、問題の原因を見つける問題を抱えています。CPUが多い、コンテキスト切り替えの可能性がありますか?

現在の理論の1つは、スレッドが多すぎることと同時に実行中のスレッドの数を減らそうとする必要があるということです。 3000スレッドのメインスレッドプールが1つあり、WorkManager(これはJava EE - Glassfish)で動作します。任意の瞬間に、並列で実行する必要がある約620の別個のネットワークIO操作があります(java.NIOの使用はオプションではありません)。さらに、IOが含まれておらず、パラレルに実行される操作は約100件あります。

この構造は効率的ではなく、実際に損傷を引き起こしているかどうか、あるいは単に悪い習慣であるかどうかを確認したいと考えています。理由は、このシステムでは(人時間の点で)変更が非常に高価であるため、問題の証拠が必要です。

これで、必要な並行操作よりもはるかに多くのスレッドが存在するため、スレッドのコンテキスト切り替えが原因であるのかどうか疑問に思っています。ログを見ると、平均して14個の異なるスレッドがある秒間に実行されていることがわかります。 2つのCPU(以下を参照)の存在を考慮すると、CPUあたり7つのスレッドになります。これはあまりにも多くのように聞こえることはありませんが、我々はこれを確認したかったのです。

だから、私たちは文脈の切り替えや多すぎるスレッドを問題として除外できますか?

一般詳細:

  1. のJava 1.5(はい、それは古いです)、CentOSの5、64ビット、Linuxカーネル上で動作する2.6.18-128.el5
  2. ただ1つのJavaプロセスがありますマシン上には何もありません。
  3. 2つのCPU、VMwareの下。
  4. 8GB RAM
  5. マシン上でプロファイラを実行するオプションはありません。
  6. JavaやOSをアップグレードするオプションはありません。

UPDATE 以下のアドバイスとして、私たちは様々な負荷での我々のテストサーバー上(のvmstat 1 120を使用して)負荷(稼働時間を使用して)平均値とCPUのキャプチャを行ってきました。我々は、システムが新たな負荷を中心に安定していることを確認するために、各負荷変動とその測定値の間の15分を待っていましたし、平均負荷番号が更新されていること:運用サーバーのワークロードの

50%:http://pastebin.com/GE2kGLkk

34本番サーバーのワークロードの%:本番サーバーのワークロードのhttp://pastebin.com/V2PWq8CG

25%:http://pastebin.com/0pxxK0Fu

CPU使用率が非常に大幅なレベル25から50までパーセントから(変化への負荷が軽減として減少するように見えますが、ではありません%は実際には50%ではありませんCPU使用率の削減)。負荷平均は作業負荷の量と無関係のようです。

私たちのテストサーバーもVMであるため、同じホスト上で実行されている他のVMがそのCPU測定値に影響を与える可能性があります(上の測定は役に立たない)?三つの部分(ペーストビン限界)

第1のスレッドのスナップショットを取り付け

UPDATE 2http://pastebin.com/DvNzkB5z

パート2:http://pastebin.com/72sC00rc

パート3:http://pastebin.com/YTG9hgF5

+0

スレッドプール内のスレッド数を減らして、役立つかどうかを確認してください。 – Voo

+0

CPU使用率が高いと、CPUリソースの使用率が最適であることを意味します。あなたのスレッドは、I/Oやロックを待つことなく何かを計算しています。あなたのCPUを不必要に消費するタイトなループを持たないかぎり、あなたが達成した並行性の高さについては満足しているはずです。 – dasblinkenlight

+1

@dasblinkenlightこれは、(コンテキストの切り替えなどの)無駄がないことを証明できれば真です。これを行うことができれば、システムチームにCPUを追加して、それを正当化するように指示することができます。しかしまず、私たちは宿題をしなければなりません。 – Yon

答えて

2

は、問題が何よりも100 CPUバインドされたスレッドである私には思えます。 3000スレッドプールは、基本的には赤いニシンです。アイドル状態のスレッドは何も消費しません。 I/Oスレッドは、コンピュータ操作の観点から地質学的な時間スケールで測定されるため、時間の「ほとんど」眠っている可能性があります。

100 CPUスレッドが何をしているか、またはそれらの持続時間については言及していませんが、コンピュータの速度を落としたい場合は、「タイムスライスまで実行する」と100スレッドを指定すると、 。 「常に実行可能な状態」の100を持っているため、マシンはスケジューラが許す限り速くコンテキスト切り替えを行います。アイドル時間はほとんどゼロになります。あなたが頻繁にそれをしているので、コンテクストの切り替えは影響を与えます。 CPUスレッドはCPU時間の大半を消費するので、I/O「バウンド」スレッドは実行キュー内でI/Oを待っているよりも長く待っています。そのため、さらに多くのプロセスが待機しています(I/OプロセスはI/Oバリアを急速に突き抜けて次のプロセスのためにプロセスをアイドルさせるため、より頻繁に救済されます)。

ここでは効率を改善するために調整が行われていることは間違いありませんが、100個のCPUスレッドは100個のCPUスレッドです。それほど多くはできません。

+0

洞察をいただきありがとうございます。 2番目の更新で掲示されたスレッドスタックを見て、あなたはどう思いますか? – Yon

+0

スレッドスタックを見直し、スレッドプールサイズなどで遊んだところ、ここで正しいと結論づけました。私たちはスレッドプールのサイズを減らさず、代わりにI/Oを必要とせず何も待たないタスクがシリアルで実行されるようにコードの一部を変更しました。他のタスクは並行して実行されますが、同時に実行されるタスクの数には一定の制限があります。これは、任意の時点でRUNNABLE状態になるスレッド数の見積もりに基づいています。 – Yon

2

コンテキスト切り替えを排除できますかまたは多すぎるスレッドを問題として使用しますか?

あなたが懸念しているのは、スラッシングが保証されていると思います。確かに2 CPUのVMwareインスタンス3000件のスレッド(700+同時操作)とスレッドプールは、コンテキストスイッチング過負荷および性能問題を引き起こすことができる問題のように思えます。あなたは右の数は困難になるだろうし、おそらく試行錯誤の多くを使用します決定するものの、パフォーマンスの向上を与えることができるスレッドの数を制限します。

我々は問題のいくつかの証拠が必要です。

私が答えるための最良の方法はよく分からないが、ここでいくつかのアイデアです

  • VM OSとJVMの負荷平均をご覧ください。高負荷値(20+)が表示されている場合は、実行キューに余りにも多くのものがあることを示すインジケータです。
  • あなたがスレッドプールの番号で遊ぶことができますので、テスト環境での負荷をシミュレートする方法はありませんか?プール・サイズがXのテスト環境でシミュレート・ロードを実行してからX/2を実行する場合、最適な値を決定できるはずです。
  • 高負荷時間と低負荷時間を比較できますか?これらの時間の間のレイテンシに対する応答の数をグラフ表示して、スラッシングの点でチッピングポイントが見えるかどうかを確認できますか?
  • あなたは負荷をシミュレートすることができた場合、あなただけの方法論「消火ホースからドリンク」の下でテストされていないことを確認してください。上下にダイヤルできるシミュレーション負荷が必要です。 10%から開始し、スループットとレイテンシを見ながら、シミュレートされた負荷を増やしてください。スループットの平坦化やそれ以外の偏向を監視することで、ティッピングポイントを確認することができます。
+0

ここにミックスを追加するには、システムチームが私たちのコントロールなしでCPUの数を変更する可能性があるので、ブートするたびに再調整する必要があります。 – Yon

+1

@Yonここでは、物理コアに対するスレッドの観点から、あなたはここから離れているように思えるので、ブート時に設定された余分な1〜2台のCPUが違いを生むとは思わない。あなたはどこかで8または16のCOREシステムでシステムを実行しようとしましたか? – Gray

+0

あなたの主張を証明し、関係する仕事を正当化するにはどうすればよいですか? – Yon

1

通常、スレッドのコンテキスト切り替えは計算上非常に安価ですが、このスレッドが多数含まれている場合はわかりません。 Java 1.6 EEへのアップグレードは問題にはなりませんが、ハードウェアのアップグレードはどうですか?それはおそらく迅速な修正を提供し、その高価であってはならない...

+0

システムチームは、リソースの変更が正当な理由を説明する証拠を私たちに要求します。 – Yon

0

同様のマシンでプロファイラを実行します。

  • (生産をアップグレードする気にしないでください。その場合には、それが違いを加えることはできません)は、Java 6または7の新しいバージョンを試すには、
  • は、VMwareを使用しないようにしようのCentOS 6.xのを試してみてください。
  • スレッド数を減らしてみてください。あなたは8つのコアしか持っていません。

多くの場合、上記のオプションのいずれかが違いがありますが、既知の/繰り返し可能な作業負荷でテストできるシステムが見つかるまではわかりません。

+0

我々は、負荷のおよそ半分を実行するテスト環境を持っています。 Javaのバージョンを変更しても、スレッドの数は減少しませんでした。 – Yon

+0

Javaのバージョンをアップグレードすることは役に立たず、スレッド数はおそらく問題ではないと結論づけることができます。 –

+0

私たちが持っている質問の1つは、ロードされたサーバーの数が増えてスレッド数が増え、このコンテキスト切り替えによって問題が発生する可能性があるということです。大きなプールであっても、ほとんどのスレッドがキューを待機していることを覚えておくことが重要です。 – Yon

4

あなたの制約は不合理だと思います。基本的にあなたが言っているのは:

1.I can't change anything 
2.I can't measure anything 

あなたは私の問題が何であるかを推測できますか?

本当の答えは、適切なプロファイラをアプリケーションに接続する必要があり、CPU使用率、ディスク/ネットワークI/O、およびメモリに見えるものを関連付ける必要があるということです。

パフォーマンスチューニングの80/20ルールを忘れないでください。 80%はアプリケーションのチューニングから来るでしょう。 1つのVMインスタンスに負荷がかかりすぎる可能性があります。マシンに多くのリソースを与えることによって、水平または垂直方向のスケーリングのソリューションを検討する時間がかかることがあります。 30億のJVM設定のどれかがアプリケーションの実行の詳細とインラインではない可能性があります。

3000スレッドプールは有名なスレッドより多く=より多くの同時実行性=より多くのパフォーマンス理論から来たと仮定します。実際の答えは、チューニングの変更は、変更前と変更後のスループットと応答時間を測定し、結果を比較しない限り価値がありません。

+0

私たちができないことの根底にある根拠は、地球の反対側にあるサーバーがいくつかの保護策の背後にあることです。私たちはそこを飛ぶ必要があり、それでもインターネットにアクセスできないので、状況は非常に面倒です。私たちは本当にそれをしたくないです。より多くのリソースを提供するには、ローカルシステムチームを説得する必要があります。つまり、証拠が必要です。 – Yon

+0

スレッドプールはこれから発生しました。私たちがそれを制御せずに同時IOタスクの数が増える可能性があります。したがって、このオペレータがシステムに投げることができる作業量に十分な数として3000を設定します。 Glassfishのスレッドプールに関する問題は、実行時にサイズ変更できないことが明らかです。 – Yon

+2

あなたの正当な理由は完全に無効です。スレッドプールのサイズは、あなたの子供に与える余裕ではありません。なぜそれを40億に設定しないのですか?これは、アプリケーションの物理的な動作環境とその限界についての指標です。正しい番号を見つけることは試行錯誤のプロセスです。少しでも作業があれば、キューとコアはアイドル状態になります。スレッド間の切り替えに要するコストは、同時実行のメリットを凌駕します。あなたは正しい数を見つけるためにサイエンスの力を利用する必要があります – nsfyn55

2

プロファイルできない場合は、スレッドダンプか2つを取って、スレッドが何をしているのかを確認することをおすすめします。あなたのアプリはそれを行うために停止する必要はありません。

  1. http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/threads.html
  2. http://java.net/projects/tda/
  3. http://java.sys-con.com/node/1611555
+0

良い点、スレッドのスナップショットが質問に追加されました。 – Yon

関連する問題