2011-12-20 4 views
2

私は特定のバイナリプロトコルを扱うTCPサーバを持っています。要求には、ファイルに書き込まれる大量のデータが含まれているものがあります。サーバーはNIOフレームワーク(netty)を使用し、複数のフレームに分割されたメッセージを処理するロジックを持っています。ファイルハンドルを開いたままにするか、必要に応じて再度開きますか?

個々のフレームが入ってくると、そのフレームのデータをファイルに書き込む場合は、ファイルを開いてデータを書き込みます。ストリームが終了していないにもかかわらず、同じファイルにデータのある別のフレームが追加されることが予想される場合でも、次のフレームを受け取るまでファイルを閉じます。その時点でファイルを開き、追加のデータを追加します。

私はこの方法を選択しました。オープンファイルハンドルを残すことを避けるのが最も安全な方法だったと思いますが、何らかの間違いでそれらを閉じることはできませんでしたが、パフォーマンスに悪影響を及ぼすことが懸念されます。ファイルハンドルを開いたままにしておく方が良いですか(この場合はベストプラクティス)(開いているFileOutputStreamまたはChannelへの参照を保持していますか?開いているファイルハンドルの数にリソースの制限がありますか?

+1

どのような種類のボリューム(同時に開いているファイル)を検討していますか?どのくらいの頻度でフレームを受信して​​いますか?多かれ少なかれストリーミング/リアルタイム?または長い遅延で?プレイにおけるリミットはその点で数百(または千)になる傾向があります。また、ファイルのオープン/クローズに要する時間とフレーム間の遅延時間を考慮する必要があります。 – BRFennPocock

+0

これらのすべてが良い点です@BRPocock:この種の質問のほとんどは、本当に考慮すべき作業です。 –

+0

@BRPocockのボリュームはうまくいけば増えているので、私は最高のスケーラビリティを提供するスイートスポットを見つけようとしています。フレームはストリーミング/リアルタイムです(問題のフレームは個々のTCPパケットだけです)。私は、最も安全でスケーラブルなファイルのクローズとベストパフォーマンスの可能性のあるファイルのバランスを取ろうとしています。 –

答えて

1

ガード付きの答え:

  • 扱うファクトリクラスを作成:
    • を指定したファイルがまだ開いている場合は、プールから開いているファイルハンドルを返すと、
    • 長男(最低使用頻度)ファイルハンドルを閉じて、比較的長い期間のオフタイマーどれも用意されていない場合 (お使いのシステムのための合理的なようだいくつかの調整上限)
    • 火災(30代?分?)いくつかの時間のために使用されていないファイルハンドル

にもちろん

/* initialize once */ 
    FilePool.setLimit (maxFiles); 

    /* called often */ 
    FilePool.getFile(ident); 
    FilePool.closeFile(handle); 

    /* protected/internal/… */ 
    boolean FilePool.reachedLimit(); 
    FilePool.closeLeastRecentlyUsed (number); 
    OnTimer → FilePool.closeIdleFiles (duration); 

のようなものを閉じるために、これは、ファイルのオープン/クローズが実際にあるという程度の意味がありますいつでも浪費する。

既存のシステムの負荷テストを行い、両方のマシンにかかる時間をプロファイルすることができれば、あなたの特定のニーズに対応することができます。

+0

ありがとう、私はこれが私がやっていることだと思います。私はFileキーに基づいてOutputStreamを返す非静的プールオブジェクトにします(おそらく私が無視するFileオブジェクトに一致するいくつかの問題があります)。基本的に示すように、キャッシュされたStreamまたは新しく開かれたストリームを、他のプール管理機能とともに戻すことができます。 –

3

TCP接続ハンドシェイクなどを確立するには10〜100秒かかるので、理想的には非常にとなりません。あなたの説明を見て、私は間違いなく接続を開いたままにしておきます。有効な帯域幅はとなります。新しい接続を作成し続けると、実際にはに制限されます。

シャットダウン時に接続が切断されることに注意してください。オブジェクトが定義されたスコープから離れる場合は、gc時にシャットダウンされます。接続をスコープに入れて、それを利用できないかどうかを確認してください。

アップデートはちょうどあなたがディスクを意味コメントを見ました。しかし、同じ議論が適用されますが、ファイルを開くには一般に数ミリ秒しかかかりません。おそらく10ミリ秒程度です。

+2

これは彼が再オープンしているディスクファイルであり、TCPストリームではありません。 – Alnitak

+0

申し訳ありません............ –

3

IMHO、ファイルハンドルを開いたままにしておく方がよいと思います。

私はstracedという年月をかけてソケットを介してファイルを転送するプログラムの終わりはありません。また、宛先ファイルを繰り返し閉じて開いたこともありません。

また、ファイル名に受信ストリームを書き込んで、完了時に正しいファイル名に変更するだけです。

+0

これらのプログラムは複数の接続を処理していましたか? –

+0

@ increment1は前者です。 – Alnitak

関連する問題