データベース

ElasticsearchのILM|5フェーズの設計とmin_ageの起点・データストリームとの使い分け

AWSを利用したインフラ構築

ILMは「何日で消すか」を書く仕組みだと思って設計に入ると、日数どおりに落ちない索引を前に手が止まります。min_ageは何時点からの経過なのか、書き込み中の索引がなぜ層を降りないのか、cold層に置く前提が有償機能かどうか。詰まる原因はこの三つの前提の取り違えに寄っています。9.5系(2026年8月時点)の公式記述を実測して並べました。

まとめ:ポリシーを書く前に確定させる6つの値と結論

ポリシーのJSONを書き始める前に、次の6点を先に埋めてください。ここが空欄のまま条件だけを書くと、動いてはいるが期待した時期に落ちない索引が積み上がります。

  • 管理の単位:データストリームか、連番索引と書き込み用別名の組か
  • 切替条件:主シャード容量と経過日数のどちらを上限に置くか
  • min_ageの起点:切替時刻からの経過で数える前提になっているか
  • 層の構成:warmで止めるか、cold以降まで落とすか
  • ライセンス:cold・frozenの前提となる機能が契約に含まれるか
  • 仕組みの選択:ILMとデータストリームライフサイクルのどちらを主にするか

結論を先に置きます。無償のBasicで組む基盤なら、層はhotとwarmとdeleteの三つに絞るのが現実的な着地です。cold層とfrozen層の値打ちは検索可能スナップショットにありますが、これはEnterpriseライセンスを必要とする機能で、無償の範囲では層を増やしても保管費は下がりません。保持期間を短く保つだけが目的なら、データストリームライフサイクルのほうが設定量は少なくて済みます。

ILMの三層構造|ポリシーとフェーズとアクションの関係と評価の周期

ILMのポリシーは、フェーズを並べ、フェーズの中にアクションを並べるという二段の入れ子です。索引はポリシーへ紐づけられ、その評価はクラスタ側の周期処理として回ります。この周期の粒度が、設計の見積りに直接効いてきます。

五つのフェーズと、各フェーズで使えるアクションの対応関係一覧

フェーズはhot、warm、cold、frozen、deleteの5つです。すべてを使う必要はなく、要るものだけを並べます。設計に効く主なアクションの可否は次のとおりでした。

フェーズ 切替 縮小・統合 層移動 検索可能スナップショット 削除
hot 可 可 不可 可 不可
warm 不可 可 可 不可 不可
cold 不可 不可 可 可 不可
frozen 不可 不可 不可 可 不可
delete 不可 不可 不可 不可 可

ここから読み取れる制約が二つあります。ひとつは、切替(rollover)がhotにしか置けないこと。warm以降のフェーズで索引を分割し直すことはできません。もうひとつは、frozenで使えるのが実質的に検索可能スナップショットだけであること。frozenは独立した保管層というより、部分搭載という仕組みに専用のフェーズを割り当てたものだと捉えると設計を誤りません。

評価はpoll_interval単位|既定10分という粒度が効いてくる場面

ILMは常時監視をしているわけではなく、周期的に索引を見て回ります。この周期は indices.lifecycle.poll_interval で、既定は10分です。つまり「1分で削除」といった条件を書いても、実際の削除は最大10分ほど遅れて起こります。

これが効いてくるのは検証時です。min_age を数十秒へ縮めて動作を見ようとしても、何も起きないまま待つことになります。周期を1秒へ縮める手はありますが、本番へ持ち込むとクラスタ状態の更新が頻発するため、検証用のクラスタに限ってください。

フェーズ定義は索引側へ写し取られる|更新が既存索引へ届く条件

設計を誤りやすいのがここです。索引があるフェーズへ入った時点で、ILMはそのフェーズの定義を索引のメタデータへ写し取ります。ポリシーを後から書き換えても、すでにそのフェーズへ入っている索引は写し取られた古い定義のまま動き続けます。

この仕様は、ポリシー更新によって索引がフェーズから抜け出せなくなるのを防ぐためのものです。副作用として「直したのに挙動が変わらない」という状況が生まれます。次のフェーズへ移る際には新しい定義が読み直されるので、効き方は「今いるフェーズの残りは旧定義、次から新定義」と覚えてください。

