Elasticsearchのindex分割について考える

ITインフラ関連の仕事をしていると、日々いろんなところからログを集めて可視化するということがままあります。

そんなとき、Elasticsearchがそこそこ使われていると思うのですが、そのindexについて考えます。

logstashで何も考えずにElasticsearchへログを投げていると、だいたい、indexが1日ごとに作成されているかとおもいます。

Elasticsearchへのログ保管の要件として、1週間とか1か月とか、ログの検索したい時期によって変わってきます。

そんな時、いつでも1日ごとにindexを分ける運用でいいんでしょうか?

リソースが無限にあればいいですが、実際はそうでもありません。CPUもメモリも限られています。

ではどのくらいがいいのでしょうか。それもケースバイケースなのですが

Elasticsearch 7以降では、デフォルトで1ノードのshard数は1000に制限されています。通常、ノード障害に備え、replicaは1以上にする必要がありますので

2ノードの clusterでは、primary shard 数としては1000が限界ということになります。

2ノードあたり 1000 shard という数は多いでしょうか、少ないでしょうか。

それも扱うログの数によって変わってきます。 たとえば100サービスあって、100indexが毎日つくられるとすると、 100x2(replica)x1(shard)x7=1400shard となり、 2ノードでは足りず、3ノード必要となります。

また、1shardあたりのサイズは10-50GB程度がちょうどよいとされています。shardが増えるごとにデータが増えるのとは別でCPUやメモリを消費するからです。大きすぎると検索パフォーマンスに影響が出ます。

たくさんのサービスがあり、それぞれが生成する1日当たりのログサイズが2,3GBしかないというケースでは、そもそも1shardのサイズが小さすぎ、もったいない。という状況になります。

では、 indexを日付で分けず、indexあたりのshard数を適切な数字に設定すればよいでしょうか。

実はそうでもありません。ディスクにも限りがあるので、古いデータは削除して容量をあけていく必要があるのです。削除するためにindexを検索して対象を探して削除する、というのはまぁ負荷がかかります。

それに対し index丸ごと削除するのであれば、そこまで負荷もかからず、短時間で終わります。

ですので、数日単位で適切にindexを分割するということや、 別サービスであっても、ログの schemaが同じであれば、同じindexに入れて、検索時にカラムを指定してわけられるようにする。

といった方法で いい感じにまとめていく必要があります。これは完全にケースバイケースなので、うまくやる方法を個別に考える必要があります。

数日単位でindex分割する。というのは、 保存期間が30日以上など、そこそこ長い期間の時に有効です。 1週間ごとにindexをわければ、 30日データがほしければ 37日分くらいのデータが保存できるストレージを用意することで、35日たったindexを削除するという方法で 削除負荷もほとんどなく、いい塩梅に調整できるでしょう。

別サービスだけどschemaが同じものをまとめる場合は、1日あたりないしは1つのindexにまとめる日付単位の実際のログデータ量を見て、10-50Gが1shardになるとよいというのを基準にまとめていく作業が必要となります。

こんな感じに、時系列のログデータをいい感じに Elasticsearchで扱うには、すこし、indexの分割について考える必要があります。

程よい分割と集約を行い、値段あたりのパフォーマンスを向上させていきましょう。