話題の記事

Elasticsearch 6.3.0 の新機能を試してみた

6/13 に Elastic Stack 6.3.0 がリリースされました。Elasticsearch 6.3.0 の新機能の中でも注目されている SQL 対応、Rollup などを試してみました。
2018.06.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Elastic Stack の新しいマイナーバージョン 6.3.0 がリリースされました。

Elastic Stack 6.3.0 では Elastic{ON} 2018 で紹介された機能が多く含まれていました。今回は Elasticsearch 6.3.0 の新機能を中心に簡単に試してみました。

全般

X-Pack のデフォルト化

今まで X-Pack はプラグインという形で提供されていました。Elasticsearch 6.3.0 から X-Pack がデフォルトで含まれるようになりました。別途インストールする必要はありません。また今まで X-Pack の標準ライセンス(未サブスクリプション)はトライアル(30日間全ての機能を利用可)でした。メールアドレスを登録することで BASIC ライセンスを利用できました。Elasticsearch 6.3.0 からはデフォルトで BASIC ライセンスが適用されています。つまり、Elasticsearch をインストールすれば、X-Pack の一部機能は利用期限なく利用できます。BASIC ライセンスで利用可能な機能に関しては サブスクリプション をご参照ください。

curl localhost:9200/_xpack |jq .
{
  "build": {
    "hash": "424e937",
    "date": "2018-06-11T23:42:35.448128Z"
  },
  "license": {
    "uid": "b3f23e94-ad22-461d-a1f0-3f54246ab5da",
    "type": "basic",
    "mode": "basic",
    "status": "active"
  },
  "features": {
    "graph": {
      "description": "Graph Data Exploration for the Elastic Stack",
      "available": false,
      "enabled": true
    },
    "logstash": {
      "description": "Logstash management component for X-Pack",
      "available": false,
      "enabled": true
    },
    "ml": {
      "description": "Machine Learning for the Elastic Stack",
      "available": false,
      "enabled": true,
      "native_code_info": {
        "version": "6.3.0",
        "build_hash": "0f0a34c67965d7"
      }
    },
    "monitoring": {
      "description": "Monitoring for the Elastic Stack",
      "available": true,
      "enabled": true
    },
    "rollup": {
      "description": "Time series pre-aggregation and rollup",
      "available": true,
      "enabled": true
    },
    "security": {
      "description": "Security for the Elastic Stack",
      "available": false,
      "enabled": true
    },
    "watcher": {
      "description": "Alerting, Notification and Automation for the Elastic Stack",
      "available": false,
      "enabled": true
    }
  },
  "tagline": "You know, for X"
}

なお、X-Pack を含まないパッケージも提供されています。

新機能

SQL 対応

私が現在関わっているプロダクトでの提供を考えていたので、今回のリリースで最も気になっている機能です。

Elasticsearch は今まで JSON 形式でクエリ DSL を記述していました(クエリストリングは除く)。クエリ DSL に慣れてしまえば便利ですが、触り始めた時は想定したクエリを作るのに苦労しました。

6.3.0 では新しいクエリの形式として SQL に対応しました。Elasticsearch のクエリを知っている方よりも SQL を知っている方の方が多いと思います。より多くの人が Elasticsearch に対してクエリを実行できるようになりました。また SQL で連携するサードパーティツールから Elasticsearch をデータソースにクエリしてうんぬんするようなことも可能となりました。今まで Elasticsearch を利用したいけど難しそう、導入を考えてたけど挫折した方も改めて Elasticsearch 導入を考えてよいのではないでしょうか。

なお、SQL はクエリのみとなります。INSERT、UPDATE、DELETE のような書き込み構文は利用できません。

提供形式

SQL クエリを実行するにはいくつかの形式があります。

REST API

SQL クエリを REST API のパラメータとしてリクエストします。例えば、curlコマンドで書くと以下のようになります。

クエリ
curl -H"Content-Type: application/json" -XPOST http://elasticsearch-host:9200/_xpack/sql?format=csv
{
  "query": "SELECT field1, field2 FROM index WHERE field1 = 1"
}
field1,field2
1,aaa
1,bbb
CLI

