クラウドインテグレーション部の渡邊です。 今回はAWS OpenSearchのindex APIについて説明します。
AWS OpenSearchのシャード数の偏りにより、パフォーマンスに影響が発生する恐れがあります。
偏りがある場合、シャード数とノード数のバランスが悪いことが考えられます。ベストプラクティスにしたがってシャード数がノード数の倍数になるように設定してください。シャードの変更には_reindex api や _shrink api を用いることができます。
引用元:Amazon OpenSearch Service のパフォーマンストラブル解決のためのファーストステップ
以上の引用から、既存インデックスのシャード数をノード数の倍数へ変更するために、_reindex apiを使用したのですが、意外と面倒だったので記述します。 ドキュメントにも簡単ではない旨の記載がありました。
既存のインデックスに対してプライマリシャードの数を簡単に変更することはできません。
引用元:シャード数の選択
なお、新規インデックスの場合は事前にインデックステンプレート(Index templates)を作成しておくことで、作成時にテンプレートの設定が適用されるため、そちらを利用することをオススメします。
以前執筆した、OpenSearchのスローログ設定時の注意点でもインデックステンプレートを利用しました。
_shrink apiによる検証は記事「OpenSearchのシャード再配置のために_shrink apiを使用する際の注意点」を参考にしてください。
インデックスについて以下の制約がありました。
たとえば、インデックスAのシャード数を変更するためにインデックス自身(インデックスA)のシャード数を_reindex apiで変更することはできません。 よって、既存のインデックスと同じ名前のインデックスのシャード数を変更するために、以下の手順で対処しました。
① 仮のインデックスを希望するシャード数で作成する
② 既存のインデックスを仮のインデックスへコピー(_reindex apiを使用)
③ 既存のインデックスを削除
④ 指定のシャード数の既存のインデックスと同じ名前のものを作成
⑤ ①でコピーしたインデックスを④で作成したインデックスへ移す
また、④と⑤に関してはIndex aliasesという設定を利用することで、割愛できる場合があります。 「OpenSearchのシャード再配置のために_shrink apiを使用する際の注意点」の「余談:aliasでも似たようなことを実現することができる」に記載があるのでそちらも併せて参考にしてください。
任意ですが、頻繁に使用する値を環境変数として設定しました。
USERNAME=<マスターユーザ名>
PASSWORD=<マスターユーザパスワード>
ENDPOINT=<OpenSearchエンドポイント>
既存のインデックスとしてindex-testを作成します。
$ curl -XPUT -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/index-test/_doc/1" -d '{ "name" : "TestIndex" }'
{"_index":"index-test","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1}
シャード数の設定を確認します。
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/index-test/_settings?pretty"
{
"index-test" : {
"settings" : {
"index" : {
"replication" : {
"type" : "DOCUMENT"
},
"number_of_shards" : "5",
"provided_name" : "index-test",
"creation_date" : "1700781382862",
"number_of_replicas" : "1",
"uuid" : "EfF5dzNaSdCuOzRcJvtICQ",
"version" : {
"created" : "136327827"
}
}
}
}
}
設定から、プライマリシャード数が5、レプリカシャードが各プライマリシャードに対して1つ作成されるため、
合計で10のシャードが作成されているはずです。 シャードの配置を確認すると、インデックスの設定通りに作成されていました。
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/_cat/shards?v"
(略)
index-test 0 r STARTED 0 208b x.x.x.x 41489d33fe64d3807e1b2dbdd4f8a237
index-test 0 p STARTED 0 208b x.x.x.x fdfd42dea316faeb14b056f7c31461d9
index-test 1 r STARTED 0 208b x.x.x.x 41489d33fe64d3807e1b2dbdd4f8a237
index-test 1 p STARTED 0 208b x.x.x.x f2071b3f4d78a45206a83fd20122cd88
index-test 2 p STARTED 0 208b x.x.x.x 41489d33fe64d3807e1b2dbdd4f8a237
index-test 2 r STARTED 0 208b x.x.x.x fdfd42dea316faeb14b056f7c31461d9
index-test 3 p STARTED 0 208b x.x.x.x fdfd42dea316faeb14b056f7c31461d9
index-test 3 r STARTED 0 208b x.x.x.x f2071b3f4d78a45206a83fd20122cd88
index-test 4 r STARTED 1 3.8kb x.x.x.x fdfd42dea316faeb14b056f7c31461d9
index-test 4 p STARTED 1 3.8kb x.x.x.x f2071b3f4d78a45206a83fd20122cd88
(略)
では、初期状態を確認したところで、index-testのシャード数を変更します。
以下の記述にしたがって、ノードの倍数になるようにシャード数を設定します。 今回はデータノードを3つ作成しているため、プライマリシャード数を3とします。
ベストプラクティスにしたがってシャード数がノード数の倍数になるように設定してください。 引用元:Amazon OpenSearch Service のパフォーマンストラブル解決のためのファーストステップ
$ curl -XPUT -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/index-test-tmp" -d '{
"settings": {
"number_of_shards": 3
}
}'
シャード数の設定を確認します。 number_of_shardsに注目すると、想定のシャード数となっています。
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/index-test-tmp/_settings?pretty"
{
"index-test-tmp" : {
"settings" : {
"index" : {
"replication" : {
"type" : "DOCUMENT"
},
"number_of_shards" : "3",
"provided_name" : "index-test-tmp",
"creation_date" : "1700781571211",
"number_of_replicas" : "1",
"uuid" : "vdgoq9YoRamTxDZNdrsxUQ",
"version" : {
"created" : "136327827"
}
}
}
}
}
シャードの配置を確認すると、インデックスの設定通りに作成されていました。 レプリカシャード数はプライマリシャード数が変更されたことに伴い、5つから3つに変更されていました。
(略)
index-test-tmp 0 r STARTED 0 208b x.x.x.x 41489d33fe64d3807e1b2dbdd4f8a237
index-test-tmp 0 p STARTED 0 208b x.x.x.x f2071b3f4d78a45206a83fd20122cd88
index-test-tmp 1 p STARTED 0 208b x.x.x.x 41489d33fe64d3807e1b2dbdd4f8a237
index-test-tmp 1 r STARTED 0 208b x.x.x.x fdfd42dea316faeb14b056f7c31461d9
index-test-tmp 2 p STARTED 1 3.8kb x.x.x.x fdfd42dea316faeb14b056f7c31461d9
index-test-tmp 2 r STARTED 0 208b x.x.x.x f2071b3f4d78a45206a83fd20122cd88
.opendistro_security 0 p STARTED 10 53.2kb x.x.x.x 41489d33fe64d3807e1b2dbdd4f8a237
(略)
_reindex apiを使用して既存のインデックスを仮のインデックスへコピーします。 sourceはコピー元、destはコピー先です。
$ curl -XPOST -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/_reindex" -d '{
"source": {
"index": "index-test"
},
"dest": {
"index": "index-test-tmp"
}
}'
{"took":3389,"timed_out":false,"total":1,"updated":0,"created":1,"deleted":0,"batches":1,"version_conflicts":0,"noops":0,"retries":{"bulk":0,"search":0},"throttled_millis":0,"requests_per_second":-1.0,"throttled_until_millis":0,"failures":[]}
既存インデックスと仮のインデックスの中身を見比べると、問題なくコピーできていることが分かります。
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/index-test/_doc/1?pretty"
{
"_index" : "index-test",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "TestIndex"
}
}
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/index-test-tmp/_doc/1?pretty"
{
"_index" : "index-test-tmp",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "TestIndex"
}
}
既存のインデックスと同名かつ希望するシャード数のものを新規作成するために、既存のインデックスを削除します。
$ curl -XDELETE -u "${USERNAME}:${PASSWORD}" "https://${ENDPOINT}/index-test"
$ curl -XPUT -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/index-test" -d '{
"settings": {
"number_of_shards": 3
}
}'
シャード数の設定を確認します。既存のインデックスの同名の新規インデックスのシャード数が想定通りになっています。
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/index-test/_settings?pretty"
{
"index-test" : {
"settings" : {
"index" : {
"replication" : {
"type" : "DOCUMENT"
},
"number_of_shards" : "3",
"provided_name" : "index-test",
"creation_date" : "1700781888617",
"number_of_replicas" : "1",
"uuid" : "o8PiFYXXQD-PmaBC9qcXsw",
"version" : {
"created" : "136327827"
}
}
}
}
}
最後に、仮のインデックスindex-test-tmpのものをindex-testへコピーします。
$ curl -XPOST -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/_reindex" -d '{
"source": {
"index": "index-test-tmp"
},
"dest": {
"index": "index-test"
}
}'
{"took":1069,"timed_out":false,"total":1,"updated":0,"created":1,"deleted":0,"batches":1,"version_conflicts":0,"noops":0,"retries":{"bulk":0,"search":0},"throttled_millis":0,"requests_per_second":-1.0,"throttled_until_millis":0,"failures":[]}
インデックスの中身が想定のものになっています。
$ curl -XGET -u "${USERNAME}:${PASSWORD}" "https://${ENDPOINT}/index-test/_doc/1?pretty"
{
"_index" : "index-test",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "TestIndex"
}
}
シャード数の設定を確認します。
{
"index-test" : {
"settings" : {
"index" : {
"replication" : {
"type" : "DOCUMENT"
},
"number_of_shards" : "3",
"provided_name" : "index-test",
"creation_date" : "1700781888617",
"number_of_replicas" : "1",
"uuid" : "o8PiFYXXQD-PmaBC9qcXsw",
"version" : {
"created" : "136327827"
}
}
}
}
}
シャードの配置を確認すると、インデックスの設定通りに作成されていました。
(略)
index-test 0 p STARTED 0 208b x.x.x.x fdfd42dea316faeb14b056f7c31461d9
index-test 0 r STARTED 0 208b x.x.x.x f2071b3f4d78a45206a83fd20122cd88
index-test 1 r STARTED 0 208b x.x.x.x 41489d33fe64d3807e1b2dbdd4f8a237
index-test 1 p STARTED 0 208b x.x.x.x f2071b3f4d78a45206a83fd20122cd88
index-test 2 p STARTED 0 208b x.x.x.x 41489d33fe64d3807e1b2dbdd4f8a237
index-test 2 r STARTED 1 3.8kb x.x.x.x fdfd42dea316faeb14b056f7c31461d9
index-test-tmp 0 r STARTED 0 208b x.x.x.x 41489d33fe64d3807e1b2dbdd4f8a237
(略)
Index aliasesという設定を利用することで、インデックスにエイリアスを指定できます。
たとえば、index-testにindex-test-3というエイリアスを登録します。
curl -XPOST -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/index-test/_alias/index-test-3"
index-test-3をインデックスとして指定してリクエストを送ると、index-testへそのリクエストが反映されます。
index-test-3へインデックス設定を表示するリクエストを送るとindex-testの設定が表示されます。
curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/index-test-3/_settings?pretty"
{
"index-test" : {
"settings" : {
"index" : {
"replication" : {
"type" : "DOCUMENT"
},
"routing" : {
"allocation" : {
"initial_recovery" : {
"_id" : null
},
"require" : {
"_name" : null
}
}
},
"number_of_shards" : "3",
"routing_partition_size" : "1",
"blocks" : {
"read_only_allow_delete" : "false",
"read_only" : "false",
"write" : "false"
},
"provided_name" : "index-test",
"resize" : {
"source" : {
"name" : "index-test-shrink",
"uuid" : "xxiGBhs3R3umbZaPloLRKA"
}
},
"creation_date" : "1700869528292",
"number_of_replicas" : "1",
"uuid" : "qrYnWWXBQoSyRXgTTY3E7Q",
"version" : {
"created" : "136327827",
"upgraded" : "136327827"
}
}
}
}
}
これを利用して、ソースインデックスとは別名のインデックスを_shrink apiで作成しても、エイリアスとしてソースインデックス名を登録することで、④の手間が省けるかと思います。
ただし、インデックスの一覧を確認しても、インデックスに設定したエイリアス名index-test-3は出てきません。
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/_cat/indices?pretty"
green open index-test-1125-notallocate rOJ3Jnm5T92cEMrMKdiCrg 3 1 1 0 8.6kb 4.3kb
green open .opensearch-observability V7SoTD9lTM-BaRnDBZpZhA 1 2 0 0 624b 208b
green open .plugins-ml-config 7JrgF6XeQNSi3UN1goU6Nw 5 1 1 0 9.4kb 4.7kb
yellow open index-test-shrink xxiGBhs3R3umbZaPloLRKA 1 1 1 0 3.8kb 3.8kb
yellow open index-test-shrink-1057 mbgkgDkWQee8iYzMhLeBHg 1 1 1 0 3.8kb 3.8kb
yellow open index-test-1125 EIt--n6-ShaMGuwAtlfN2g 3 1 1 0 4.3kb 4.3kb
green open index-test qrYnWWXBQoSyRXgTTY3E7Q 3 1 1 0 8.6kb 4.3kb
green open index-test-tmp vdgoq9YoRamTxDZNdrsxUQ 3 1 1 0 8.6kb 4.3kb
green open index-test-2 6TupyNBEQWSavxR26y27Aw 6 1 0 0 2.4kb 1.2kb
green open .opendistro_security DYyz6zEbQ5aV_OGWzNe9SQ 1 2 10 0 166.5kb 53.2kb
green open index-test-shrink-cp 75MpLnlMQhC2mScCw9uUHA 1 1 1 0 7.7kb 3.8kb
green open .kibana_1 lOTu3GxzQiW9aDjwgPQgMA 1 2 1 0 15.6kb 5.2kb
エイリアスを確認するには以下のようにします。
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/_cat/aliases?pretty"
index-test-3 index-test - - - -
.kibana .kibana_1 - - - -
【参考】 Reindex API