0

私はこれについてすべて間違っているかもしれませんが、ここに私の問題と提案された解決策があります:

非常に迅速に処理する必要がある数億の独立したレコードを含む 50 ギガバイト以上のファイルがあります。私の現在のソリューションは、1 時間あたり 7,400 万レコードを取得しています。I/O スレッドにブロッキング キューを使用しています。各ワーカー スレッドは、このキューからデータのチャンクを取得しようとします。

上記は、I/O スレッドとワーカー スレッド間のミューテックスの競合により、かなり遅くなります。

ロックなしでこのスタイルのプロデューサー/コンシューマーを行う方法はありますか?

4

3 に答える 3

1

ブロッキングキューを使用してワーカースレッドをそこからプルするのではなく、各スレッドに独自のキューを与え、I/Oスレッドに作業のバッチを各スレッドのキューにプッシュさせます。

各キューにプッシュできるアイテムの数を追跡するために何らかの方法を実装するために余分な労力を費やしてもかまわないと仮定すると、循環キューはこれに非常に適しています。I / Oスレッドがワーカースレッドが新しいレコードを処理しているよりも速く新しいレコードを読み取っている場合は、未処理のレコードを上書きしないように注意する必要があります。

レコードが上書きされないようにする1つの方法は、ワーカースレッドにメッセージを送信させて、処理されたレコードの数でI/Oスレッドを更新することです。このアプローチではロックは必要ありません。I/Oスレッドを頻繁に更新するためのアトミック操作のみ。

これとは別に、最後のバッチをキューにプッシュするときに、ノンブロッキングI / Oを使用してより多くのレコードを読み取ることにより、パフォーマンスを向上させることもできます。また、ボトルネックがディスクアクセスなのか処理なのかを知るのにも役立ちます。

于 2011-05-04T15:05:57.313 に答える
0

シングルプロデューサーシングルコンシューマー(SPSC)のロックフリーキューが存在します。そして、これから、プロデューサースレッドにラウンドロビン方式で各ワーカーに作業をディスパッチさせることができます(ワーカーごとに1つのキュー)。一部のキューがいっぱいになる可能性があることに注意してください。この場合は無視してください(このラウンドでは)。

IOについて:実際にファイルを分割できますか?レコードの終わりを検出する安価な方法がある場合は、ファイルを分割してさまざまな部分を別のマシンに配置するのが簡単な場合があります。または、より高速なHDDを購入するだけです。

于 2011-05-04T15:07:45.543 に答える
0

コンシューマーがアクセスするキューに実行可能なサイズのチャンクを入れる単一のリーダー スレッドはどうでしょうか。または、ファイルリーダーが別のチャンクを読み取るたびに取得するキューに、コンシューマーに独自の ID を入れてもらいます。後者はおそらくリーダーを頻繁にブロックしないでしょう。

于 2011-05-04T15:01:26.590 に答える