はじめに

Elasticsearch と言うか、Elasticsearch や Solr の基盤となっている Lucene の話になると思います。

上記のブログ記事を自分なりに整理してみましたが、内容には誤りや古い情報が含まれている可能性があるので、誤りがあればご指摘頂けると嬉しいです。

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 なのか

以下、こちらのブログについて、個人的な解釈をまとめていきます。

あくまでも個人的な解釈の為、誤り等が散見されると思いますが、その際はコメント等でご指摘頂けると幸いです。

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 の挙動について、以下の記事がとても参考になりました。

##概要インデックスと関連する二つのコマンド(option)を検証します。* expungeDeletes* prepareCommit##expungeDeletesLucene Index 考察(2)で、delete...

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 処理をしてくれるので、それに任せた方が良いと考えています

元記事はこちら

Elasticsearch の Deleted Documents についてメモ