サムネ出典URL:https://aws.amazon.com/jp/architecture/icons/
クラウドインテグレーション部の渡邊です。
今回はAWS OpenSearchのスロークエリについて説明していきます。
AWS OpenSearchが出力可能なログは以下4種類です。
その中で検索スローログおよびインデックススローログ(以降、まとめてスローログと呼ぶ)や監査ログはAWS OpenSearchのログ設定に加え、OpenSearchDashboard側で追加の設定が必要になります。
今回はスローログに絞って説明していきます。
監査ログについては別の記事で紹介します。
実施内容としては踏み台サーバであるEC2からOpenSearchにリクエストを送り、スローログのしきい値の設定を実施します。
事前に、検索スローログおよびインデックススローログの有効化をAmazon OpenSearchで設定済みです。
スローログはしきい値を設定しないとデフォルトのしきい値がdisable(-1)なのでスローログが出力されません。
スローログのしきい値はインデックスに直接設定することもできますが、インデックステンプレートとして設定する方法でも各インデックスでスローログを出力することができます。
インデックステンプレートとはインデックスの標準設定を定義するもので、新しく作成したインデックスの標準設定をカスタムすることができます。
※事前に以下環境変数を設定してください
USERNAME=<マスターユーザ名>
PASSWORD=<マスターユーザパスワード>
ENDPOINT=<OpenSearchエンドポイント>
インデックスを試しに作成してみます。
$ curl -XPUT -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}:443/test/_doc/1" -d '{ "A JSON": "document" }'
{"_index":"test","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1}
インデックスの設定を確認するとスローログのしきい値が設定されていません。
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}:443/test/_settings?pretty"
{
"test" : {
"settings" : {
"index" : {
"creation_date" : "1693296376512",
"number_of_shards" : "5",
"number_of_replicas" : "1",
"uuid" : "ojZbuyKdSmSL_eLai-iRWg",
"version" : {
"created" : "136287827"
},
"provided_name" : "test"
}
}
}
}
まず、この状況でインデックステンプレートを設定してみます。
$ curl -XPUT -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/_index_template/slowlog-template" -d\
'{
"index_patterns": [
"*"
],
"template": {
"settings": {
"index": {
"search": {
"slowlog": {
"level": "trace",
"threshold": {
"query": {
"warn": "3s",
"trace": "3s",
"debug": "3s",
"info": "3s"
},
"fetch": {
"warn": "3s",
"trace": "3s",
"debug": "3s",
"info": "3s"
}
}
}
},
"indexing": {
"slowlog": {
"level": "trace",
"threshold": {
"index": {
"warn": "3s",
"trace": "3s",
"debug": "3s",
"info": "3s"
}
}
}
}
}
}
}
}'
{"acknowledged":true}
確認すると、インデックステンプレートが作成されております。
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}/_index_template/slowlog-template?pretty"
{
"index_templates" : [
{
"name" : "slowlog-template",
"index_template" : {
"index_patterns" : [
"*"
],
"template" : {
"settings" : {
"index" : {
"indexing" : {
"slowlog" : {
"level" : "trace",
"threshold" : {
"index" : {
"warn" : "3s",
"trace" : "3s",
"debug" : "3s",
"info" : "3s"
}
}
}
},
"search" : {
"slowlog" : {
"level" : "trace",
"threshold" : {
"fetch" : {
"warn" : "3s",
"trace" : "3s",
"debug" : "3s",
"info" : "3s"
},
"query" : {
"warn" : "3s",
"trace" : "3s",
"debug" : "3s",
"info" : "3s"
}
}
}
}
}
}
},
"composed_of" : [ ]
}
}
]
}
その上で再度先ほど作成したインデックスtest
を確認してもインデックスの設定が変わっていません。
既存のインデックスに対してはインデックステンプレートが反映されませんので注意してください。
既存のインデックスに反映させるためには直接スローログを設定してください(以下では検索スローログのしきい値のみ設定)。
$ curl -XPUT -u "${USERNAME}:${PASSWORD}" \
-H "Content-Type: application/json" \
"https://${ENDPOINT}:443/test/_settings" \
-d '{
"index.search.slowlog.threshold.query.warn": "3s",
"index.search.slowlog.threshold.query.info": "3s",
"index.search.slowlog.threshold.query.debug": "3s",
"index.search.slowlog.threshold.query.trace": "3s",
"index.search.slowlog.level": "trace"
}'
{"acknowledged":true}
インデックスtest
を確認してみると、しきい値が設定されています。
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}:443/test/_settings?pretty"
{
"test" : {
"settings" : {
"index" : {
"search" : {
"slowlog" : {
"level" : "trace",
"threshold" : {
"query" : {
"warn" : "3s",
"trace" : "3s",
"debug" : "3s",
"info" : "3s"
}
}
}
},
"number_of_shards" : "5",
"provided_name" : "test",
"creation_date" : "1693296376512",
"number_of_replicas" : "1",
"uuid" : "ojZbuyKdSmSL_eLai-iRWg",
"version" : {
"created" : "136287827"
}
}
}
}
}
ただ、こちらを作成の都度やるのは面倒なので、インデックステンプレートの作成をおすすめします。
新規インデックスを作って、インデックステンプレート通りに設定がされるか試してみます。
$ curl -XPUT -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}:443/test2/_doc/1" -d '{ "A JSON": "document" }'
{"_index":"test2","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1}
$ curl -XGET -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" "https://${ENDPOINT}:443/test2/_settings?pretty"
{
"test2" : {
"settings" : {
"index" : {
"search" : {
"slowlog" : {
"level" : "trace",
"threshold" : {
"fetch" : {
"warn" : "3s",
"trace" : "3s",
"debug" : "3s",
"info" : "3s"
},
"query" : {
"warn" : "3s",
"trace" : "3s",
"debug" : "3s",
"info" : "3s"
}
}
}
},
"indexing" : {
"slowlog" : {
"level" : "trace",
"threshold" : {
"index" : {
"warn" : "3s",
"trace" : "3s",
"debug" : "3s",
"info" : "3s"
}
}
}
},
"number_of_shards" : "5",
"provided_name" : "test2",
"creation_date" : "1693298195323",
"number_of_replicas" : "1",
"uuid" : "latFK9MrT0Ss6QiWznbBTg",
"version" : {
"created" : "136287827"
}
}
}
}
}
設定されていますね。
最後にスローログ出力の動作確認として、処理の重い検索リクエストを行います。
サンプルデータをOpenSearchDashboardに作成するため、今回はOpenSearch Dashboards APIというものを使います。
OpenSearch Dashboards APIはOpenSearch Dashboardの詳細設定をCUI上で実施するために使用するAPIです。
サンプルデータを作成する理由は、検索スローログを出力するためにデータ量が多いインデックスが必要だからです(もちろん自分でたくさんのデータをインデックスに投入してもOKです)。
そのために、APIの認証情報を使用してリクエストを送る必要があるので、以下のコマンドでAPIの認証情報を取得します。
$ curl -curl -k -X POST "https://${ENDPOINT}:443/_dashboards/auth/login" \
-H "osd-xsrf: true" \
-H "content-type:application/json" \
-d "{\"username\":\"${USERNAME}\", \"password\":\"${PASSWORD}\"}" \
-c auth.txt
{"username":"watanabe","tenants":{"global_tenant":true,"watanabe":true},"roles":["security_manager","all_access"],"backendroles":[]}
OpenSearchでサンプルデータを作成します。
$ curl -k -X POST "https://${ENDPOINT}/_dashboards/api/sample_data/logs" \
-H "osd-xsrf:true" \
-H "content-type:application/json" \
-b auth.txt
{"opensearchIndicesCreated":{"opensearch_dashboards_sample_data_logs":14074},"opensearchDashboardsSavedObjectsLoaded":13}
処理の重い検索リクエストを行います。
$ curl -u "${USERNAME}:${PASSWORD}" -H "Content-Type: application/json" https://${ENDPOINT}/opensearch_dashboards_sample_data_logs/_search -d\
'{
"query": {
"script": {
"script": "long total = 0;\n for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) { total += i;\n} for (int i = 0; i < 100000; ++i) { total += i;\n}"
}
}
}'
{"took":12054,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":0,"relation":"eq"},"max_score":null,"hits":[]}}
CloudWatchLogsの検索スローログ/aws/OpenSearchService/domains/<ドメイン名>/search-logs
確認してみると・・・
[2023-08-29T08:53:10,789][WARN ][index.search.slowlog.query] [5f89e3ec7c749a982790d6d3040ce489] [opensearch_dashboards_sample_data_logs][0] took[5.9s], took_millis[5917], total_hits[0 hits], stats[], search_type[QUERY_THEN_FETCH], total_shards[1], source[
{
"query": {
"script": {
"script": {
"source": "long total = 0;\n for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) {total += i;\n} for (int i = 0; i < 100000; ++i) { total += i;\n} for (int i = 0; i < 100000; ++i) { total += i;\n}",
"lang": "painless"
},
"boost": 1
}
}
}
], id[],
出てました!
【参考】