influxDB + Grafanaに入門する


背景

可視化ツールとしては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

docker-compose.yml
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のみ対応です。

fieldstagsの使い分けが若干恣意的なところがありそうですが、大きな違いとして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については先程も書いたとおり、fieldstagsを複数入れてみています。これで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ということになりそう。