Amazon Elasticsearch Service が Slow Log の出力に対応しました

ども、藤本です。

現地時間 10/17、Amazon Elasticsearch Service が VPC に対応しました。

Amazon ElasticsearchがVPCをサポートしました

非常に嬉しいです。実はこのアップデートに隠れて、もう一つ嬉しいアップデートがありました。それは Elasticsearch の Slow Log を CloudWatch Logs に出力する機能です。

概要

Elasticsearch にはパフォーマンスの悪いクエリを記録するスローログ機能があります。RDB を利用されている方は MySQL や PostgreSQL が持つようなスローログ機能と言えばイメージしやすいかと思います。ただ今まで Amazon Elasticsearch Service は Slow Log を記録する機能がサポートされておらず、利用することができませんでした。パフォーマンス要件がシビアなシステムでは Slow Log によるログ記録からパフォーマンス解析ができないことは辛かったです。

それが今回のアップデートにより Amazon Elasticsearch Service で Slow Log の設定をできるようになり、そのログを CloudWatch Logs に出力することが可能となりました。

Elasticsearch の Slow Log

Elasticsearch の Slow Log 機能について少し説明します。公式ドキュメントも分かりやすく書かれていますので下記もご参照ください。

ログ出力種別

Elasticsearch の Slow Log の場合、大きく 3つに分類して設定・出力することができます。

  • 検索
    • クエリ
    • フェッチ
  • 登録

Elasticsearch は検索処理において、クエリに応じた対象ドキュメントの検索、および対象ドキュメントを取得するフェッチという 2つのフェーズがあります。それぞれを別の処理として Slow Log に記録できます。またデータ登録(インデキシング)処理も同様に Slow Log に記録することができます。

ログレベル

Slow Log のしきい値は 4段階に設定でき、秒数指定により記録をレベル分けすることができます。設定できるログレベルは以下の 4種類です。例えば、とりあえず記録したいのであれば、trace を 1ms(ミリ秒)に設定し、許容できないレスポンスとして、warn を 3s(秒)に設定するといったことが可能です。CloudWatch Logs は検索することもできるので、warn だけに絞って確認するようなことも可能です。

  • trace
  • debug
  • info
  • warn

ログ出力設定単位

インデックス単位で設定が可能です。インデックスのsettings内に設定します。逆に言うと、インデックス毎の設定が必要となります。全てのインデックスに適用したい場合、インデックステンプレートで設定しておく必要があります。

試してみた

早速使い方を試してみましょう。

マネジメントコンソールから Slow Log の CloudWatch Logs 連携の有効化

まずは AWS 側の設定です。マネジメントコンソールから見ると Logs タブが追加されました。Logs タブをクリックします。デフォルト設定は検索、登録の両方とも CloudWatch Logs との連携機能は無効化されています。

Amazon_Elasticsearch_Service_Management_Console

検索の CloudWatch Logs 連携機能を有効化します。Set up Search Slow Log の[Setup]ボタンをクリックします。

Slow Log を出力する CloudWatch Logs のロググループ指定、および CloudWatch Logs へアクセスするための IAM Role の設定画面へ遷移します。

Amazon_Elasticsearch_Service_Management_Console 2

今回はデフォルト設定のまま[Enable]ボタンをクリックします。

以上で、AWS 側の設定は完了です。

Slow Log のしきい値設定

続いて Elasticsearch クラスタへの設定です。Elasticsearch クラスタへ Web API で Slow Log のしきい値を設定します。クエリ、フェッチのスローログのしきい値を設定します。テストデータとして ELB のアクセスログをインデキシングしています。(インデックス名:elblog-yyyy.mm.dd)

PUT elblog-*/_settings
{
  "index": {
    "search": {
      "slowlog": {
        "threshold": {
          "query": {
            "trace": "1ms",
            "debug": "100ms",
            "info": "1s",
            "warn": "3s"
          },
          "fetch": {
            "trace": "1ms",
            "debug": "100ms",
            "info": "1s",
            "warn": "3s"
          }
        }
      }
    }
  }
}
{
  "acknowledged": true
}

動作確認

それでは確認してみましょう。適当にクエリしてみます。

GET elblog-*/_search
{
  "size": 0, 
  "query": {
    "range": {
      "@timestamp": {
        "gte": "2017-03-26T00:00:00Z",
        "lt": "2017-03-28T00:00:00Z"
      }
    }
  }, 
  "aggs": {
    "1": {
      "date_histogram": {
        "field": "@timestamp",
        "interval": "30m"
      }
    }
  }
}
{
  "took": 13,
<snip>
}

CloudWatch Logs を見てみましょう。

CloudWatch_Management_Console 2

全く同じクエリというわけではありませんが、同様のクエリが記録されています。ログの記録はシャード単位となります。tookが処理時間です。sourceの JSON が受け取ったクエリの内容(Elasticsearch が解釈した内容?)となります。

データ登録の Slow Log 有効化も同様の手順で設定できます。

まとめ

いかがでしたでしょうか? Amazon Elasticsearch Service で Slow Log を出力できるようになり、より本番投入しやすくなりました。更に、CloudWatch Logs から Elasticsearch へストリームすることで Kibana でモニタリングすることも可能となるのは嬉しいですね。