IoTシステムにおけるセンサーデータの扱い方の注意点
我々が生きている物理的な世界からデータを集め、クラウドという空間に情報を送るには色々面倒なことがあるということで、前回は実世界からのデータ収集の難しさとデータの到達保証について書きました。
IoTシステムで苦労する部分はもう1つあります。それはクラウドに貯めたデータを取り出す部分です。
IoTシステムで扱うデータは主にセンサーから集められたデータです。センサーは毎分あるいは毎秒データを吐き出すので、時間順で並んだデータということで、時系列データと呼びます。
たとえば騒音センサーが騒音データを毎秒計測している場合、このデータを単純に収集すると、1データポイント x 60秒 x 60分 x 24時間 x 365日 = 31,536,000データポイントになります。たった1個のセンサーのデータを1年間集めただけで3000万件以上のデータが生成されてしまいます。
実際に企業で使われているセンサーデータシステムの設計を見てみると、これらのセンサーの時系列データを通常のデータベース(リレーショナル・データベース)などに格納するような作りになっていることが多々ありますが、これは良い設計とは言えません。
集められたデータの使い方として一般的なのは、ある期間のデータを取り出して、グラフの形で可視化するものです。たとえば、過去1年間で騒音が激しかった時の状況を調査したいというニーズがあったとします。これを実現するには、過去1年間のデータを取得し、騒音が激しいピークを検出する必要があります。
通常のデータベースでこの作業をインタラクティブに行おうとすると、3000万件のデータを読み出して最大値を求めるような作業が必要になります。今どきのサーバーはかなり高速になったとは言え、3000万件のデータ読み出しには1-2分程度の時間がかかります(手元での測定にて)。つまり、ユーザーがデータをリクエストしてから結果が画面に出るまでに最低1-2分かかってしまい、「お待ち下さい」の回転マークを長時間ださざる終えません。これはあまり良いユーザー体験ではありません。できれば1年間のデータを処理する場合でも瞬時に結果が変えられるべきです。
似たような問題で、毎秒収集されたデータを1日分グラフ表示したい場合を考えてみます。1日分のデータは86400件ですので、直接読み出してもなんとかなる量ですが、8万件のデータはサーバーから離れたユーザーの元に送ると、2つの問題が起こります。
データ転送量が多くなるので、その部分の遅延
ブラウザ側のJavaScriptのグラフ描画の負荷
やってみるとわかりますが、8万データポイントのグラフをブラウザのJavaScriptで描画すると耐えられないほど重く感じます。
画面上のグラフがきれいに見えてかつ有用なためには、だいたいグラフ上の点の数が100-200程度あれば十分です。1日のデータの場合は、だいたい10分ごとにデータをまとめて144データポイントのグラフ描画用の集計データを返すとよいでしょう。
この2つの例でも分かる通り、通常のデータベースにセンサーなどの時系列データを保存するというのはベストな方法とは言えません。生のセンサーデータはむしろログデータのような形で収集し、利用目的に合わせてデータを加工し、加工済みデータを主に使うというアプローチが良いと思います。
長期間でデータは、ログ形式の生データからdaily(日次)データとして集計を行っておき、こちらを読み出すようにすれば、1年間のデータ読み出しは365レコードの読み出しでしかありませんので瞬時に結果を返すことができます。
1日のグラフ描画のためには10分おきのデータを同じように生成しておけば、同じく効率的になデータを返すことができます。
加工済みデータを用意するとストレージ利用量は増えますが、ユーザー体験の向上を考えれば十分意味のあるトレードオフといって良いでしょう。
MODEではMODE TSDB(時系列DB)として、このようなデータ加工をサービス内部で実装し、使う側はこれらのことを特に考えずデータを入れれば良いような運用を行っています。過去3年ほどこのような形でのシステム運用を行っていますが、ほとんどの用途には対応できているようなので設計としては適切なアプローチだと考えています。
まとめ
センサーのデータは定期的にデータが発生する時系列データで、データ量が非常に多い
時系列データをリレーショナル・データベースへ格納し、直接使うのは効率が悪い
生データと利用データは分離し、生データから生成した加工済みデータを利用すると良い
※ 別媒体からの転載記事です。
※ 掲載内容は2019年12月当時のものです。