web-dev-qa-db-ja.com

従来のIO in Java

Java NIOは従来のJava IOよりも優れたソリューションである」という記事やブログをたくさん見ました。

しかし、今日、私の同僚の1人がこのブログを見せてくれました http://mailinator.blogspot.com/2008/02/kill-myth-please-nio-is-not-faster-than.html 。 Javaコミュニティの誰かが、Java NIOパフォーマンスに関連するこの種のベンチマークを行ったことがあるかどうか疑問に思っています。

24
sanjoy roy

NIO vs IOは、議論するのにとても楽しいトピックです。

私の経験では、この2つは2つの異なる仕事のための2つの異なるツールです。 IOは「クライアントごとのスレッド」アプローチと呼ばれ、NIOは「すべてのクライアントに1つのスレッド」アプローチと呼ばれると聞いたことがありますが、名前は100%正確ではありませんが十分にフィットしている。

NIOとIOの本当の問題は、私が見ているように、スケーラビリティにあります。

NIOネットワーク層は、単一​​のスレッドを使用してセレクターを処理し、読み取り/書き込み/受け入れジョブを他のスレッドにディスパッチします(すべきですか?)。これにより、セレクターを処理するスレッド(「セレクタースレッド」)はそれだけを実行できます。これにより、多数のクライアント(実際の数が不足していることに注意)を処理するときに、はるかに高速な応答が可能になります。さて、NIOが崩壊し始めるのは、サーバーが非常に多くの読み取り/書き込み/受け入れを取得しているため、セレクタースレッドが常に機能しているときです。これを超える追加のジョブがあると、サーバーは遅れ始めます。さらに、すべての読み取り/書き込み/受け入れジョブはセレクタースレッドによって処理されるため、CPUを追加してもパフォーマンスは向上しません。

IOネットワーク層は、リスニングソケットを含め、ソケットごとに1スレッドのアプローチを取る可能性があります。したがって、スレッドの数はクライアントの数に正比例します。クライアントの数が中程度の場合、このアプローチは非常にうまく機能します。このアプローチを使用して支払うコストは、スレッドのコストの形で提供されます。サーバーに2000のクライアントが接続されている場合、少なくとも2001のスレッドがあります。クアッドチップでも、チップマシンあたり6コア、これらの2001スレッドを処理するための処理ノードは24(HyperThreadingを数えると48)のみです。これらすべてのスレッドのインスタンス化にはcpu時間とramが必要ですが、スレッドプーリングを使用する場合でも、スレッド間を移動する際のCPUコンテキスト切り替えのコスト。これは、サーバーの負荷が高いと非常に見苦しくなり、適切にコーディングされていないと、マシン全体を停止させる可能性があります。プラス面として、CPUをマシンに追加します。この場合、パフォーマンスが向上します。

これですべてうまくいきましたが、IOまたはNIOを使用するかどうかを決定するのに役立つ数字が説明にないため、要約になります。これは、次の変数がさらにあるためです。考慮してください:

  • クライアントの寿命は?短いですか長いですか?
  • クライアントごとに予想されるデータの量は?小さなチャンクがたくさんありますか、それとも大きなチャンクがいくつかありますか?
  • 同時に接続されると予想されるクライアントの数はどれくらいですか?
  • どのOSを使用していて、どのJVMを使用していますか?スレッドとポーリングの両方のコストが考慮されます。

考えのためのほんの少しの食べ物。どちらが速いかという質問に答えるには、NIOまたはIO:両方でどちらでもない:)

36
claymore1977

