最初に
このページで話すこと
Elasticsearch のシャード数削減の説明だけではなく、
実際の運用現場での事例をもとに、
どのような問題があって、どう対処したのか、
にフォーカスして説明します
検証環境
- Elasticsearch 7.17
- 以前: Elasticsearch 6.8
- OS: Rocky Linux8
月次インデックスの年次集約による削減
背景
いろいろな需要から、
各種用途の月次インデックスを、数年分残していました。
あるとき、Elasticsearch 6.8 から 7.17 に移行したところ、
すぐにシャード数があふれてしまいました。
原因は2つ
- インデックス1つのシャードを、プライマリ5台+レプリカ1台の6台に分散していた
- Elasticsearch6系から7系に移行したことで、シャード数の上限管理が厳しくなった
1年間で72シャード、それが複数インデックス分×数年保持なので、
7.17 のデフォルトの限界値(シャード数 1000)を超えたようです。
対処としては、
- 暫定的に、月次インデックスを年次インデックスに集約する
- かつ、年次インデックスのシャード数を減らす
- 恒久的には、最初から年次インデックスを使用する
暫定対処
- health で現在のシャード数を確認 (エビデンスとして残すため)
curl localhost:9200/_cat/health
- 現在の月次インデックスの状態を確認 (エビデンスとして残すため)
curl -s localhost:9200/_cat/indices/daily_report_2024*?pretty
- 集約用(年次)のインデックスを作成する
curl -XPUT -H 'Content-Type: application/json' localhost:9200/daily_report_2024?pretty -d ' { "settings": { "number_of_shards": 1, "number_of_replicas": 1 } }'
- データを参照する場合でも、頻度が低ければ number_of_shards は減らしていいはず
- 参照しないのであれば、ILM でコールドフェーズやフローズンフェーズに移動するのもあり
- 月次のインデックスを年次のインデックスにコピー(集約)する
curl -XPOST -H 'Content-Type: application/json' localhost:9200/_reindex?pretty -d ' { "source": { "index": ["daily_report_202401", ... "daily_report_202412"] }, "dest": { "index": "daily_report_2024" } }'
- 年次インデックス作成確認
curl -s localhost:9200/_cat/indices/daily_report_2024?pretty
- 出力結果
green open daily_report_2024 <uuid> 1 1 1234 0 4.4mb 2.2mb
- 1234 の部分がプライマリのシャード数。ここが増えるまで待つ
- 出力結果
- シャード数確認
curl -s localhost:9200/_cat/shards/daily_report_2024?pretty
- 出力結果
daily_report_2024 0 p STARTED 1234 2.2mb 192.0.2.1 els-1 daily_report_2024 0 r STARTED 1234 2.2mb 192.0.2.2 els-2
- 1234 の部分がプライマリのシャード数。ここがレプリカと同じ数値ならOK
- 出力結果
- 検索確認
- 意図したレコードが出てくればOK
curl -s localhost:9200/daily_report_2024/_search?pretty
- 月次インデックスの削除
curl -XDELETE localhost:9200/daily_report_20240*?pretty curl -XDELETE localhost:9200/daily_report_20241*?pretty
- 名前を工夫すればもっと簡単に消せると思います
- 月次インデックス削除確認
- 年次インデックスだけ出てくればOK
curl -s localhost:9200/_cat/indices/daily_report_2024*?pretty
- health でシャード数低下の確認
curl localhost:9200/_cat/health
- 出力結果
174000xxxx 00:01:36 els-cluster green 3 3 1192 596 0 0 0 0 - 100.0%
- 1192 の部分が、全ノードの合計シャード数
- 出力結果
恒久対処
- 少量のデータしか入れないのであれば、月次単位ではなく年次単位のインデックスを作る
- 過去分は閲覧頻度も低いはずなので、shrink でプライマリの数を減らす(例: 5 => 1)
- 可能であれば、2年保存など区切りをつけておく(要関係者と相談)
シャード数のあふれ確認
1ノードのシャード上限数はデフォルトで1,000。
例えばノードが3つなら、/_cat/health
の結果が 3,000シャード未満であればOK。
増え方にもよりますが、体感70%未満なら安全圏だと思います。
ILM による保存期間の変更による削減
背景
前述のシャード数あふれの対応後、
1か月でまたシャード数があふれてきました。
今回の原因は、定期的に削除している日次インデックスの増加によるもの。
定期的な削除をしていても、
インデックスのと保持日数が多ければ、シャード数は超過します。
対策としてはシンプルに、
保持日数を減らす、というのが、
需要の面、対応難度の面からみても対処しやすいでしょう。
暫定対処
- health で現在のシャード数を確認 (エビデンスとして残すため)
curl localhost:9200/_cat/health
- 現在のポリシーの確認
curl localhost:9200/_ilm/policy/report_policy?pretty
- 以下、確認ポイント
"phases" : { "delete" : { "min_age" : "60d", => 削除するまでの期間
"in_use_by" : { "indices" : [ daily_report_202401 => ILM対象のインデックス daily_report_202402
- 以下、確認ポイント
- ポリシー更新
curl -XPUT -H 'Content-Type: application/json' localhost:9200/_ilm/policy/report_policy?pretty -d ' { "policy" : { "phases" : { "delete" : { "min_age" : "30d", "actions" : { "delete" : { "delete_searchable_snapshot" : true } } } } } }'
- 更新後のポリシーの確認
curl localhost:9200/_ilm/policy/report_policy?pretty
- min_age が変更後の値に変わっていること
- 一番古いインデックスの ILM の状態を確認する
curl localhost:9200/_ilm/policy/daily_report_202401?pretty
- 以下、確認ポイント
"age" : "40.98d", "phase" : "delete",
- 変更後の期間を過ぎたインデックスの phase が delete になっていればOK
- 以下、確認ポイント
恒久対処
保持日数削減によるシャード数低下は一時的なものです。
今後、インデックスが増えればまた再発します。
なので、インデックスを使用する関係者と相談し、
最低限必要な保持日数を減らしたり、
不要なインデックスを削除するなどの検討が必要です。
phase = delete になったインデックスはすぐには消えません。
しばらくすると消えます。