Elasticsearch Kibana is a great tool!
話が少し長くなります。
時系列データベースとプロットツールの歴史など
以前から、温度センサや湿度センサから取得したデータをプロットするのが好きなのですが、データ保存およびグラフ化のツールとして、ずっと RRDtool を使ってきました。(もっと言うと、MRTG の頃からのファンでもあります。)
RRDtool は、あまり「今風」な設計でなく、最近の若い技術者さんは見向きもしないと思うのですが、ポイントをしっかり押さえたソフトウェアです。軽量で安定して動作し、デプロイメントもシンプルです。具体的には、cron で定期的に起動したり、シェルスクリプトに sleep コマンドと一緒にループを組んだりするだけで、グラフを PNG ファイルなどで生成してくれるので、それを HTTP サーバーのファイルディレクトリに置いて上げるだけで、とりあえず公開できます。
さらに重要なのは、生成されるグラフが十分に練られ実用的であり、軸(axis)表示をいじってみたいとか、tick や label をカスタマイズしてみたいなど、あまり頭を悩ますことがありません。(唯一、ときどき Y 軸のオートスケーリングが自分の期待通りでなく、チューニングしてみたくなることはあります。また、label に TeX 風の記述(m$^2$ とか)ができたら嬉しいですけど、やり過ぎでしょうか。)
他には、センサからのデータには時間軸上の欠損があり得るということを初めから設計思想に盛り込んでいるのも良い点です。センサから期待通りにデータが来ているときは線グラフで表示するが、データが一定時間以上得られない場合は、その部分のグラフを表示しない、という当たり前のことを簡単に実現できます。(これを簡単にできないツールが非常に多いのです!)
それではなぜ RRDtool では不満かというと(はい、不満なのです)、ウェブ上にグラフを表示して、マウスなどを使ってインタラクティブにグラフを操作するという(今風で、お客様に受けが良さそうな)ことが、残念ながら簡単には実現できないことと、生データの操作や閲覧がやや面倒だということです。基本的にデータをリアルタイムに書き込むようになっていて、過去のデータをバッチ的に書き込んだり、データをコピーしたりすることは、あまり想定していないようです。
話は変わりますが、技術屋のグラフ作成ツールとして往年の gnuplot というものもありますね。工学系や理学系の学生で、gnuplot を知らなければモグリとも言えるでしょう(?)。gnuplot も現代的な代替ツールがなく、Matplotlib や Flot、Plotly はありますが、gnuplot に比べてツールとしての学習(習熟)曲線が良くないように感じます。
Node-RED は好きなんだけど
最近は、JavaScript をグリグリ使ってしゃれたグラフをウェブに表示するツールを多く見かけますが、技術屋的には眉をひそめるようなグラフ表示が多く、あまり魅力を感じませんでした。意味もなく高次スプライン補間をしてぐにゃぐにゃなグラフを表示したり、プロットの左右が軸に合ってなかったり、ひどいものになると tick が等間隔でなかったり、そうでなくとも、tick が 5 や 10の倍数になっていないとか、有効桁の概念を分かっていないとか、それってグラフじゃないでしょう! あなた理科系じゃないでしょう!(← 言い過ぎです)というものが非常に多いです。
以前からこのブログでも紹介している Node-RED でも、Node-RED は非常に面白いソフトでありますが、dashboard の chart(折れ線グラフ)表示は、はっきり言ってお粗末です。フリーソフトウェアであるので自分で修正すれば良いのでしょうが、グラフ表示の基本を分かっていない設計なのだと思うと、どうせ直しても本家に pull されることはないだろうなあ、まあ、いいか、という感じでした。(dashboard のグラフは、Node-RED を終了してしまうとグラフデータが消えてしまったり、と、全体に荒削りな印象です。いろいろと逃げ道は提案されていますが。)
Python + pandas という手もある
次に手を出したのは pandas です。これはグラフ化ツールというよりも、数値データ解析のための Python ライブラリです。R 言語を意識しているそうで(私は R は知らない)、流行りのデータアナリストが Python と NumPy, SciPy、さらに Jupyter Notebook を併せてガリガリとデータ解析するには最高のツールなのではないでしょうか。
このように優れたライブラリではあるのですが、ウェブでリアルタイムにグラフを表示したりするには、ある程度のプログラミングをせざるを得ず、時系列データが適切なデータベース(後述の Whisper とか Elasticsearch など)に入っていない場合、年間にわたるような長期時系列データをプロットしようとすると、データベースへの query でゴリゴリと aggregation, resample(間引き)処理をせざるを得ず、お気軽とは言えない環境です。RRDtool で簡単にできたことを、Python, pandas, Matplotlib,(MongoDB のような)データベース、Flask などを総動員して実現することを考えると、RRDtool が非常にポイントを押さえた現実的なツールであることが分かります。(もちろんツールとしての目的が違うので、乱暴な比較です。単純に、「私がやりたいこと、お客様に見せたいことを、どれだけ簡単で美しい視覚化ができるか」という点でお話ししています。別の言い方をすると、私は「2割の労力で 8割を実現できる」ツールが好きなのです。)
結果として、時系列データの視覚化ツールとして、pandas を取引先にお勧めするのは諦めざるを得ませんでした。お客様には、「Microsoft Excel で、CSV データをプロットすればいいんじゃないですか?」と言われる始末です。。。
なお、pandas ではグラフの表示は基本的に Matplotlib を使うことになっているようですが、後述のように Plotly を使うこともできるようです。(実はまだ Plotly 未体験。)
Grafana を触ってみる
さて、世の中には Tableau とかいうツールがあることも知りましたが、これはやや高価なツールです。一方で、Grafana という視覚化ツールが面白そうだったので、MongoDB に格納したデータをプロットしてみることにしました。まず最初に困ったのは、Grafana は標準では MongoDB に対応していない、ということでした。よくよく調べると、IoT などのセンサ測定データ(メトリクス)を MongoDB に蓄えるのは、あまり良いやり方ではないようでした。時系列データの保管には、MongoDB や MySQL などよりも、OpenTSDB ですとか、Graphite Whisper、InfluxDB、さらに後述の Elasticsearch などを使うべきだそうです。
ま、今となっては既に蓄えてしまったデータがあるので、とりあえず Grafana 用の MongoDB 用プラグインを探してきて利用させて頂くことにしました。便利に使わせて頂いたのですが、問題は Grafana です。
Grafana は見た目はまあまあなのですが、設計にいくつか不満な点がありました。一つは、セキュリティとユーザー認証の扱いです。Grafana で、あるダッシュボードを公開するには、まず最初に公開用の organization を用意し、そこにダッシュボードを作る(場合によっては既存のダッシュボードをコピーする)必要があり、やや煩雑です。試しに作ったダッシュボードを人に見せるために、さらに別の organization というインスタンスを作るのは面倒に感じました。ま、Node-RED の dashboard では、そもそも複数のダッシュボードを用意することすらできないので、贅沢な言い分かも知れませんが。
しかしもっと不便に感じたのは、グラフ表示のカスタマイズが難しいことと、(原則として)時系列グラフがダッシュボード全体で同一時系列になるようになっていて、これは変更できるのですが、主要な設計指針とは異なるようで、使い方の一貫性が崩れてしまいます。ウェブ上の議論を見ていると、それはできない、あれもできない、それは Grafana のせいではなく、データベースの責任だ、などなど、ちょっと学習曲線の不連続点を多く感じられます。つまり、ちょっとした(Grafana の価値観にあっている)ことは「比較的」簡単に実現できるのですが、ちょっと工夫しようとすると、極めて困難だったりするのです。
というわけで、Grafana は「あるがまま」に利用するには便利なのですが、取引先に「受け」るように表示を工夫しよう、と考えたりすると、いろいろと障壁が多そうで、これまた利用を断念しました。
後記(2019/3/11)
上記はちょっと Grafana にネガティブな印象を与えてしまっています。後日の日記に書きますが、Grafana にも優れた点がありますので、御参考ください。
Elasticsearch と Kibana を見つける
IoT のセンサデータを蓄えるには、どんなデータベースが良いのだろうと(上述の通り)悩んでいたとき、Elasticsearch というものを見つけました。本来はセンサなどの時系列データを保存するために作られたものではなく、(私の印象としては)ネットワークやサーバーなどのインフラ管理者が、Kibana を併用して、システムの様々な部分で予想しない事態が起きていないか(ネットワークトラフィックが急激に増えていないか、不正なアクセスや DoS 攻撃は発生していないか、サーバーのメモリに空きがなくなっていないか、サーバーの筐体温度は大丈夫か)を、大きなダッシュボードに表示して監視するために使うもののようです。さらに、サーバーアプリのいろいろなログを自動監視するために、テキスト検索のエンジンも持っているようです。(後者のほうが主要な目的なのかも)
しかし、ネットでいろいろ調べると時系列データをうまく扱うのに向いているらしいこと、さらに私がずっと悩んでいた問題、つまり「時系列のデータのうち、そのデータが古くなれば古くなるほど自動的に間引いてくれる仕組はないか」という、RRDtool が簡単に実現していたことを、Elasticsearch では Rollup というアイデアで対処できるようになっていることを知り、これは面白そうだ、と感じました。RRDtool では、例えば過去 1時間のデータは 5秒単位に保管するが、1時間を過ぎたら 1分単位に間引き、1日を過ぎたら 10分単位に間引き、1月を過ぎたら、、、ということを初期設定(スキーマ設計?)で指定することができ、あとはおまかせで古いデータをどんどん消してくれるのです。Elasticsearch の Rollup は、これをもっと洗練された(あるいは凝った)方法で実現しているようです。正直言って、RRDtool のやり方でも十分なことが多いのですが、とりあえずデータベースに 1秒単位など大量のデータをたたき込んでおいて、後から Rollup を検討したい、という向きには便利なのではないかと思います。(まだ試していないのですが。)
最後になりましたが、Elasticsearch の素晴らしい点は、コンパニオンツールである Kibana に非常に多くの機能があることです。パッと見の限りですが、グラフ表示もまあまあ美しいようです。はっきり言って、このツールが無償であるというのは驚きですが、実際問題として、取引先などに紹介する場合は Elasticsearch 社や Amazon AWS などの有償クラウドサービスを提案すべきでしょう。(IBM Cloud でも利用できるようです。) ソースコードを公開してくれていることに感謝しつつ、ある程度お金のある企業様には有償版を使って頂く、というのが、このような優秀なソフトウェアが末永く正しい発展を続けていくために、必要なことなのではないかと思います。
Kibana も、まだちょっと触っただけなので、使っているうちにいろいろ不満は出てくると思います。(私ははっきり言って文句が多い!) いずれ、Kibana についても書いてみたいと思います。
Elasticsearch 補足
ところで、初めて Elasticsearch に触れると、非常に捉えどころのない印象を受けます。…search とあるからテキスト検索エンジンにも思えますし(その機能もあるようですが)、Kibana や Logstash との関連がよく分かりません。まるで近年の Amazon AWS の製品群のようです。S3, EC2 くらいまではすぐにイメージができたのですが。
閑話休題。私も触れたばかりなのですが、自分でインストール作業をしてみたので、勘所が少しだけ分かりました。備忘録を兼ねて書いておきます。Elasticsearch はクラウド製品を使って欲しいのだと思いますが、探すとローカルのサーバーへのインストール方法が見つかります。
Elasticsearch はデータベースです。データの格納や query は HTTP と JSON を用います。極端なことを言えば、curl というツールがあれば大抵のことができるようで、Elasticsearch と直接お話するアプリを書けそうです。ところで、最初の動作確認で「GET /」をしろとあったので、古風な私は telnet で GET / したらエラーになってしまいました。HTTP のバージョンの相違でしたっけ。素直に curl を使ったほうが良さそうです。
Elasticsearch はポート 9200 で上記の通信を listen してますが、とりあえず localhost 内からだけ接続を受け付けるようにしておきます。(デフォルト動作です。) そして、必須ではないようですが、同じホストに Kibana をインストールします。(Kibana を使わないというのは、硬派な使い方のようです。) Kibana をサーバーにインストールした場合は、Kibana の設定で自分のパソコンから接続できるようにすると良いようです。(参考)
Kibana は、デフォルトでポート 5601 を listen しているので、パソコンのブラウザからこのポートにアクセスすれば、瀟洒なウェブ画面を見て感激できます。あとは、ここのチュートリアルを見てください。
長くなりましたが、今日はここまで。「後述する」と書きながら、Whisper、Dash Plotly など「後述」していないことがいくつかあるようですが、それはまた今度書きたいと思います。