Luceneインデックスへの10GBのデータのインデックス作成を高速化したいと思います。TPLはこれを行うための良い方法でしょうか?データをチャンクに分割してから、各スレッドにチャンクのインデックス作成を開始させる必要がありますか?
UIのレスポンシブを維持するには、BackgroundWorkerが最善のアプローチ、タスク、またはその他の方法でしょうか。
SOLRはすでにこのようなことをしていますか?それとも、これを自分でコーディングする価値はありますか?
Luceneインデックスへの10GBのデータのインデックス作成を高速化したいと思います。TPLはこれを行うための良い方法でしょうか?データをチャンクに分割してから、各スレッドにチャンクのインデックス作成を開始させる必要がありますか?
UIのレスポンシブを維持するには、BackgroundWorkerが最善のアプローチ、タスク、またはその他の方法でしょうか。
SOLRはすでにこのようなことをしていますか?それとも、これを自分でコーディングする価値はありますか?
Javaを使用していると仮定すると、複数のスレッドを使用してインデックスを作成するのに良い経験があります。Luceneのインデックス作成は、私の経験では基本的にCPUにバインドされています。つまり、N個のスレッドを生成すると、N個のコアすべてを使用できます。
LuceneIndexWriter
は並行性を処理するので、それについて心配する必要はありません。スレッドはindexWriter.addDocument
、準備ができたらいつでも呼び出すことができます。
あるプロジェクトでは、ドキュメントはデータベースのSELECTステートメントから取得されました。N個のスレッドを作成し、それぞれがから次のドキュメントを取得ResultSet
してインデックスに追加しました。行がなくなるとスレッドは終了し、メインスレッドはで待機しましたCountDownLatch
。
2番目のプロジェクトはもう少し複雑でした。システムは一連のドキュメントを「クロール」していました。つまり、最初からドキュメントの数がいくつになるかは明確ではありませんでした。そのため、すでに発見されたドキュメントの「キュー」を維持する必要がありました。そして、それらのドキュメントを分析してインデックスを作成する過程で、キューに追加されたドキュメントをさらに見つけることができました。キューには、最初に初期/シードドキュメントが入力されていました。スレッドを管理するためにクラスAutoStopThreadPoolを作成しました。必要に応じて、ダウンロードしてください。(すべてのタスクを「追加」してから「完了を待つ」必要があるJVMスレッドプール。これは、タスクの処理によって新しいタスクが検出される可能性があるため、適切ではありませんでした)
複数のスレッドを単一のIndexWriterに書き込みたい場合は、次のようなことを行う1つのスレッドを生成します。
Parallel.ForEach(docs, d => { writer.Add(d,analyzer) });
そのため、.NETはデータの分割を処理します。
インデックスサイズが大きい場合、複数のインデックスを書き込んでからすべてのインデックスをマージすると、パフォーマンスが向上することがあります。私の理解では、これは本当に大規模なインデックスに対してのみ本当に役立ちますが、これを実行したい場合は、おそらく自分でデータを分割する必要があります。その場合、tplのようなよりフル機能のライブラリを使用すると便利な場合があります。
Solrは本質的にマルチスレッドであるため、ライターを直接呼び出す代わりに、REST / SolrNetメソッドを呼び出すことを除いて、前に示したのとまったく同じスニペットを実行します。
原則として、「Solrを使用するか、自分で作成するか」と尋ねた場合。答えはほとんどの場合「Solrを使用する」です。jvmが本当に悪いか、javaが本当に嫌いでない限り、ここで自分で作成したいと思う理由は考えられません。