[〜#〜] a [〜#〜][〜#〜] b [〜#よりも高速です〜]多くの場合非常に単純なビューであり、時々は明らかに間違っています。

NIOはnotプレーンIOよりも自動的に高速です。

一部の操作は、NIOを使用すると潜在的に高速になり、多くのネットワークにスケールできますNIOを使用すると、接続がはるかに簡単になります(接続ごとに1つのスレッドが必要ないため)。

しかし、NIOは魔法の「ものをより速くする」ものではありません-すべてに適用する必要があるスイッチです。

19
Joachim Sauer

NIOが使用されるのは、高速であるためではなく、より優れているスケーラビリティ特にクライアントの数があります。

IO(ブロッキングIO /ストリームIO)は通常接続ごとに1つのスレッドであり、クライアントへの応答を向上させます。スターバックスがすべてを提供するように、すべてのクライアントに対して(blocking)listen /(blocking)read/process /(blocking)writeにシングルスレッドを使用するとします。単一のウィンドウ内の顧客、スターバックスの顧客(クライアント)は焦ります(タイムアウト)。

膨大な数のスレッドがサーバーを引きずるのを避けるために、スレッドプールについて考えるかもしれないことに注意してください。スターバックスがすべての顧客を複数のウィンドウに並べるのと同じように、他のブロッキングのために顧客はまだ遅れています。そのため、接続ごとに1つのスレッドが従​​来のプログラミングでは良い選択ですJava IOプログラミング。

NIO(None Blocking IO/Block IO どちらを使用するか )はReactorPatternを使用してIOイベントを処理します。この場合、 youcouldシングルスレッドを使用してblocking/listen | read | process | write。次に、クライアントがブロックします(待機期間)は相互に影響を与えません。

IOとNIOの両方がmultiply-threadsを使用して、より多くのcpu-resourcesを利用できることに注意してください。詳細については、 Doug leeの紹介 を参照してください。

10
leef

あなたが引用する記事は3年前のものです。 Java 1.4.2(4)を使用しました。

それ以来、Java 5、6、そして今は7が出ています。

JVM内およびクラスライブラリ内の大幅な変更により、1.4.2のベンチマークに関係するものはすべて無関係になりました。

Digを始めると、Java.ioとJava.nioの違いがそれほど明確ではないことにも気付くでしょう。 Java.io呼び出しの多くは、Java.nioクラスに解決されるようになりました。

しかし、パフォーマンスを向上させたいときはいつでも、解決策はただ1つのことをすることではありません。確実に知る唯一の方法は、さまざまな手法を試し、それらを測定することです。なぜなら、私のアプリケーションにとって高速なのは必ずしもアプリケーションにとってそうではないからです。逆もまた同様です。一部のアプリケーションでは、NIOの速度が遅くなる可能性があります。または、パフォーマンスの問題の解決策になる可能性があります。ほとんどの場合、それは両方のほんの少しです。

4
lavinio

この記事の問題は、ブロッキングIOと非ブロッキングNIOを比較していることです。私自身のテストでは、ブロッキングIOとブロッキングNIOを比較しています( NIOは最大30%高速です。

ただし、プロキシサーバーのようにアプリケーションが簡単でない限り、問題になる可能性はほとんどありません。アプリケーションが行うことははるかに重要です。 IOとNIOの両方が、最大10,000の接続でテストされています。

超高速が必要な場合IO Asynch IO(Java 7+)をInfinibandで使用できます(安価ではありませんが、レイテンシーは低くなります)

4
Peter Lawrey

また、AFAIK、Java IOはNIOの裏で使用するように書き直されました(そしてNIOにはより多くの機能があります)。マイクロベンチマークは特に悪い考えです。ラヴィニオが述べているように、彼らが古いとき。

2
Dave Newton

Java NIOとreactorパターンは、ネットワークパフォーマンス自体ではなく、パフォーマンスとシンプルさの点でシングルスレッドモデルがシステムに提供できる利点についてです。そして、それは、シングルスレッドのアプローチであり、劇的な改善につながる可能性があります。ここを見てください: 2マイクロ秒未満の遅延のあるソケット間通信

1

Java NIOは、通常よりも高速であると見なされますIO理由:

  1. JavaNIOは非ブロッキングモードをサポートしています。非ブロッキングIOは、接続ごとに専用スレッドを必要としないため、ブロッキングIOよりも高速です。これにより、大量の処理が必要な場合にスケーラビリティを大幅に向上させることができます。スレッドはあまりスケーラブルではないため、同時接続。

  2. Java NIOは、ダイレクトメモリバッファをサポートすることにより、データのコピーを削減します。データをまったくコピーせずにNIOソケットの読み取りと書き込みを行うことができます。従来のJava IOでは、データはソケットバッファとバイト配列の間で複数回コピーされます。

1
rustyx

一方が他方よりも速いという固有の理由はありません。

スレッドごとに1つの接続モデルは、現在、Javaスレッドには大きなメモリオーバーヘッドがあり、スレッドスタックは固定(および大きな)サイズに事前に割り当てられているという事実に悩まされています。修正する必要があります。そうすれば、数十万のスレッドを安価に作成できます。

0
irreputable