Solrj を使用していくつかのファイルのインデックスを作成していますが、ConcurrentUpdateSolrServerクラスを使用すると奇妙な動作に気付きました。私の目標は、ファイルを非常に高速にインデックス化することです (1 秒あたり 15000 ドキュメント)。
8 つの CPU を搭載した Linux 上の離れた仮想マシン (VM) に Solr インスタンスを 1 つセットアップし、Eclipse を使用して自分のコンピューターに Solrj で Java プログラムを実装しました。私の問題を説明するために、私が試した両方のシナリオについて説明します。
シナリオ 1 :
eclipse を使用して Java プログラムを実行し、サーバーを定義するドキュメントに次のような VM のアドレスでインデックスを付けました。
String url = "http://10.35.1.72:8080/solr/";
ConcurrentUpdateSolrServer server = new ConcurrentUpdateSolrServer(url,4000,20);
そして、それを行うThreadを拡張する Java クラスを作成するドキュメントを追加しました。
@Override
public void run(){
SolrInputDocument doc = new SolrInputDocument();
/*
* Processing on document to add fields ...
*/
UpdateResponse response = server.add(doc);
/*
* Response's Analysis
*/
ただし、ドキュメントを順次追加することを避けるために、Executorを使用して、次のようにドキュメントを並行して追加しました。
Executor executor = Executors.newFixedThreadPool(nbThreads);
for (int j = 0; j < myfileList.size(); j++) {
executor.execute(new myclassThread(server,new myfileList(j)));
}
このプログラムを実行すると、結果は良好です。すべてのドキュメントは、solr インデックスで十分にインデックス化されています。solr admin で確認できます:
Results :
numDocs: 3588
maxDoc: 3588
deletedDocs: 0
問題は、solrj を使用しないインデックス作成や VM でのインデックス作成に比べて、インデックス作成のパフォーマンスが非常に低い (インデックス作成速度が遅い) ことです。そのため、VM で実行するプログラムの jar ファイルを作成しました。
シナリオ 2 :
そこで、Eclipse で jar ファイルを生成し、VM で実行しました。サーバーの URL を次のように変更しました。
String url = "http://localhost:8080/solr/";
ConcurrentUpdateSolrServer server = new ConcurrentUpdateSolrServer(url,4000,20);
同じドキュメント コレクション(一意の ID を持つ 3588 ドキュメント) を使用して、次のように jar ファイルを実行しました。
java -jar myJavaProgram.jar
Solr Admin での結果は次のとおりです。
Results :
numDocs: 2554
maxDoc: 3475
deletedDocs: 921
この結果は、私のスレッド設定 (Executor と SolrServer の場合) に依存します。最後に、すべての文書が索引付けされているわけではありませんが、索引付けの速度は向上しています。私のドキュメントの追加は、Solr には速すぎて、いくつかの損失があると思います。
スレッドの正しい設定を見つけることができませんでした。スレッドを多く設定しても少なく設定しても、いずれにしても損失があります。
質問:
- ConcurrentUpdateSolrServer Class に関する問題を聞いたことがある人はいますか?
- これらの損失の説明はありますか? 2 番目のシナリオですべてのドキュメントがインデックス化されないのはなぜですか? また、一意のキーを持っているにもかかわらず、一部のドキュメントが削除されるのはなぜですか?
- Solrj を使用してドキュメントを並行して (順次ではなく) 追加する適切な方法はありますか?
データにインデックスを付ける別の Solrj クラスを見てきました: EmbeddedSolrServer. このクラスはインデックス作成速度を向上させますか、それとも ConcurrentUpdateSolrServer より安全にデータをインデックス化できますか?- add() メソッドの応答を分析すると、結果は常に OK (response.getstatut()=0) であることに気付きましたが、ドキュメントのインデックスが適切に作成されていないため、そうではありません。では、この add() メソッドの通常の動作ですか?
- 最後に、誰かがデータを非常に高速にインデックス化する方法についてアドバイスしてくれれば、とても感謝しています! :-)
編集 :
ConcurrentUpdateServer の add() メソッドの各呼び出しの間にThread.sleep(time)を使用して、インデックス作成速度を遅くしようとしました。
ConcurrentUpdateServer の add() メソッドを呼び出すたびに commit() しようとしました (追加するたびにコミットするのは良い解決策ではないことはわかっていますが、テストすることでした)。
Executor を使用してスレッドを管理しないようにしましたが、1 つまたは複数の静的スレッドを作成しました。
ドキュメント コレクションにインデックスを付けるためにこれらのいくつかの戦略をテストした後、EmbeddedSolrServer クラスを使用して結果が改善されるかどうかを確認することにしました。
そこで、 EmbeddedSolrServer を使用するために次のコードを実装しました。
final File solrConfigXml = new File( "/home/usersolr/solr-4.2.1/indexation_test1/solr/solr.xml" );
final String solrHome = "/home/usersolr/solr-4.2.1/indexation_test1/solr";
CoreContainer coreContainer;
try{
coreContainer = new CoreContainer( solrHome, solrConfigXml );
}catch( Exception e ){
e.printStackTrace( System.err );
throw new RuntimeException( e );
}
EmbeddedSolrServer server = new EmbeddedSolrServer( coreContainer, "collection1" );
適切な JAR を追加して機能させ、コレクションのインデックス作成に成功しました。
しかし、これらの試行の後でも、Solr の動作に問題が発生します... 私はまだ同じ損失を抱えています。
Result :
Number of documents indexed :2554
2554 ドキュメント / 3588 ドキュメント (myCollection) ...
私の問題はより技術的なものだと思います。しかし、私のコンピューティングの知識はそこで止まります。:( コンピューターから Java プログラムを実行すると損失が発生しないのに、VM でドキュメントのインデックスを作成すると損失が発生するのはなぜですか?
Jetty とのリンクはありますか (入力ストリームを吸収できないのでしょうか?)。Solr にいくつかの制限があるコンポーネント (バッファ、RAM オーバーフロー?) はありますか?
私の問題について十分に明確でない場合は、教えてください。より明確にしようとします。
ありがとう
コランタン