- はじめに
- Lucene
— Lucene とは
— Elasticsearch と Lucene
— Lucene のデモ
—– Lucene を取得
—– 展開して CLASSPATH を指定
—– インデックスの作成
—– 検索してみる - 再掲・Deleted Documents
— なぜ Deleted Documents なのか
— Lucene は削除したドキュメントをどのように処理しているのか
— Deleted Documents のマージ処理について
— Deleted Documents の検索への影響について
— Expunge Deletes について
— Time-Based Indices(時間ベースのインデックス?) - 以上
— まとめ
— すいません
— 再掲・Deleted Document
はじめに
Elasticsearch と言うか、Elasticsearch や Solr の基盤となっている Lucene の話になると思います。
- Lucene’s Handling of Deleted Documents | Elastic
- Designing the Perfect Elasticsearch Cluster: the (almost) Definitive Guide
- https://lucene.apache.org/core/7_1_0/core/org/apache/lucene/codecs/lucene70/package-summary.html#file-names
上記のブログ記事を自分なりに整理してみましたが、内容には誤りや古い情報が含まれている可能性があるので、誤りがあればご指摘頂けると嬉しいです。
Lucene
Lucene とは
- Java で実装された全文検索エンジン
- Lucene は検索エンジンライブラリとして提供されていて、検索アプリケーションとして Solr が提供されているという理解(Elasticsearch も同様に Lucene を利用した検索アプリケーションという感じなのかな)
Elasticsearch と Lucene
Elasticsearch インデックスと Lucene インデックスについて、こちらの記事の下図が解り易かったので転載させて頂きました。
- Elasticsearch Index はシャードと呼ばれる物理的な概念で各ノードに分散配置される
- シャードが Lucene Index となる
- Lucene Index には最大で 2147483519 個のドキュメントを含めることが出来る
- Lucene Index はセグメントと呼ばれるファイルに分割されている
Lucene のデモ
Lucene を取得
cd /tmp/ wget http://ftp.jaist.ac.jp/pub/apache/lucene/java/7.1.0/lucene-7.1.0.zip
展開して CLASSPATH を指定
unzip lucene-7.1.0.zip export CLASSPATH=lucene-7.1.0/core/lucene-core-7.1.0.jar:lucene-7.1.0/queryparser/lucene-queryparser-7.1.0.jar:lucene-7.1.0/analysis/common/lucene-analyzers-common-7.1.0.jar:lucene-7.1.0/demo/lucene-demo-7.1.0.jar
インデックスの作成
java org.apache.lucene.demo.IndexFiles -docs lucene-7.1.0/docs
インデックスの作成が終わると、カレントディレクトリに index
というディレクトリが作成されます。
$ tree index index ├── _0.cfe ├── _0.cfs ├── _0.si ├── _1.cfe ├── _1.cfs ├── _1.si ├── segments_1 └── write.lock 0 directories, 8 files
各ファイルの概要については、以下のドキュメントに記載されています。
ほうほう、これが Lucene のインデックスなんですな…位のレベルの理解に留めておきます。(とても奥深そうなので)
検索してみる
以下のように lucene
というキーワードで検索してみると以下のように出力されました。
$ java org.apache.lucene.demo.SearchFiles Enter query: lucene Searching for: lucene 6221 total matching documents 1. lucene-7.1.0/docs/core/allclasses-noframe.html 2. lucene-7.1.0/docs/test-framework/allclasses-noframe.html 3. lucene-7.1.0/docs/analyzers-common/allclasses-noframe.html 4. lucene-7.1.0/docs/core/allclasses-frame.html 5. lucene-7.1.0/docs/analyzers-common/allclasses-frame.html 6. lucene-7.1.0/docs/spatial3d/overview-tree.html 7. lucene-7.1.0/docs/test-framework/allclasses-frame.html 8. lucene-7.1.0/docs/queryparser/allclasses-noframe.html 9. lucene-7.1.0/docs/changes/Changes.html 10. lucene-7.1.0/docs/benchmark/allclasses-noframe.html Press (n)ext page, (q)uit or enter number to jump to a page.
Lucene のドキュメントから lucene
というキーワードが含まれているドキュメントの HTML 一覧が出力されるようです。
再掲・Deleted Documents
なぜ Deleted Documents なのか
- そもそも Deleted Documents って何なのか解っていなかった
- ググっていたら Elastic のブログ Lucene’s Handling of Deleted Documents に出会った
以下、こちらのブログについて、個人的な解釈をまとめていきます。
あくまでも個人的な解釈の為、誤り等が散見されると思いますが、その際はコメント等でご指摘頂けると幸いです。
Lucene は削除したドキュメントをどのように処理しているのか
- 削除又は更新時はセグメントにビットをマークしてドキュメントが削除されたことを記録する(論理削除)
- 論理削除されたドキュメントは検索時にスキップされる
- 論理削除したドキュメントの領域はセグメントがマージされるまでは再利用されない
- 削除されたドキュメントでのみ存在する用語(?)はマージするまでは削除されない(削除されたドキュメントはマージするまでディスク領域を消費する)
Deleted Documents のマージ処理について
- Lucene のマージポリシーは TieredMergePolicy と呼ばれるポリシー
- TieredMergePolicy は削除されたドキュメントを再利用を優先する
- 時間の経過と共により多くの削除を持つセグメントがマージの対象となる
index.merge.policy.reclaim_deletes_weight
はマージを制御する設定項目- どのくらい削除対象をマージするかを指定
- あまり大きくしすぎると危険らしい
Deleted Documents の検索への影響について
- Deleted Documents はあくまでも論理削除されただけで、検索時にはこれらをスキップするだけ
- Deleted Documents が多くなれば検索パフォーマンスに影響を及ぼす
- ブログ記事によると…
- 100MB の Lucene インデックスとその Lucene インデックスを 50% 削除したインデックスで QPS を比較
- 20% 1〜 50% 弱のパフォーマンス劣化が見られた
Expunge Deletes について
- Elasticsearch の Optimize API(Elasticsearch 2.1 以降は Merge API)の
only_expunge_deletes
は Lucene のIndexWriter.expungeDeletes
メソッドを呼び出す only_expunge_deletes
が付与された場合にはセグメント全体の 10 % を超える削除があるセグメントのマージが行われる(という理解)- Elasticsearch のドキュメントでは
only_expunge_deletes
フラグの説明は以下の通り記載されているonly_expunge_deletes
フラグが立っていると、削除されたセグメントのみマージ処理が行われる- デフォルトは
false
になっている
Expunge Deletes の挙動について、以下の記事がとても参考になりました。
qiita.com
有難うございます。
Time-Based Indices(時間ベースのインデックス?)
- Elasticsearch では追加したドキュメント毎に生存時間を指定出来る
- 指定した時間を過ぎるとドキュメントは自動削除されるが、時間の経過と共に削除処理が重くなる
- セグメント内の全てのドキュメントが削除された場合(全てのドキュメントに削除フラグが立つと)、それらのドキュメントのマージを待つことなく削除されるので、マージ処理と比較すると効果的
以上
まとめ
- Deleted Documents は Lucene インデックスのセグメントで削除フラグが立っているが、マージ処理が行われていないドキュメントのこと
- Deleted Documents は 検索時にスキップされるだけで、検索性能に影響を与える(20 〜 50% 程度の検索パフォーマンスの劣化が見られる)
- Lucene のデフォルトマージポリシーは TieredMergePolicy と呼ばれるマージポリシーが適用される
- Elasticsearch の Marge API での
only_expunge_deletes
フラグが立っていると、削除されたセグメントのみマージ処理が行われる
すいません
Google 翻訳しながら読んだので半分も理解出来ていない可能性がありますが、Lucene のレベルまで切り込んで Elasticsearch について考えたことが無かったのでとても良い経験になりました。
再掲・Deleted Document
- 基本的には Elasticsearch が自動で Merge 処理をしてくれるので、それに任せた方が良いと考えています