Lucene で増分インデックスを作成した後にインデックスを最適化する必要がありますか?
-
02-07-2019 - |
質問
完全なインデックスの再作成は 7 日ごとに実行されます (つまり、Lucene インデックスと増分インデックスを 2 時間ごとに作成します。私たちのインデックスには約 700,000 のドキュメントが含まれており、完全なインデックスを作成するには約 17 時間かかります (これは問題ではありません)。
増分インデックスを実行する場合、過去 2 時間以内に変更されたコンテンツのみにインデックスを作成するため、所要時間は大幅に短縮され、約 30 分です。ただし、この時間の多く (おそらく 10 分) が IndexWriter.optimize() メソッドの実行に費やされていることがわかりました。
の Luceneよくある質問 は次のように述べています。
IndexWriter クラスは、インデックス データベースを圧縮し、クエリを高速化する optimize() メソッドをサポートします。ドキュメント セットの完全なインデックス作成を実行した後、またはインデックスの増分更新後にこのメソッドを使用するとよいでしょう。増分更新によってドキュメントが頻繁に追加される場合は、最適化による余分なオーバーヘッドを避けるために、最適化を時々のみ実行する必要があります。
...しかし、これでは「頻繁に」が何を意味するかについては何も定義されていないようです。最適化は CPU を大量に消費し、IO も非常に大量に消費するため、できる限り最適化は行わないほうがよいでしょう。最適化されていないインデックスでクエリを実行すると、どのくらいのヒットが発生しますか (特に、完全なインデックスの再作成後のクエリ パフォーマンスと、たとえば 50,000 個のドキュメントが変更された 20 個の増分インデックスの後との比較について考えています)。インデックスを増分するたびに最適化する必要がありますか、それともパフォーマンスの低下にはその価値がありませんか?
解決
マットさん、現在のプロセスにどれくらいの時間がかかるかよくわかっているようですので、削除することをお勧めします。 optimize()
そしてその影響を測定します。
この 2 時間の間に多くのドキュメントが変更されますか?ごく一部 (50,000/700,000 は約 7%) のみが増分的に再インデックスされる場合、そのインデックスから多くの価値が得られるとは思えません。 optimize()
.
いくつかのアイデア:
- インクリメンタルを行わないでください
optimize()
全然。私の経験では、とにかくクエリの大幅な改善は見られません。 - を実行してください
optimize()
2時間ごとではなく毎日。 - を実行してください
optimize()
取引量が少ない時間帯(これが Javadoc と言う)。
そして必ず測定を行ってください。この種の変更は、それがなければ暗礁に乗り上げてしまう可能性があります。
他のヒント
アン optimize
この操作はインデックス全体の読み取りと書き込みを行うため、IO 負荷が非常に高くなります。
最適化操作の背後にある考え方は、Lucene インデックス内のさまざまなセグメントをすべて 1 つの単一セグメントに再結合することです。これにより、クエリごとに複数のファイルを開いて検索する必要がなくなるため、クエリ時間を大幅に短縮できます。(結合された構造ではなく) 通常の Lucene インデックス ファイル構造を使用している場合は、コミット操作ごとに新しいセグメントを取得します。インデックスの再作成と同じだと思いますか?
私は思う マット 彼は素晴らしいアドバイスを持っています。私は彼の言うことをすべて尊重します - あなたが持っているデータに基づいて行動してください。実際にはさらに一歩進んで、a) 必要な場合と、b) クエリ量が少ない場合にのみ最適化します。
クエリのパフォーマンスはインデックス内のセグメントの数と密接に関係しているため、単純な ls -1 index/segments_* | count
最適化が本当に必要な場合に役立つ指標となる可能性があります。
あるいは、クエリのパフォーマンスとボリュームを追跡し、ボリュームが許容範囲内で許容できないほど低いパフォーマンスに達したときに最適化を開始する方が、より良い解決策になります。