1.はじめに
Elasticsearchのインデックスでは、シャードの内部にLuceneのインデックス構成をとっており、ドキュメントの削除が行われてもすぐにファイルを削除することはせずに、一定のタイミングでマージ処理によって変更・削除をファイルに反映している。
そのためマージ処理が実行されるまでは一時的にデータが肥大化してしまうので、マージ処理について調整できるものがないかを調査した。
2.Luceneのインデックスについて
Luceneのインデックスでは、複数のドキュメントをまとめてLuceneセグメントに格納しており、セグメントは一度作成されたら中身のドキュメントを編集したり削除したりすることのないImmutableなファイルとなる。
ドキュメントに削除があった場合、セグメントに削除マークを付与し、一定のタイミングでマージ処理を実行してセグメントの変更・削除を反映させている。
3.Mergeについて
マージ処理では、小さなセグメントをより大きなセグメントにマージしたり、削除マークのついたドキュメントを削除したりしている。
マージ処理は、他のマージ処理や検索などの処理とハードウェアリソースを調整してMerge schedureingで自動実行される。
4.Merge schedureingについて
マージ操作を必要に応じて自動実行する。
マージ処理は別々のスレッドで実行され、スレッド数の上限に達した状態で、それ以上マージ処理を実行しようとする場合は、マージスレッドが使用可能になるまで待機する。
マージに使用するスレッド数については、設定を動的に変更することが可能である。
マージスレッド数の設定
- 設定名:index.merge.scheduler.max_thread_count
- 内容:単一のシャード上で動作するマージ処理に使用するスレッド数の最大値
-
デフォルト:
SSDに最適化された設定(CPUの数に応じて1~4が設定される)
Math.max(1, Math.min(4, Runtime.getRuntime().availableProcessors() / 2)) -
注意点:
デフォルトではSSDに最適化された設定になっているが、
SSDを使用せずHDDなどのように回転するディスクを使用する場合は1を設定する必要がある。
(並列IOが出来きないドライブはマルチスレッドで処理できないためだと思われる) -
変更方法:
動的変更が可能である。そのため、update-index-settings APIを使用して動的に変更することが出来る。
PUT /{index}/_settings
{
"index" : {
"index.merge.scheduler.max_thread_count" : 2
}
}
5.調査結果
マージ処理はMearge sceduringによって必要に応じて自動実行されており、その条件を設定したり頻度を明示的に変更することは出来なさそうだった。
マージ処理に使用するスレッド数を変更することは可能ですが、デフォルトでSSDに最適化されているので、一時的にデータ量が多くなってしまいますが、Elasticsearchが自動的に消してくれるのを待つのがよいのかと思われます。
スレッド数はどの程度まで変更してもよいのかが難しいですが、効果的に変更できればマージスレッド使用可能待ちを減らすことができ、マージ処理の実行頻度が向上する可能性はあるかもしれないです。
6.参考
1.Elasticsearch 6.2のリファレンス - Merge
2.あなたの知らないElasticsearch設定トップ5 - 5番に記載があります
3.Elasticsearch実践ガイド P.225
7.補足_Elasticsearchのインデックスの構成
Elasticsearchではインデックスファイルを構成する際に、
下記のようにしてLuceneのインデックスの構成をとっている。(粒度の大きい順)
-
Elasticsearchインデックス:
複数のシャードで構成されている。 -
シャード:
Luceneインデックスに該当するもの。 -
Luceneインデックス:
複数のLuceneセグメントから構成されている。 -
Luceneセグメント:
ドキュメントが格納されている。一度作成されたら中身のドキュメントを編集したり削除したりすくことのない変更されないファイルとなる(immutable)。ドキュメントが削除される場合はセグメントに削除マークがつけられる。