web-dev-qa-db-ja.com

大量のデータを処理する低結合

通常、リスト、セット、およびマップを交換するクラスを作成することで、疎結合を実現します。現在、Javaバッチアプリケーションを開発していますが、メモリが不足しているため、すべてのデータをデータ構造内に配置できません。データの1つのチャンクを読み取って処理してから、処理する必要があります。次のデータに移動します。したがって、読み取るデータがまだあるかどうかなどをどこかで確認する必要があるため、結合が少ないことははるかに困難です。

私が今使っているのは:

ソース->プロセス->永続化

処理するクラスは、読み取る行がまだあるかどうかをSourceクラスに要求する必要があります。

そのような状況でのベストプラクティスや有用なパターンは何ですか?

私に言わないにしても、私は自分自身を説明していると思います。

コメントから、Javaを使用していることがわかります。さまざまな キュー 実装を見てください。特に、 BlockingQueueproducer-consumer シナリオに役立ちます。 2つのキューを作成できます。1つはソース(データのプロデューサー)とプロセス(データのコンシューマー)の間にあり、もう1つはプロセス(結果のプロデューサー)と永続(結果のコンシューマー)の間にあります。

容量が制限されたブロッキングキューを使用すると、効率的なシステムを実装するのはかなり簡単です(ボトルネック部分は、100%の時間、データが供給され続けます)。データの量に関係なく、限られた量のメモリのみを使用します。

7
Joonas Pulakka

(Joonas Pulakkaからの)ブロッキングキューは、頑丈な答えです。より簡単な答えがうまくいくかもしれません。すべてのデータがソースに保存されている場合は、プロセッサに参照を渡すだけで、ソースからデータを取得できます。もちろん、これはおそらくあなたが過去にやっていたことです。ソースのメモリにすべてのデータがない可能性があり、必要な低結合が得られない可能性があります。

次のステップは、列挙子またはイテレーターインターフェイスを使用することです。 (イテレータはJavaでより一般的ですが、ほとんどの場合、そのremoveメソッドは単なるニュアンスです。)プロセッサはソースからイテレータを取得し、完了するまでメソッドを呼び出します。ソースがどこかからテラバイトのデータをプルしている場合、各呼び出しには時間がかかることがあります。ただし、キューに何かが入るまでプロセッサをスリープ状態にする場合は、自動的にスリープ状態になります。また、ソースがプロデューサーよりも進んでいる場合、ソースはプロデューサーがhasNextおよびnextを呼び出すのを自動的に待機します。

一方、ソースがitsソースからできるだけ早くデータを取得し、プロセッサが追いつくまでデータを備蓄したい場合は、not座って待っています。プロセッサが処理すると、キュー(および複数のスレッド)は、より複雑な場合でも、良いアイデアのように見え始めます。これで、ソースはより高速に実行できるときにデータを積み上げることができ(その制限はおそらくディスクI/Oのようなものです)、プロセッサはitがより速く実行できるときに、積み上げのサイズを減らすことができます((その制限は、永続化モジュールがデータを永続化できる速度です)。

2
RalphChapin