min_ageの起点|切替時刻からの経過で数えるという前提の取り違え

「7日でwarmへ、30日で削除」と書いたのに、実際には想定の倍近く残っている。この相談のほとんどは、min_ageの起点を索引の作成時刻だと思っているところから来ています。

作成時刻起点と切替時刻起点の差、日数計算がずれる仕組みと理由

min_age は既定では索引の作成時刻から測ります。ただし索引がロールオーバー済みの場合、min_age はロールオーバーが行われた時刻からの相対値になります。データストリームや別名方式で運用している索引は、書き込み先から外れた瞬間が起点です。

数えると差がはっきりします。7日ごとに切り替わるデータストリームで「30日で削除」と書くと、書き込み先を外れるまでに7日、そこから30日なので、最古のドキュメントは37日分残る計算です。監査要件が「30日保持」の場面でこの差を無視すると、下限は満たすものの想定より1週間分多くディスクを使い続けます。切替間隔を短くすれば誤差は縮み、そのぶん索引の本数が増えました。ログ側の保持日数の逆算はElasticsearchのログ収集と保持期間の設計に整理しています。

書き込み中の索引は層を降りない|hotに留まる期間の見積り方

もうひとつ押さえておきたいのが、書き込み先になっている索引はフェーズを先へ進めないという性質です。ロールオーバーを含むポリシーでは、切替が起きるまで min_age の計算そのものが始まりません。

ここに条件の設定が絡みます。切替の判定に使えるのは max_ で始まる条件と min_ で始まる条件で、max_ 側は最低1つの指定が要ります。切替が起きるのは max_ 条件のいずれかが満たされ、かつ min_ 条件がすべて満たされたときです。流量の少ないデータストリームで容量条件だけを書くと、条件に届かないまま索引が書き込み先に居座り、hot層のディスクを占め続けました。経過日数の条件を併記するのが安全側の設計です。

hotとwarmの設計|統合と縮小をどちらの層へ置くかという判断

層を分ける狙いは、書き込みが止まった索引を安いノードへ移し、形を整えて容量を削ることにあります。整える操作は二つあり、置き場所で影響の出方が変わります。

warmで縮める二手|セグメント統合とシャード削減の順序と条件

統合(force merge)はLuceneのセグメントを少数へまとめる操作で、削除済みドキュメントの領域が解放されます。縮小(shrink)は主シャードの本数を減らす操作です。どちらもwarmで使えますが、対象は書き込みが止まった索引に限ります。統合のあとに追記が続くと、新しいセグメントが増えて効果が薄れるためです。

順序は縮小のあとに統合を置きます。シャード本数を減らしてからセグメントを整理すれば、統合の対象が減って処理時間も短くなりました。どちらもCPUとディスクI/Oを持っていくので、取り込みの山と重なる時刻には走らせないでください。シャード本数の考え方はElasticsearchのチューニングと遅いクエリの特定で数値とともに扱っています。

層の移動を担うmigrateと、書き換わる配置指定の中身を確認

索引を実際に別の層のノードへ動かすのは migrate アクションです。warm と cold で使え、frozen では使えません。動作は index.routing.allocation.include._tier_preference という配置指定の書き換えです。warm では data_warm,data_hot、cold では data_cold,data_warm,data_hot という順の値が入ります。

この値がカンマ区切りの並びである点に意味があります。先頭の層にノードが無ければ次の候補へ落ちる代替の指定なので、warm層のノードを用意していないクラスタでも索引はhot層に残るだけでエラーにはなりません。層を分けていない構成でポリシーだけ先に書いても壊れないのは、この仕組みによるものでした。自前で配置指定を書いていて上書きされたくない場合は、migrate を明示して enabled を false にします。

coldとfrozenとdelete|有償機能という前提と削除前の安全弁

ここが費用計画の分かれ目です。cold層とfrozen層の値打ちは、データをスナップショット置き場に持たせたまま検索できる仕組みにあり、これには契約上の前提が付きます。

