背景
可視化ツールとしてはElasticsearchを常に使っていたのですが、いわゆるサーバーのメトリクスデータのような数値データを記録するのであれば、influxDBというのもあるということでお試し。
influxDB + Grafanaの概要
influxDB
influxDBは時系列DB (Time series database) と呼ばれるソフトウェアに分類される。時系列DBはその名の通り、時間を追うに従って変化するようなデータを格納する機構を備えたDBで、英語版Wikipediaだと記事ページがあるが、これによればRRDToolも時系列DBとされるよう。
RRDToolとの比較も考えつつ、influxDBの特徴を上げると以下のような点。
- データ登録はREST APIを通じてjsonで可能。
- デフォルトで認証機構を備えている。
- クエリはSQLに準じた文法を使用することが可能。
- Web UIを備えており、GUIでインタラクティブにクエリ結果を確認できる。
Grafana
GrafanaはKibanaからフォークされて作られたダッシュボードツールですが、influxDBに特化したものではなく、GraphiteやCloudWatchとも連携ができる。こちらもデフォルトで認証機構を備えている。
手順
influxDBとGrafanaの起動
手っ取り早いので公式のDockerイメージをDocker Composeで立ち上げました。
2016-12-22 追記: Grafanaのコンテナ設定にData Volumeの記述を追加。Grafanaのダッシュボード、ユーザー設定等を永続化するために、sqliteのディレクトリを保存しておく必要があったため。ダッシュボード設定等はMySQLなどの外部DBに保存させることも可能だが、簡略化の意味で、今回はデフォルトで用意されるsqliteを使用することにした。(参考: Grafana - Configuration )
version: "2"
services:
influxdb:
image: influxdb
ports:
- "8083:8083"
- "8086:8086"
volumes:
- /tmp/influxdb:/var/lib/influxdb
grafana:
image: grafana/grafana
ports:
- "3000:3000"
volumes:
- /tmp/grafana:/var/lib/grafana
influxDBで開いている2つのポートのうち、8083
がWeb UIで8086
がREST APIのエンドポイントに当たります。またデータは/var/lib/influxdb
に保存されるので、データボリュームとしてホストOSと同期させています。
GrafanaはWeb UI用のポートを開けるだけ。Kibanaの場合はkibana.yml
でElasticsearchとの接続設定をしていましたが、GrafanaはWeb UI上でDBとの接続を設定するので、この時点では特に設定ファイルなどの考慮は不要です。
influxDBとGrafanaの接続
http://(Docker HostのIP):3000
にウェブブラウザからアクセスし、左上のアイコンから「Data Sources」を選び、「Add Data Source」からhttp://(Docker HostのIP):8086
へ接続します。
なお認証ユーザーIDとパスワードの初期設定は、influxDBがroot:root、Grafanaがadmin:admin。
influxDBへのデータ投入
今回はPythonを使いましたが、その前に前提としてinfluxDBの構造の話。
influxDBの構造
-
Database
: RDBMSにおけるデータベースと同様、最も大きなデータ単位。Database
はデータ投入前に作成しておく必要がある。 -
Measurement
: RDBMSにおけるテーブルの位置。 -
Retention Policy
: データの保存期間を定めたDURATION
と、influxDBクラスタ内でいくつデータのコピーを保持するかを定めたREPLICATION
からなるデータの保存ポリシー。基本的にはDatabase
に対して紐付ける形で使用する。
まだお試しなのでちゃんと使っていないのですが、Retention Policy
があるのがいいですね。データを無制限に保存して容量が溢れてしまうような事象を防げるのと、可用性を担保できるのと。
influxDBのデータ構造
Elasticsearchだとjsonを適当に突っ込むとそれでもう使えたので、APIから取得したjsonをそのまま投げるようなズボラ運用もできたんですが、influxDBの場合はjsonに含むべきデータ構造が決められています。
-
measurement
: どのmeasurement
にインポートするかを指定。 -
fields
: いわゆるデータそのものをキーバリューの形式で指定する。キーは文字列型限定ですが、バリューは文字列の他にfloat, integer, booleanにも対応しています。また複数のfield
を含めることも可能。 -
tags
: オプショナルなデータを指定する。例えばサーバーのメトリクスデータを入力しているのであれば、サーバー名を指定するのがtags
。こちらも複数含めることはできますが、文字列型のみに対応している点に注意。 -
timestamp
: データのタイムスタンプ。時系列データの要と言ってもよい部分。指定しなかった場合は入力処理が行われた時刻が自動的に適用されます。なお、influxDBは UTCのみ対応です。
fields
とtags
の使い分けが若干恣意的なところがありそうですが、大きな違いとしてfields
はインデックスされませんが、tags
はインデックスされます。従ってクエリをかけるときに例えばGROUP BY
句を使ったりすると思いますが、ここで使用するのはtags
の方です。検索等に使うメタデータがtags
で、時系列で変化するデータがfields
と押さえればよいかと。変化するデータ、例えばCPU使用率が80%のとき、などというクエリは普通かけないので、そう考えるとfields
がインデックスされないというのは納得ですね。
データ投入処理
簡単にソース示します。
from influxdb import InfluxDBClient
client = InfluxDBClient('127.0.0.1', 8086, 'root', 'root', 'sample')
# databaseの存在を判定し、作成前であれば新規作成
dbs = client.get_list_database()
sample_db = {'name' : 'sample'}
if sample_db not in dbs:
client.create_database('sample')
# インポートするjsonデータを作成
import_array = [
{
"fields" : {
"cpu" : 50.0,
"mem" : 20.0,
},
"tags" : {
"category" : "fuga",
"machine" : "web02"
},
"measurement" : "metrics"
}
]
# データ投入
client.write_points(import_array)
簡単です。InfluxDBClient
に直にパスワード書いていますが、本運用する際はハードコーディングはやめるべきところです。データのjsonについては先程も書いたとおり、fields
やtags
を複数入れてみています。これでMachineごとのグラフを描いたりすることができます。
Grafanaでの可視化
GUIでの操作になるので詳細は割愛しますが、KibanaのようにDashboard上にPanelと呼ばれるパーツを配置していく形で可視化していきます。PanelにはGraphのほか、最新の値だけを数字で大きく表示させたりできるSingle stat、Markdown等で文章が書けるTextといったものもあり、自由度は高いです。
またGraph等で表示するデータを指定する際は、SQL文で設定するため、わかりやすい一方でinfluxDBにおけるSQL文の使用方法は押さえておく必要があります。とはいえGUI上で候補をクリックしながら組み合わせてSQLを作れるので、多少曖昧な理解でもなんとかなります。とても楽です。
使用感、ES+Kibanaと比べて
Elasticsearch + Kibanaの使用感をイメージすると、インプットするときに設定する必要のあるjsonのキーが定められていたり、勝手が違うところに戸惑いはしましたが(というよりはjsonなら何でも突っ込めて程々に検索できちゃうESが神)、使用感としてはやはり「簡単にデータの可視化ができる」、しかも見やすいという点では一致しています。はじめはElasticsearchと競合するのかな?と思っていましたが、現在では両者は明確に異なる守備範囲を持ったツールとして理解しました。
- influxDB : 文字通り時系列データであり、時を経て「変化」する値に関し、その変化を可視化する点に特化されている。
fields
には文字列も入力できるが、インデックスされていないため検索用途には向かない。 - Elasticsearch : Kibanaでの可視化、グラフ描画が便利なので忘れていたが、こちらは「全文検索エンジン」。投入した大量の文字列データから検索をかけたい場合にはこちら。
例えばMySQLを運用するにあたり、スロークエリログを長期間取り溜めて解析を行いたい場合にはElasticsearchが適切ですし、トラフィック量を監視したいのであればElasticsearchでも可能ではありますが、棲み分けとしてはinfluxDBということになりそう。