やりたいこと
Amazon Elasticsearch Service(以下Amazon ES)でISMを設定してUltraWarmを動かしたい。
Amazon ES側の公式ドキュメントの説明が少ないので、OpenDistroのドキュメントや先達の記録を参考にしつつ、手探りで進めてみる。
(2021/9/7追記)
最近のエンジンアップデートで、テンプレート経由でのISMポリシーアタッチはdeplicatedとなったようです。
現在は、ISMポリシー内に適用対象のインデックスパターンを直接記載する形に変更されています。
参考:https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ism.html
参考:
Index State Management
Amazon ES用のUltraWarm
Index State Management(OpenDistro)
ISM API(OpenDistro)
やってみる
前提条件
- UltraWarm付き、バージョン7.9のAmazon ESドメインが作成済み。
- 手元の端末からアクセスできるよう、アクセスポリシーを構成済み。
- bashで実行。
ISMポリシー作成
- ポリシードキュメントを準備。
-
ism-policy
というポリシーを作ってみる。 - 公式のサンプルポリシーをベースに、「インデックス作成後5分経過したらUltraWarmへ移動、15分経過したら削除」の内容とする。
- JSONファイルを作成して、引数渡しでISMポリシーを作成する。
-
※2021/3/4追記
- timeoutを短くし過ぎると、ステートの移行が失敗することがある模様。
- 以下の例では元々timeout=5m、delay=5mとしていたが、warmステートへの移行は成功したもののdeleteステートへの移行(削除)が
Action timed out
となってしまった。 - timeout=2h、delay=1hとしたところ無事成功。混乱を避けるため、後追いとなるが下記JSONも修正した。
{
"policy": {
"description": "Demonstrate a hot-warm-delete workflow.",
"default_state": "hot",
"schema_version": 1,
"states": [{
"name": "hot",
"actions": [],
"transitions": [{
"state_name": "warm",
"conditions": {
"min_index_age": "5m"
}
}]
},
{
"name": "warm",
"actions": [{
"warm_migration": {},
"timeout": "2h",
"retry": {
"count": 5,
"delay": "1h"
}
}],
"transitions": [{
"state_name": "delete",
"conditions": {
"min_index_age": "15m"
}
}]
},
{
"name": "delete",
"actions": [{
"delete": {}
}],
"transitions": []
}
]
}
}
- ISMポリシーをPUT。
- 結果はポリシードキュメントがそのまま返されるだけなので省略。
$ curl -X PUT https://<文字列>.ap-northeast-1.es.amazonaws.com/_opendistro/_ism/policies/ism-policy?pretty -H 'Content-Type: application/json' -d @ism-policy.json
- ISMポリシーを確認。
- 同じく長いので、存在確認できたらOK。
$ curl -X GET https://<文字列>.ap-northeast-1.es.amazonaws.com/_opendistro/_ism/policies/ism-policy?pretty | head -8
{
"_id" : "ism-policy",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"policy" : {
"policy_id" : "ism-policy",
"description" : "Demonstrate a hot-warm-delete workflow.",
インデックステンプレート作成
- ポリシードキュメントを準備。
- 作成したポリシーを新規インデックスに自動アタッチするよう、インデックステンプレート(
ism-settings
)を作成する。
- 作成したポリシーを新規インデックスに自動アタッチするよう、インデックステンプレート(
{
"template": "log-*",
"settings": {
"index": {
"number_of_shards": 1,
"opendistro.index_state_management.policy_id": "ism-policy"
}
}
}
- インデックステンプレートをPUT。
- 結果は省略。
$ curl -X PUT https://<文字列>.ap-northeast-1.es.amazonaws.com/_template/ism-settings?pretty -H 'Content-Type: application/json' -d @ism-settings.json
- インデックステンプレートを確認。
$ curl -X GET https://<文字列>.ap-northeast-1.es.amazonaws.com/_template/ism-settings?pretty
{
"ism-settings" : {
"order" : 0,
"index_patterns" : [
"log-*"
],
"settings" : {
"index" : {
"number_of_shards" : "1",
"opendistro" : {
"index_state_management" : {
"policy_id" : "ism-policy"
}
}
}
},
"mappings" : { },
"aliases" : { }
}
}
ISMポリシーが設定に含まれていることが分かる。
これで、log-
で始まるインデックスには自動的にISMポリシーがアタッチされるようになる(はず)。
テストの準備
- テストインデックスを作る。
- インデックステンプレートに合致するよう
log-20210217
というインデックスを作り、同時にデータを投入する。 - ちなみにsample.jsonの中身はこんな感じ(公式のサンプルから拝借)。
- インデックステンプレートに合致するよう
{
"director": "Burton, Tim",
"genre": ["Comedy","Sci-Fi"],
"year": 1996,
"actor": ["Jack Nicholson","Pierce Brosnan","Sarah Jessica Parker"],
"title": "Mars Attacks!"
}
$ curl -X PUT https://<文字列>.ap-northeast-1.es.amazonaws.com/log-20210217/_doc/1?pretty -H 'Content-Type: application/json' -d @sample.json
- インデックス設定を確認する。
$ curl -X GET https://<文字列>.ap-northeast-1.es.amazonaws.com/log-20210217?pretty
$ {
"log-20210217" : {
"aliases" : { },
"mappings" : { },
"settings" : {
"index" : {
"opendistro" : {
"index_state_management" : {
"policy_id" : "ism-policy"
}
},
"number_of_shards" : "1",
"provided_name" : "log-20210217",
"creation_date" : "1613518166590",
"number_of_replicas" : "1",
"uuid" : "PTgQT-EwQlSyzfqo_S7iCg",
"version" : {
"created" : "7090199"
}
}
}
}
}
無事ISMポリシーがアタッチされている。
ついでにインデックス一覧の方でも確認しておく。
$ curl -X GET https://<文字列>.ap-northeast-1.es.amazonaws.com/_cat/indices?v | egrep 'log-|uuid'
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open log-20210217 BTmZU_MBS-yMss2uFrvbHQ 1 0 1 0 6.2kb 6.2kb
テスト
- ISMの挙動を確認する(①ホット→UltraWarm)。
$ curl -X GET https://<文字列>.ap-northeast-1.es.amazonaws.com/_ultrawarm/migration/_status?v
index migration_type state
空。
$ curl -X GET https://<文字列>.ap-northeast-1.es.amazonaws.com/_ultrawarm/migration/log-20210217/_status?pretty
{
"error" : {
"root_cause" : [
{
"type" : "illegal_argument_exception",
"reason" : "Index [log-20210217] has no active migrations"
}
],
"type" : "illegal_argument_exception",
"reason" : "Index [log-20210217] has no active migrations"
},
"status" : 400
}
エラー。
もしかしてもう終わったのか?
公式によるとUltraWarmに移行したインデックスには"box_type" : "warm"
の項目が現れているはずなので、確認してみる。
$ curl -X GET https://<文字列>.ap-northeast-1.es.amazonaws.com/log-20210217 | jq '.[].settings.index.routing.allocation'
null
...ということで、まだのようだ。
作成後5分待てばOKかと思ったが、どうやらポリシーの評価は小一時間ごとに起動するISMジョブによって行われるようで、ポリシーアタッチからしばらく待たないとダメっぽい。
ポリシーをインデックスにアタッチすると、ISM は 30~48 分ごとに実行されるジョブを作成し、ポリシーアクションを実行して条件を確認してから、インデックスを別の状態に移行します。このジョブを実行する基本時間は 30 分ごとです。さらに、0~60% のランダムなジッターが追加され、すべてのインデックスから同時にアクティビティが急増しないようにします。
今回はテストなので分単位にしているが、もともと日単位で移行したり削除したりするための仕組みなので、運用上はそれで問題はなさそうではある。
ということで、しばらく放置して別の作業に向かうことにする。
テスト(再訪)
ポリシーアタッチから約2時間。
再度確認してみる。
$ curl -X GET https://<文字列>.ap-northeast-1.es.amazonaws.com/log-20210217 | jq '.[].settings.index.routing.allocation'
"routing" : {
"allocation" : {
"require" : {
"box_type" : "warm"
}
}
今度は出てきた。無事UltraWarmノードに移行されている模様。
ちなみにマネジメントコンソールのAmazon ESダッシュボードにも"UltraWarmストレージの使用状況"という列があり、そこの容量が増えていることでも確認できる。
- ISMの挙動を確認する(②UltraWarm→削除)。
さらに10分待てばインデックスが削除、されて欲しいところだが、これもISMジョブが巡回するのを待つ時間の方が方が長そうなので、今回は省略。
掃除
- インデックステンプレートを削除(結果は省略)。
$ curl -X DELETE https://<文字列>.ap-northeast-1.es.amazonaws.com/_template/ism-settings?pretty
- ISMポリシーを削除。
$ curl -X DELETE https://<文字列>.ap-northeast-1.es.amazonaws.com/_opendistro/_ism/policies/ism-policy?pretty
{
"_index" : ".opendistro-ism-config",
"_type" : "_doc",
"_id" : "ism-policy",
"_version" : 2,
"result" : "deleted",
"forced_refresh" : true,
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
余談
- UltraWarmへの移行確認には以下のコマンドも使える。特に
explain
が有益。
$ curl -X GET https://<エンドポイント>.ap-northeast-1.es.amazonaws.com/_opendistro/_ism/explain/<インデックス名>
$ curl -X GET https://<エンドポイント>.ap-northeast-1.es.amazonaws.com/_cat/indices/_warm?v
- ISMを待たず、直接APIでUltraWarmに送り込んでしまいたい場合はこちら(
_warm
を_hot
に変えると、ホットノードに戻すこともできる)。
$ curl -X POST https://<文字列>.ap-northeast-1.es.amazonaws.com/_ultrawarm/migration/log-20210217/_warm
- 以下のコマンドで、ホットノード上にある、あるいはUltraWarmに移動したインデックスの内容を取得できる。取れる内容はインデックスを指定してGETした場合と同じ。
$ curl -X GET https://<文字列>.ap-northeast-1.es.amazonaws.com/_hot?pretty
$ curl -X GET https://<文字列>.ap-northeast-1.es.amazonaws.com/_warm?pretty