完全搭載と部分搭載|二つの載せ方で変わる応答と占有領域の違い

検索可能スナップショットのアクションは hot、cold、frozen で使え、snapshot_repository の指定が必須です。載せ方は二種類あります。frozen層へは部分搭載として載り、索引名には partial- の接頭辞が付きます。それ以外の層へは完全搭載として載り、接頭辞は restored- です。

完全搭載はスナップショットの内容をクラスタ内へ丸ごと持つため、応答は通常の索引に近くなります。部分搭載が持つのは直近に参照した分だけで、載っていない範囲を検索すると置き場から取りに行く時間が加わりました。frozen層の索引へ日常的な検索を流す設計は、応答時間の約束と噛み合いません。年に数回の監査で開く程度の頻度に合わせた層だと考えてください。

Enterprise前提という制約|無償の範囲で組むときの代替経路

検索可能スナップショットは Enterprise ライセンスを必要とする機能です。ILM そのものは Basic の範囲で使えますが、cold層とfrozen層の費用削減効果はこの機能に依存しています。つまり無償で組む前提の基盤では、cold層を足しても保管費は下がりません。

代替は二つです。ひとつは、検索が要る期間だけをwarmまでで持ち、それ以降は通常のスナップショットとしてクラスタ外の安価な置き場へ出し、必要時に復元する運用。検索の即時性は失われるものの、費用は最も低く収まります。もうひとつは、ライセンス費と削減できるディスク費を並べる判断で、取り込み量が大きく保管年数が長い基盤ほど成立しやすくなりました。系列ごとのライセンスの違いはElasticsearchとOpenSearchの違いと移行先の決め方に整理しています。

deleteの前に置く待機|取り切れていない状態で消さないための指定

deleteフェーズで使えるのは、スナップショット待機と削除の二つです。待機のほうは、指定した取得ポリシーが対象索引を含む形で完了するまで削除を止める安全弁になります。

長期保管をクラスタ外へ出す設計なら、この指定は入れてください。取得が失敗し続けたまま保持日数が過ぎると、退避できていないデータが静かに消えます。待機があれば削除が止まり、失敗として表に出ました。消えたあとに気づく形を避けるための一行です。

データストリームライフサイクルとの分担|二重管理を避ける優先順位

8系の途中から、保持期間の管理にはもう一つの仕組みが並んでいます。データストリームライフサイクルは、層という考え方を持たず、保持期間の指定と背景処理に絞った作りです。ILMは索引とデータストリームの双方を管理でき、機能の幅は広くなります。

保持だけで足りる場面と、層の移動まで要る場面を決める具体的な基準

選び分けの基準は単純です。ノードを性能別に分けていないクラスタなら、層を移動させる先がないため、ILMの機能の大半は使われません。この構成では保持期間の指定だけを持つデータストリームライフサイクルのほうが設定量が少なく、事故も減ります。

逆に、hotにSSDのノード、warmに大容量ディスクのノードという分け方をしているなら、層の移動を担えるのはILMだけです。順序としては、まずノード構成が分かれているかを確認し、分かれていないならデータストリームライフサイクルから始めるのが手戻りの少ない進め方でした。なお、Elastic Stack 9.5 以降は検索可能スナップショットへの移行にも対応が入っています。層を持たない側との機能差は、版が進むごとに縮んでいます。

両方が当たったときの優先順位と、クラスタ側で縛る既定値を確認

同じ索引に両方の設定が乗ることがあります。この場合の優先順位は index.lifecycle.prefer_ilm で決まり、既定は true です。つまり何もしなければILMが勝ちます。データストリームライフサイクルへ寄せたいなら、この値を明示的に false にしてください。移行の途中で「新しく書いた保持設定が効かない」と見えるとき、原因はここにあることが多くなります。

