Elasticsearchの"index.mapping.total_fields.limit"を監視する話
Elasticsearchには index.mapping.total_fields.limit
という設定があり、これは何かというと「1つのindexあたりが保存できるフィールドの上限数」を表現しており、この上限に触れると Limit of total fields [1000] in "your_index" index has been exceeded
のようなエラーが発生してindexができなくなります。
この上限への対症療法としては先人たちが示している通り様々あるのでそちらに譲り *1、本記事ではこの index.mapping.total_fields.limit
を監視する方法について考えていきましょう。上にも書きましたが、この上限にヒットするとそのindexに対するindexingが完全にストップするのでマズいんですよ……
(もちろん、Elasticsearchのパフォーマンスを考えると1つのindexに大量のフィールドを生やすのは良くないし、そもそも理性的な使いかたをしていれば起きないことだとは思うのですが……まあ実際にElasticsearchを運用していると色々なことがありますね)
というわけで、johtaniさんに色々教えてもらったことについて以下に記します。いつもありがとうざいます。
情報は取れなそうだから、mappingから数えるとかかなぁ
— Jun Ohtani (@johtani) February 18, 2021
Mappingが変更されるタイミングでチェックしてるだけだからねぇ。https://t.co/l51A1Wgawp
— Jun Ohtani (@johtani) February 18, 2021
なるほど、コードを読んでみると確かにシンプルなリミットチェックを行っているだけっぽい。
これが一番楽そう?(正しい値化は確認してない)https://t.co/wOIWd5DTlt
— Jun Ohtani (@johtani) February 18, 2021
ハハア、なるほど。APIを叩いてそのindexのフィールド数を回収することで現在のステータスを回収しよう、ということですね。
というわけで以下のようなスクリプトを一定周期で流してメトリクスとして回収し、可視化およびアラートを設定することで現状なんとかしております、というお話でした。
for idx in $(curl -Ss "${ES_ENDPOINT}/_cat/indices?format=json" | jq -r .[].index); do num_of_fields=$(curl -Ss "${ES_ENDPOINT}/${idx}/_field_caps?fields=*" | jq '.fields | length') echo "$idx: $num_of_fields" store_metric "$idx" "$num_of_fields" done