パッケージ内に CLI ツールが提供されています。MySQL でいうmysql、PostgreSQL でいうpsqlのようなものです。

接続

Elasticsearch の bin ディレクトリにシェルがあります。第一引数に接続先ホストを指定します。

# /usr/share/elasticsearch/bin/elasticsearch-sql-cli localhost
     .sssssss.`                     .sssssss.
  .:sXXXXXXXXXXo`                `ohXXXXXXXXXho.
 .yXXXXXXXXXXXXXXo`            `oXXXXXXXXXXXXXXX-
.XXXXXXXXXXXXXXXXXXo`        `oXXXXXXXXXXXXXXXXXX.
.XXXXXXXXXXXXXXXXXXXXo.    .oXXXXXXXXXXXXXXXXXXXXh
.XXXXXXXXXXXXXXXXXXXXXXo``oXXXXXXXXXXXXXXXXXXXXXXy
`yXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
 `oXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo`
   `oXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo`
     `oXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo`
       `oXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo`
         `oXXXXXXXXXXXXXXXXXXXXXXXXXXXXo`
           .XXXXXXXXXXXXXXXXXXXXXXXXXo`
         .oXXXXXXXXXXXXXXXXXXXXXXXXo`
       `oXXXXXXXXXXXXXXXXXXXXXXXXo`   `odo`
     `oXXXXXXXXXXXXXXXXXXXXXXXXo`   `oXXXXXo`
   `oXXXXXXXXXXXXXXXXXXXXXXXXo`   `oXXXXXXXXXo`
 `oXXXXXXXXXXXXXXXXXXXXXXXXo`   `oXXXXXXXXXXXXXo`
`yXXXXXXXXXXXXXXXXXXXXXXXo`    oXXXXXXXXXXXXXXXXX.
.XXXXXXXXXXXXXXXXXXXXXXo`   `oXXXXXXXXXXXXXXXXXXXy
.XXXXXXXXXXXXXXXXXXXXo`     /XXXXXXXXXXXXXXXXXXXXX
.XXXXXXXXXXXXXXXXXXo`        `oXXXXXXXXXXXXXXXXXX-
 -XXXXXXXXXXXXXXXo`            `oXXXXXXXXXXXXXXXo`
  .oXXXXXXXXXXXo`                `oXXXXXXXXXXXo.
    `.sshXXyso`        SQL         `.sshXhss.`

sql>

X!!!

クエリ
sql> SELECT field1, field2 FROM index WHERE field1 = 1;
     field1    |      field2
---------------+---------------
1              |aaa
1              |bbb
JDBC

JDBC Drive が提供され、Java プログラムから SQL クエリを実行できます。JDBC 接続を利用するには PLATINUM、ENTERPRISE の Subscription が必要なようです。

ODBC?

Elastic{ON}2018 のセッションではこの他にも ODBC からのアクセスも提供を予定していると発表していました。

SQL 対応の詳細についてはもっと色々調べたいので別記事で改めてエントリーしたいと思います。

Rollup

Elasticsearch に時系列データをインデックスすることは多くのケースであります。各種ログ、IoTから取り込んだデータ、サーバのシステムメトリクスなどなど。時系列データは何も対処しないとどんどん肥大化します。ディスク使用量の増加、パフォーマンスの劣化、様々なシステム影響を及ぼします。そこで Elasticsearch は様々な対応方法を提供してきました。インデックスを日付毎など時系列のある単位で分割することで、古いデータが不要であれば古いインデックスを削除することで安定したデータ量でディスクの使用量逼迫の回避、パフォーマンス劣化の予防ができました。古いデータもまれに参照したいようであれば古いインデックスをクローズすることでパフォーマンスを改善できますが、ディスク使用量の増加は回避できません。

そこで Elasticsearch は新しいアプローチとして Rollup Job API の提供を開始しました。Rollup はインデックスにあるデータの集計して別のインデックスに取り込みます。ざっくりイメージとしてはジョブスケジューリング機能付き Aggregation 版 reindex です。以下のスライドがイメージしやすいと思います。