クラスタ側から縛る値も用意されています。保持を書いていないデータストリームへ既定を当てるのが data_streams.lifecycle.retention.default、どこにもこれ以上は許さない上限が data_streams.lifecycle.retention.max です。部署ごとに設定を任せる運用なら、上限を先に決めておくと、誰かが「念のため5年」と書いた瞬間にディスクが伸び始める事態を防げました。切替の既定条件は cluster.lifecycle.default.rollover にあり、9.5系では主シャード容量50gbなどが並びます。評価の周期は data_streams.lifecycle.poll_interval で既定5分と、ILM側の10分より短く設定されています。

データストリームを使わない索引へ当てる|別名方式で要る三つの設定

ILMはデータストリーム専用ではありません。業務検索の索引や、データストリーム導入前から動いている連番索引にも当てられます。ただし切替を伴う場合は、データストリームが暗黙に担う部分を手で組む必要があります。索引の作成や別名の張り替えをアプリ側から呼び出す場合は、ElasticsearchのREST APIとエンドポイント体系の記事で呼び出し口の整理と認証の設計を扱っています。

連番の索引名と書き込み用の別名|起点を作る手順と三つの必須設定

要るのは次の三点です。第一に、ポリシー名を index.lifecycle.name で指定すること。第二に、切替対象の別名を index.lifecycle.rollover_alias で指定すること。第三に、最初の索引を作り、その別名の書き込み先指定を有効にしておくこと。索引名は末尾が連番である必要があり、my-index-000001 のような形にします。

連番が要るのは、切替時に次の名前を機械的に決めるためです。この形式から外れた名前を起点にすると、切替の段で失敗しました。索引テンプレート側にも同じ二つの設定を書いておかないと、切替で作られた新しい索引にポリシーが当たらず、二本目以降が管理から外れます。設定の重複に見えて、どちらも省けません。テンプレートへ載せるマッピング側の設計はElasticsearchのマッピング設計で扱っています。

PUT _index_template/app-log-template
{
  "index_patterns": ["app-log-*"],
  "template": {
    "settings": {
      "index.lifecycle.name": "app-log-policy",
      "index.lifecycle.rollover_alias": "app-log"
    }
  }
}

止まったときの調べ方|explainで現在地と失敗した段を突き止める

設計どおりに落ちない索引が出たとき、ポリシーのJSONを読み返しても原因は分かりません。索引ごとに「今どの段にいて、何で止まっているか」を返すAPIから見ます。

失敗だけを絞る指定と、返る項目のどれを先に見るかという確認順序

状態は GET /_ilm/explain で確認します。索引が多いクラスタでは only_errors=true を付けて失敗しているものだけへ絞ってください。返る項目のうち先に見るのは、phase・action・step の三つです。ここで現在地が分かります。止まっている場合は failed_step にどの段で落ちたかが入り、step_info に理由の文言が入ります。

次に見るのが is_auto_retryable_error です。この値が真なら、失敗した索引はポーリング周期ごとに自動で再実行されます。何度試したかは failed_step_retry_count に積み上がるため、回数が伸び続けているなら再実行では抜けられない原因が残っています。典型は、置き場の未登録でスナップショットが取れない、縮小の移動先ノードに空きがない、といった索引の外側の事情でした。

自動の再実行と手動の再実行|待つ場面と押す場面の具体的な判断基準

原因を直したあとは、次の周期を待てば自動で再実行されます。急ぐ場合は POST /_ilm/retry で即時に再実行できます。既定の10分を待たずに結果を確かめたいとき、たとえば切り分けの最中はこちらを使ってください。

押す前に、直した内容が索引側へ届いているかを確認します。ポリシーの記述を直した場合、今いるフェーズの定義は写し取られた古いものが使われるため、再実行しても同じ段で落ちました。この場合はポリシーの紐づけを付け直してから再実行する順序です。段の失敗と定義のキャッシュは別の話なので、分けて確認してください。

ILMへ任せてよい条件と、手で回したほうが早い場面の判断基準

自動化には設計と検証の手間がかかります。掛けた手間が返ってくる条件と、返らない場面を分けておきます。

任せてよい条件|次の三点が揃うなら設計どおりに落ちていく運用条件

第一に、索引が時間軸で増えていくこと。ログや監査記録のように追記が中心で、古いものから価値が下がる形です。第二に、保持期間が要件として決まっていること。監査規程で年数が示されていれば、min_ageの値は逆算できます。第三に、切替の条件を数値で置けること。1日あたりの取り込み量が分かれば、主シャード容量から間隔が見積もれます。

