この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、藤本です。
現地時間 5/4 の GW期間に Elastic Stack 5.4.0 がリリースされました。
- Elastic Stack 5.4.0 Released
- Elasticsearch 5.4.0 released
- Kibana 5.4.0 released
- Logstash 5.4.0 released
- Beats 5.4.0 released
昨日は Kibana 5.4.0 の新機能である Time Series Visual Builder を触ってみました。
今回は Kibana 5.4.0 で Pipeline Aggregation がサポートされたので触ってみました。
Elasticsearch の Aggregation
Elasticsearch は検索エンジンという名前の通り、豊富な検索機能を持っています。ただ検索機能だけでなく、柔軟な集計機能もあります。元々は Facet という機能でしたが、より柔軟な集計機能として 1.0.0 から Aggregation がリリースされ、現在のメインの集計機能となりました。
Aggregation は大きく 3つの種類があります。
- Merics Aggregations
- Bucket Aggregations
- Pipeline Aggregations
Metrics Aggregations
値を集計する機能です。例えば、あるドキュメントのまとまりから最大値を取り出すには Max Aggregation を利用します。同じように合計値を取り出すには Sum Aggregation を利用します。
Sum Aggregation を利用して、アクセスログからデータ転送量の合計値を取り出してみます。elblog-*
のインデックスパターンでデータ転送量はsent_bytes
フィールドに格納されています。
リクエスト
GET elblog-*/_search
{
"size": 0,
"aggs": {
"トラフィック合計値": {
"sum": {
"field": "sent_bytes"
}
}
}
}
レスポンス
{
"took": 1256,
"timed_out": false,
"_shards": {
"total": 50,
"successful": 50,
"failed": 0
},
"hits": {
"total": 4405182,
"max_score": 0,
"hits": []
},
"aggregations": {
"トラフィック合計値": {
"value": 140538714301
}
}
}
トラフィック合計値のvalue
が集計結果です。
Kibana でも簡単に表すことができます。
Bucket Aggregations
ドキュメント群をある単位でまとめる機能です。例えば、ウェブサイトのアクセスログから時間単位のアクセス数を集計する場合、Date Histogram Aggregation によってある時間単位にデータまとめることができます。ドキュメントのタームを集計する場合、Terms Aggregation を利用します。
先に紹介した Metrics Aggregation と組み合わせて、
全てのドキュメント -(Bucket Aggregation)-> 分割したドキュメント群 -(Metrics Aggregation)-> 分割した単位の集計値
といった使い方も可能です。
Date Histogram Aggregation を利用して、アクセスログから1日単位のアクセス数を取り出してみましょう。
リクエスト
GET elblog-*/_search
{
"size": 0,
"query": {
"range": {
"@timestamp": {
"gte": "2017-03-25T00:00:00.000Z",
"lt": "2017-04-01T00:00:00.000Z"
}
}
},
"aggs": {
"アクセス数": {
"date_histogram": {
"field": "@timestamp",
"interval": "day"
}
}
}
}
レスポンス
{
"took": 14,
"timed_out": false,
"_shards": {
"total": 50,
"successful": 50,
"failed": 0
},
"hits": {
"total": 4202408,
"max_score": 0,
"hits": []
},
"aggregations": {
"アクセス数": {
"buckets": [
{
"key_as_string": "2017-03-25T00:00:00.000Z",
"key": 1490400000000,
"doc_count": 455381
},
{
"key_as_string": "2017-03-26T00:00:00.000Z",
"key": 1490486400000,
"doc_count": 473337
},
{
"key_as_string": "2017-03-27T00:00:00.000Z",
"key": 1490572800000,
"doc_count": 626237
},
{
"key_as_string": "2017-03-28T00:00:00.000Z",
"key": 1490659200000,
"doc_count": 659243
},
{
"key_as_string": "2017-03-29T00:00:00.000Z",
"key": 1490745600000,
"doc_count": 668035
},
{
"key_as_string": "2017-03-30T00:00:00.000Z",
"key": 1490832000000,
"doc_count": 667299
},
{
"key_as_string": "2017-03-31T00:00:00.000Z",
"key": 1490918400000,
"doc_count": 652876
}
]
}
}
}
Kibana でも簡単に表すことができます。
Pipeline Aggregations
Elasticsearch 2.0.0 から追加された Aggregation の種類です。Aggregation の結果から集計して結果を付与する機能です。言葉で表すの難しい。。
個人的には下記エントリの説明が分かりやすかったです。特に Map/Reduce と表現が最高に分かりやすかったです。
Pipeline Aggregation は更に 2つの種類に分かれます。
- Sibling Pipeline Aggregations
- Parent Pipeline Aggregations
Sibling Pipeline Aggregations
Aggregation の結果に対して Reduce 処理ができます。例えば、ウェブサイトのアクセスログから時間単位のアクセス数に加えて、その合計値を算出する場合、Bucket Aggregation の Date Histogram Aggregation の結果に対して、Sum Bucket Aggregation することで両方の結果を得ることができます。平均値を算出する場合、Avg Bucket Aggregation を利用します。
Sum Bucket Aggregation を利用して、アクセスログから1日単位のアクセス数に加えて合計値を取り出してみましょう。
リクエスト
GET elblog-*/_search
{
"size": 0,
"query": {
"range": {
"@timestamp": {
"gte": "2017-03-25T00:00:00.000Z",
"lt": "2017-04-01T00:00:00.000Z"
}
}
},
"aggs": {
"アクセス数": {
"date_histogram": {
"field": "@timestamp",
"interval": "day"
}
},
"合計アクセス数": {
"sum_bucket": {
"buckets_path": "アクセス数>_count"
}
}
}
}
レスポンス
{
"took": 1372,
"timed_out": false,
"_shards": {
"total": 50,
"successful": 50,
"failed": 0
},
"hits": {
"total": 4202408,
"max_score": 0,
"hits": []
},
"aggregations": {
"アクセス数": {
"buckets": [
{
"key_as_string": "2017-03-25T00:00:00.000Z",
"key": 1490400000000,
"doc_count": 455381
},
{
"key_as_string": "2017-03-26T00:00:00.000Z",
"key": 1490486400000,
"doc_count": 473337
},
{
"key_as_string": "2017-03-27T00:00:00.000Z",
"key": 1490572800000,
"doc_count": 626237
},
{
"key_as_string": "2017-03-28T00:00:00.000Z",
"key": 1490659200000,
"doc_count": 659243
},
{
"key_as_string": "2017-03-29T00:00:00.000Z",
"key": 1490745600000,
"doc_count": 668035
},
{
"key_as_string": "2017-03-30T00:00:00.000Z",
"key": 1490832000000,
"doc_count": 667299
},
{
"key_as_string": "2017-03-31T00:00:00.000Z",
"key": 1490918400000,
"doc_count": 652876
}
]
},
"合計アクセス数": {
"value": 4202408
}
}
}
Parent Pipeline Aggregations
Aggregation の結果に対して、バケット間で Map 処理ができます。例えば、前のデータとの差異を取りたい場合、Serial Differencing Aggregation を利用します。更には移動平均を取りたい場合、Moving Average Aggregation を利用します。Moving Average Aggregation は単純な移動平均法だけではなく、指数平滑法や、ホルトウィンタース法にも対応しており、予測値を算出することもできます。
Serial Differencing Aggregation を利用して、アクセスログから1日単位のアクセス数の前日との差異を算出してみます。
リクエスト
GET elblog-*/_search
{
"size": 0,
"query": {
"range": {
"@timestamp": {
"gte": "2017-03-25T00:00:00.000Z",
"lt": "2017-04-01T00:00:00.000Z"
}
}
},
"aggs": {
"アクセス数": {
"date_histogram": {
"field": "@timestamp",
"interval": "day"
},
"aggs": {
"差分": {
"serial_diff": {
"buckets_path": "_count"
}
}
}
}
}
}
レスポンス
{
"took": 1303,
"timed_out": false,
"_shards": {
"total": 50,
"successful": 50,
"failed": 0
},
"hits": {
"total": 4202408,
"max_score": 0,
"hits": []
},
"aggregations": {
"アクセス数": {
"buckets": [
{
"key_as_string": "2017-03-25T00:00:00.000Z",
"key": 1490400000000,
"doc_count": 455381
},
{
"key_as_string": "2017-03-26T00:00:00.000Z",
"key": 1490486400000,
"doc_count": 473337,
"差分": {
"value": 17956
}
},
{
"key_as_string": "2017-03-27T00:00:00.000Z",
"key": 1490572800000,
"doc_count": 626237,
"差分": {
"value": 152900
}
},
{
"key_as_string": "2017-03-28T00:00:00.000Z",
"key": 1490659200000,
"doc_count": 659243,
"差分": {
"value": 33006
}
},
{
"key_as_string": "2017-03-29T00:00:00.000Z",
"key": 1490745600000,
"doc_count": 668035,
"差分": {
"value": 8792
}
},
{
"key_as_string": "2017-03-30T00:00:00.000Z",
"key": 1490832000000,
"doc_count": 667299,
"差分": {
"value": -736
}
},
{
"key_as_string": "2017-03-31T00:00:00.000Z",
"key": 1490918400000,
"doc_count": 652876,
"差分": {
"value": -14423
}
}
]
}
}
}
Kibana の Pipeline Aggregation 対応
前置きが長くなりましたが、今まで Kibana は Metics Aggregation、Bucket Aggregation にしか対応していませんでした。Kibana 5.4.0 から Pipeline Aggregation に対応し、更に豊富なデータ分析・解析ができるようになりました。
対応している Pipeline Aggregation
- Sibiling Pipeline Aggregations
- Parent Pipeline Aggregations
試してみた
いくつかの Pipeline Aggregation を試してみました。
Sum Bucket Aggregation
Sebiling Pipeline Aggregations のいいユースケースが思いつかなかった。時間単位の URL 別のアクセス数の上位 5つの合計アクセス数を表示します。
buckets は 1時間単位で集計したいので Date Histogram で 1時間のインターバル設定にします。metrics はアクセス数と、URL 別のアクセス数の上位 5つの合計アクセス数をプロットしたいので 2つ設定します。一つは Count です。もう一つに Sub Bucket を選択します。URL 毎に集計したいので Aggregation は Terms、Field は path.keyword(URL の keyword フィールド) を指定します。Metric は件数なので Count を指定します。
一時間単位のアクセス数 + 上位 5件の合計数のチャートがプロットされました。
Serial Diff Aggregation
アクセスログから1日単位のアクセス数の前日との差異を表示してみます。
buckets は 1日単位で集計したいので Date Histogram で 1日のインターバル設定にします。metrics はアクセス数と、前日との差異の 2種類をプロットしたいので 2つ設定します。一つは Count です。もう一つに Serial Diff を選択します。Metric は新しいものか、既に定義済みのものかを選択できます。今回は Count を定義していますので、metric: Count
を指定します。
一日単位のアクセス数 + 前日との差異のチャートがプロットされました。
Moving Average Aggregation
続いて、移動平均です。移動平均も基本的には Serial Diff と同じ設定でできます。Aggregation に Moving Avg を指定します。Date Histogram は 1時間単位のデータとしています。
・・・どうでしょうか。豊富な Moving Average Aggregation のオプションが全然設定できない。と思っていたら、そういえば、Advanced オプションを書けるの忘れてました。
例えば、指数移動平均モデルでウィンドウを 24、係数を 0.2 を指定するには下記のような JSON を書き加えます。
{
"model": "ewma",
"window": 24,
"settings": {
"alpha": 0.2
}
}
うん、よくわかっていないw
移動平均のプロットの時間軸をスライドさせて、予測データをプロットできると面白そうなんだけどな。
まとめ
いかがでしたでしょうか? Github の Issues でも 2015 年に起票され、ずっと +1 が続いていたのを見ていたので待ち望まれた機能なのではないでしょうか。(Pipeline aggregations #4584)利用したい方は是非、Elastic Stack 5.4.0 にアップグレードしましょう。