例えば、サーバから CPU/MEM/Disk使用率などのメトリクスを 1秒間隔で 100ノードから収集しているとします。すると、1日で 864万件のドキュメントが作成されます。1年で 31億件のドキュメントになります。1年前のデータを 1秒間隔で分析したいケースはどれぐらいありますか?1秒間隔では不要で 1時間間隔で十分なケースもあると思います。1時間間隔にサマライズするだけで 1日分のドキュメントを 864万件から 2400件まで減らすことができます。

Rollup の実行

Rollup はジョブ定義、ジョブ開始の 2つプロセスで実行されます。

ジョブ定義

今回は ELB のアクセスログを Rollup でサマライズしてみました。ELB のアクセスログはリクエスト一件づつ記録します。リクエストの情報には接続元IPアドレス、リクエストURL、リクエストのステータスコード、レスポンスタイムなどが含まれます。アクセスログを 1時間単位にサマリし、ステータスコード毎に分割して持ちます。更にレスポンスタイムの最小値、最大値、平均値を集計します。

Request
PUT _xpack/rollup/job/<job_name>
{
    "index_pattern": "elblog-*",
    "rollup_index": "rollup_elblog",
    "cron": "* * * * * ?",
    "page_size" : 1000,
    "groups" : {
      "date_histogram": {
        "field": "@timestamp",
        "interval": "1h",
        "delay": "7d"
      },
      "terms": {
        "fields": ["elb_status_code"]
      }
    },
    "metrics": [
        {
            "field": "target_processing_time",
            "metrics": ["min", "max", "avg"]
        }
    ]
}
キー 説明
index_pattern 対象のインデックスのパターン
roll_up_index 集計データを格納するインデックス名
cron ジョブ実行間隔。名前の通り、cron 形式(分 時 日 月 年 曜日
page_size 一回の集計で処理する Aggregation のバケット数
groups 集計単位。Bucket Aggregation で指定可能
metrics 集計するデータ
ジョブ実行

ジョブ実行の開始は API をリクエストするだけです。

Request
POST _xpack/rollup/job/<job_name>/_start
集計データの確認

しばらく待つと指定したインデックス rollup_elb にデータが格納されます。例えば以下のようなデータがインデックスされます。

POST rollup_elblog/_search
{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 24,
    "max_score": 1,
    "hits": [
      {
        "_index": "rollup_elblog",
        "_type": "_doc",
        "_id": "3550658316",
        "_score": 1,
        "_source": {
          "@timestamp.date_histogram.time_zone": "UTC",
          "@timestamp.date_histogram.timestamp": 1490569200000,
          "target_processing_time.avg._count": 5,
          "target_processing_time.min.value": 0,
          "_rollup.version": 1,
          "target_processing_time.avg.value": 0.7070000050589442,
          "target_processing_time.max.value": 0.40400001406669617,
          "@timestamp.date_histogram.interval": "1h",
          "elb_status_code.terms.value": 301,
          "@timestamp.date_histogram._count": 5,
          "elb_status_code.terms._count": 5,
          "_rollup.id": "elblog"
        }
      },
...

Painless スクリプトの検証

Painless スクリプト言語の動作検証ができるようになりました。Elasticsearch は Painless Scripting Language という独自言語を持ちます。独自言語であり、なかなか検証しづらかったのですが、検証 API が提供されるようになりました。これでちょっと複雑なスクリプトを書きたい時も安心して実装・検証ができます。

POST /_scripts/painless/_execute
{
  "script": {
    "source": "params.var1 + params.var2",
    "params": {
      "var1": 1,
      "var2": 2
    }
  }
}
{
  "result": "3"
}

まとめ

待望の Elasticsearch 6.3.0 がリリースされました。今回は新機能をメインに紹介しましたが、X-Pack のソースコード公開や、Java 10 対応などマイナーバージョンアップ?と思えるような大きな変化がありました。記事中の SQL 対応はもう少し調査してまた詳細なブログレポートを書きたいと思います。