この三点が揃う基盤では、ポリシーを一度組めば運用の手が離れます。層の分け方と保持期間を要件から起こし、既存の索引を止めずに移す作業は、データ分析基盤構築・MLOps構築支援でも引き受けている範囲です。ディスクが伸び続けて費用の見通しが立たない段階でも、層構成と保持の設計から入れば削減幅は先に計算できます。

見送る場面|本数が少なく期間も読めるなら手動で足りる判断基準

索引が数本しかなく、削除の頻度が月に一度という規模なら、ポリシーを組むより削除のAPIを定期実行するほうが早く終わります。ILMの設計コストは想定どおりに落ちることの確認に集中していて、この確認は索引が実際に日数を経過するまで完了しません。

もうひとつの見送り条件が、Serverless での運用です。ILM は Elasticsearch Serverless では使えず、その環境ではデータストリームライフサイクルが保持の選択肢になります。移行先としてServerlessを検討しているなら、層を前提としたポリシーを今から作り込むほど、移行時に捨てる設計が増えます。版を上げる計画と並行して検討しているなら、Elasticsearchのバージョンアップと移行の判断と合わせて順序を決めてください。製品そのものの前提はElasticsearchの仕組みとシャード設計・採用可否に置いています。

よくある質問

ポリシーを更新すると、動いている索引にも反映されますか?

今いるフェーズの残りには反映されません。索引がフェーズへ入った時点で、そのフェーズの定義が索引のメタデータへ写し取られるためです。新しい定義が読まれるのは次のフェーズへ移るときになります。すぐに反映させたい場合は、対象索引のポリシー紐づけを付け直す操作が要ります。

min_ageの日数どおりにフェーズが進まないのはなぜですか?

起点が索引の作成時刻ではないためです。ロールオーバー済みの索引では、min_ageは切替が行われた時刻からの経過で測られます。7日ごとに切り替わる構成で30日と書けば、最古のドキュメントは37日残る計算でした。書き込み先の索引はそもそも次のフェーズへ進まない点も併せて確認してください。

cold層やfrozen層は無償の範囲で使えますか?

層としての指定はできますが、費用を下げる仕組みである検索可能スナップショットが Enterprise ライセンスを必要とします。Basic の範囲で組むなら、warmまでで検索性を持たせ、それ以降はクラスタ外のスナップショットへ出す構成が現実的な着地になります。

データストリームライフサイクルとILMはどちらを選べばよいですか?

ノードを性能別の層に分けているかどうかで決めてください。分けていないなら移動先が無いため、保持期間の指定に絞ったデータストリームライフサイクルで足ります。層を分けている場合の選択肢はILMです。両方の設定が乗った場合は index.lifecycle.prefer_ilm の既定によりILMが優先されます。

データストリームを使っていない索引にもILMを当てられますか?

当てられます。切替を伴う場合は、ポリシー名と切替用の別名を索引設定と索引テンプレートの両方へ書き、末尾が連番の索引を起点として作り、その別名の書き込み先指定を有効にしてください。切替を使わず削除だけを任せる構成なら、ポリシー名の指定だけで動きます。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.09 テックブログ IDCFクラウド(IDCフロンティア)不正アクセス・ランサムウェア:影響先・復旧・データは戻るか
  2. 2026.10.09 テックブログ ニッスイのサイバー攻撃で日水物流の入出荷停止|委託先クラウド障害に荷主が備える手順
  3. 2026.10.09 テックブログ 京王電鉄のランサムウェア被害とグループ共通基盤:決済・ポイント・予約が止まった範囲と遮断の初動
  4. 2026.10.09 テックブログ スタディサプリの不正アクセスとメールアドレス3,687件|アカウント列挙を防ぐ実装
  5. 2026.10.08 コラム 雇用保険の適用拡大:2028年10月の週10時間以上への変更と、勤怠・労務システムで直す判定ロジック

RELATED POSTS 関連記事

目次