2016-07-08 5 views
1

30GB(2,500万行)という膨大なファイルを読み込もうとしています。私はスレッドプールを作成し、各スレッドは1000行を並列に読み込みます(最初のスレッドは最初の1000行を読み込み、2番目のスレッドは次の1000を読み込むなど)。 ファイル全体を読み込んでスレッドプールを作成しましたが、今は各スレッドが1000行だけを読み込み、次のスレッドが読み込む必要がないように読み込まれた行番号を確実に追跡できるようにしていますそれらの行。すべてのスレッドがラインのほぼ等しい数を持っているacceaptableならマルチスレッドを使用して30GBファイルを読む

+1

この問題を解決したら、磁気ドライブを使用していますか?それにかかわらず、これはIOバウンドになります。 –

+0

1つのスレッドで大きなチャンク(30GB)を読み取ると、通常は25000スレッドが小さなチャンクを読み取るよりも高速になります。 25000スレッドには多くのオーバーヘッドがあり、1つのディスクに1つのファイルがある場合、各スレッドはキュー内のアクセス時間を待たなければなりません。 –

+5

通常は、ファイルなどの外部リソースを操作するスレッドは1つしかありません。パフォーマンスを向上させないI/Oを配布しようとするのではなく、リーダースレッドが各バンドルを並行キューに入れて、それをexecutorタスクに送信するようにします。 – chrylis

答えて

0

A.、次のことができます。

  1. スレッドプールのサイズがNであると仮定し、第一のスレッドは、30ギガバイト/ Nをオフセット0のファイルと[0を読みしよう)、2番目のスレッドは30GB/Nをオフセットしようとします。[30GB/N、30GB/N * 2など]
  2. 2番目のスレッドは、行の先頭ではなく行の中央にあります。大丈夫です。正義線をスキップして、完全な線を読んでください。第1のスレッドは、部分線で終わってもよい。大丈夫です。「\ n」を読むまで読書を続けてください。残りのスレッドは同じことを行います。すべてのスレッドがラインの正確euqal数を持たなければならない場合

B.は、それはあなたには、1000行を言うことができます:

  1. はインデックスマップを構築し、あるスレッドがファイル全体を読みました。マップはオフセット0から始まるline0〜line999、オフセットline1000〜line1999はオフセット13521で始まるなどの情報を持っています。
  2. すべてのスレッドはそれに応じてオフセットからファイルを読み取り、1000行を読み込みます。

アプローチAはファイルを1回読み取ります。アプローチBはファイルを2回読み込みます。

アプローチAまたはBを使用すると、すべてのスレッドでファイルを処理(変換、抽出、クリーニング)することができます。しかし、処理が非常に速い場合、境界はディスク速度です。次に、アプリケーションはIOバウンドになります。あなたはただ1つのスレッドにファイルを読み込ませ、処理を逐次行わなければなりません。

+0

アプローチBは、私が追求したロジックですが、すでにスレッド間で読み込まれている行番号を共有するという問題がありました。ファイルを読み取る単一のスレッドは、ファイルの内容をキューに入れて、特定の行のキューを同時に読み取るのが面倒になります。すでに読み取られた行を示すスレッドセーフカウンタを維持します。 –

+0

「最初のスレッドは最初に読み込みます1000行 "私は、行のグループを一緒に処理する必要があると思った。そのような制約がない場合は、最初の小さなN(1、2、okです)行を読み、1番目のスレッドに与え、2番目の小さなNの行を2番目のスレッドに渡します。 – waltersu

+0

@ChristineDsouzaあなたはすでにアプローチしています。あなたのコードと、スレッドセーフな問題についてのあなたの質問を表示してください。 – waltersu

関連する問題