t0mmy.log

日々のコンピュータ周りのこと

Elastic stack 1node運用

この記事は、Elastic stack Advent Calendar 2016の10日目の記事です。

Elastic Stackがっつりお世話になっています。
下はFilebeatから、上はKibanaまで使用していますが、Filebeat以外は1node構成です。
1node構成でのログデータ取込みについて書きたいと思います。
CentOS6.8、Elastic Stack5.02で検証しています。

構成

f:id:t0mmy_jpn:20161208230126p:plain

1node構成では、スケールアウトをしない前提で構築することが多いと思います。
Kibanaの検索と集計も重要ですが、ログデータ取込みが所定時間内に完了することも重要です。
そこで、今回はログデータ取込みの処理速度に焦点をあてます。

処理速度に関わる大きな要素

f:id:t0mmy_jpn:20161208230132p:plain

ログデータを加工すると遅くなる

  • LogstashのFilter処理は、ログデータを加工するので、処理速度が下がります。
  • ElasticsearchのTemplate処理からのmappingは、ログデータを加工するので、処理速度が下がります。
    (例えば、Logstashでパースした値を数値としてElasticsearchに代入する場合、String -> Integerの変換がされる)

Kibanaで表示したいグラフを決めて、なるべく少ない加工をするようにします。

取込むファイルサイズを減らす

処理するファイルサイズを小さくすれば、
処理速度を上げる必要は減るので、一考の余地ありです。

加工はCPUがやっている

今回の1node構成の場合、大抵のケースはCPUを増強することで解決します。
大体2Core -> 4Coreで1.5倍に向上しました。
後はnodeを増やしてスケールアウトするしか…。
ElasticStackはデフォルト設定で割とやってくれているイメージはありますが、
どうしてもチューニングが必要な場合は、次の公式ブログが参考になります。

Logstash configuration tuning
Elasticsearchインデックス作成におけるパフォーマンス考慮事項

Logstashで処理速度を計測する

チューニングするにしても、処理速度を把握しないとどうしようもありません。
LogstashのFilterにはmetricsという便利なプラグインがあります。
metricsプラグインはイベント単位での処理速度を教えてくれます。
イベントとは、LogstashやFilebeatが処理する単位です。
multilineプラグインを使ってなければ、ログファイル1行が1イベントです。

metricsプラグインの使い方

次のようなLogstashの設定ファイルを書きます。
それぞれを/etc/logstash/conf.dに格納し、 initctl start logstashで運用します。

input.conf
Filebeatでdocument_typeでログを仕分けている前提

input {
    beats {
        port => 5043
    }
}

filter.conf

filter {
    grok {
        /* ログのフィルタ処理 */
    }
    metrics {
        meter => "events"
        add_tag => "metric"
        flush_interval => 10
    }
}

output.conf
syslog-*は適宜変更

output {
    if [@metadata][type] == "syslog-secure" or [@metadata][type] == "syslog-messages" {
        elasticsearch {
            hosts => [ "localhost:9200" ]
            manage_template => false
            index => [ "%{[@metadata][type]}-%{+xxxx.ww}" ]
            document_type => "%{[@metadata][type]}"
        }
    }
    if "metric" in [tags] {
        elasticsearch {
            hosts => [ "localhost:9200" ]
            index => [ "logstash-metrics-%{+YYYY}" ]
        }
    }
}

metricsプラグインのグラフ例

logstash-metrics-*インデックスに値が格納されますので、Kibanaでグラフにできます。
Metricbeatと組み合わせた例です。

f:id:t0mmy_jpn:20161208230112p:plain

取込処理が終わったことを検知する

Logstashのmetricの値はElasticsearchに格納されているので、
次のようなスクリプトを使えばできます。Python2でElasticsearchのsearchAPIを使ってます。

#!/usr/bin/env python
# -*- cording: utf-8 -*-

import json
import urllib
import os

host = "localhost"
index = "logstash-metrics-*"
url = "http://"+ host + ":9200/" + index + "/_search"
jsonfile = "get_metric.json"

dirpath = os.path.abspath(os.path.dirname(__file__))
jsonpath = os.path.join(dirpath, jsonfile)
f = open(jsonpath)
data = json.load(f)
f.close()

query = json.dumps(data)
response = urllib.urlopen(url, query)
result = json.loads(response.read())
rate = result["aggregations"]["rate"]["value"]
print(rate)

rate_round = round(rate)
if rate_round == 0:
    print("All data is transmitted!")
else:
    print("Filebeat is still running : " + str(rate_round))

get_metric.json
最新5分間のevents.rate_1mの最小値を得るクエリ

{
  "query": {
    "range": {
      "@timestamp": {
        "gte": "now-5m",
        "lte": "now"
      }
    }
  },
  "aggs": {
    "rate": {
      "min": {"field": "events.rate_1m"}
    }
  },
  "size": 0
}

検知の活用例

例えば、過去のサンプルデータを順々に投入していくテスト等で使っています。
過去3ヶ月分のデータを日毎のログファイルとして保存してあるので、
Filebeatの設定ファイルを書き換えるようにしてあげれば、3ヶ月分の疑似運用テストができたり。

f:id:t0mmy_jpn:20161208230117p:plain

処理速度以外に1nodeで気を付ける点

シャード数を少なくしましょう。1シャード当たり1GB-1.5GBに収まるようにします。 ログデータによって、日毎、週毎等でインデックスを作成する頻度を変えています。
インデックス当たりのシャード数を1に、レプリカを0にするテンプレートをElasticsearchに入れましょう。
他のテンプレートはorderの値を1以上に設定します。

{
    "order": 0,
    "template": "*",
    "settings": {
        "index": {
            "number_of_replicas": 0,
            "number_of_shards": 1,
            }
        }
    }
}

まとめ

1nodeで構築する場合は、Kibanaに表示する内容に制限をかけるほうがいいと思います。
それでもダメならCPUを増強しましょう!それでもダメなら1nodeやめましょう!
身も蓋もないまとめですが、以上がElastic stack Advent Calendar 2016の10日目の記事でした。