Amazon Web Services ブログ

時系列データ可視化のための InfluxDB、Grafana、AWS IoTの連携

IoTには様々な種類の実装がありますが、多くのアプリケーションでは、大量のテレメトリーデータ収集します。インダストリアルやヘルスケア、コンシュマー製品、ロジスティクスなどにおいて、IoT のテレメトリーデータは非常に時刻に依存しています。
多くの IoT ソリューションでは、データの収集やレポートのタイミングが重要になります。例えば、アノマリー検出や予兆保全のための属性分析においては、異常発生時や発生の予兆が出たときのイベントが、正確に保存され、わかりやすく資料化されることが必要です。

時系列システムは、個々の IoT デバイスレベルで考えるだけでなく、 IoT アプリケーション全体で考えることが重要です。 たとえば、工場のフロアでは、ベルトコンベアの速さと、その瞬間の搬送力と、それに伴う部品の重量が、ベルトドライブから得られるデータのみを利用するよりも、より良いベルト故障の指標を提供することができることがあります。 また、特定の障害が起こる直前のイベント/データは、データの時間変化をチャートにすることでより多くの洞察が得られることもあります。

こういった時系列データを扱う IoT アプリケーションでは、デバイス間、またはセンサーとゲートウェイソフトウェア(AWS Greengrassなど)間の時間ドリフト(進みや遅れなど)を考慮した管理が不可欠です。 IoT アプリケーション全体の時間ドリフトを管理する効果的な方法としては、各テレメトリデータのペイロードの取り込みに AWS IoT Core を使用し、取り込み時のタイムスタンプを付加することです。 覚えておくべき点として、AWS IoT Core は取り込まれたデータの順序を保証しません。そのため、取り込み時にタイムスタンプを付加する場合においても、IoT デバイス/センサーから送られるデータペイロードに対して、純増するシーケンス番号(可能であればタイムスタンプも)を付加することがベストプラクティスです。

このブログでは、時系列データを扱う IoT ソリューションの開発方法の例として、基本的な AWS IoT コンポーネントと時系列データに最適化された InfluxDB インスタンスを使用し、テレメトリデータを保存する方法を紹介します。また、Grafana と呼ばれる時系列視覚化ツールもセットアップします。 なお、InfluxDB と Grafana はどちらもオープンソースです。

AWS IoT Device Simulator は、高頻度の時系列データを生成します。 データは AWS IoT Core に取り込まれ、Lambda 関数がルールエンジンによってトリガーされて、データを時系列専用データベースに挿入します。 この例では、AWS CLI InfluxDB をインストールした EC2 インスタンスを使用します。 同じ EC2 インスタンスに AWS CLI と InfluxDB をインストールし、Grafana をインストールして、時系列の視覚化とダッシュボードを作成しました。 InfluxDB データを使用して時系列データセットを(CSVとして)作成し S3 に保存し、Amazon SageMaker を使用して異常検出 ML モデルをトレーニングおよびデプロイするといった、別のユースケースをトリガーすることも可能です。

fig

上記のアーキテクチャ図には、JSON データを AWS IoT Core に発行するエッジ IoT デバイスのシミュレーションを含みます。 AWS Lambda 関数がトリガーされ、Grafana でダッシュボードを開発するために使用される InfluxDB データベースインスタンスに IoT データを挿入します。 追加オプションとして、Lambda Step Functions をトリガーして特定の時間間隔(5分間隔の平均など)でデータを集約し、集約されたデータを InfluxDB に挿入することも可能です。 InfluxDB データは CSV ファイルとして Amazon S3 バケットにエクスポートすることもでき、Amazon SageMaker で異常検出またはその他の ML モデリングを実行するためのデータソースになります。

このブログでは、IoTデータを時系列データベースにパブリッシュし、リアルタイムダッシュボードを開発するための4つのステップについて詳しく説明しています。

  1. AWS IoT Device Simulator をセットアップします。
  2. 自分の Amazon EC2 インスタンスで InfluxDB と Grafana をセットアップします。
  3. 時系列データベースに入力するために必要な AWS IoT Core リソースと AWS Lambda 関数をセットアップします。
  4. IoT データを追跡するためのリアルタイム可視化が可能な Grafana ダッシュボードを開発します。

Step 1 – AWS IoT Device Simulatorのセットアップ

最初のステップは、ターゲット AWS アカウントに AWS IoT Device Simulator をデプロイすることです。 AWS CloudFormation テンプレート導入ガイドは、こちら にあります。 すべてのリソースのプロビジョニングに最大15分かかる場合があります。 AWS IoT Device Simulator をデプロイした後、PressureDevice という新しいデバイスタイプを作成します。 圧力デバイスは、AWS IoT Device Simulator のデバイスタイプとして表示されます。

fig

このデバイスタイプに対して、データ送信頻度の設定と、pressure、 viscosity、 sensordatetime、 deviceid、 clientid のメッセージ属性の追加を行います。

fig

各属性の設定は以下のようになります。 各デバイスと属性は、自身が作成する ID とは別に、内部 ID が割り当てられること注意してください。

{
  "name": "pressure",
  "_id_": "wzCHpAvdm",
  "min": 500,
  "type": "int",
  "max": 1500
}

{
  "name": "viscosity",
  "_id_": "NJJXwHTdW",
  "min": 25,
  "type": "int",
  "max": 100
}

{
  "name": "sensordatetime",
  "_id_": "QyKD1oCtd",
  "tsformat": "default",
  "type": "timestamp"
}

{
  "name": "deviceid",
  "_id_": "W4uk2jVHX",
  "static": "false",
  "type": "shortid"
}

{
  "name": "clientid",
  "_id_": "nXHjO4oTL",
  "static": true,
  "type": "uuid"
}

シミュレーターの Widget 画面で、pressuresensor というデバイスの新しいインスタンスを20個作成します。起動すると、AWS IoT Core の指定したトピック pressure/data に対して データのパブリッシュが開始されます。

fig

AWS コンソールを開き、AWS IoT Core に移動して、Test のメニュー選びます。指定したトピック(pressure/data)をサブスクライブして、シミュレートされたデバイスから受信したデータを確認します。

fig

デバイスシミュレーターから AWS IoT Core にデータが送信できていることが確認できます。

Step 2 – EC2 上に InfluxDB と Grafana をセットアップ

次のステップでは、VPC のプライベートサブネットに Amazon EC2 インスタンスをセットアップします。 段階的なチュートリアルについては、 このリンク を参照してください。 また、 InfluxDB と Grafana を一つの Amazon EC2 インスタンスにインストールすることもできます。VPC および Amazon EC2インスタンスをセットアップしたら、インバウンドアクセス用にポート 3000 をセキュリティグループに追加します。 ブログでは、 t2.micro インスタンスタイプとUbuntu ディストリビューションを選択します。 作成された Amazon EC2 インスタンスに SSH で接続し、 InfluxDB と Grafana をインストールします。

InfluxDB のインストールには、次のコマンドを実行します。

wget https://dl.influxdata.com/influxdb/releases/influxdb_1.7.7_amd64.deb
 
sudo dpkg -i influxdb_1.7.7_amd64.deb

インストールが完了したら、InfluxDB エンジンを開始します。

sudo service influxdb start

InfluxDB エンジンが正しく起動しているかは、 InfluxDB CLI を用いて確認できます。

influx

InfluxDB CLI を終了する場合は、 quit と入力します。

quit

次に、同じ EC2 インスタンスに Grafana をインストールします。 プロダクション環境では、同じサブネット上の別の EC2 インスタンスにインストールする必要がある場合があります。

wget https://dl.grafana.com/oss/release/grafana_6.2.5_amd64.deb 
sudo apt-get update
sudo apt-get install libfontconfig1
sudo apt --fix-broken install

sudo dpkg -i grafana_6.2.5_amd64.deb

InfluxDB と Grafana のセットアップが完了したら、データベースとテーブルを作成します。 次の構文を使用して新しいデータベースと新しいユーザーを作成し、 quit コマンドを使用してデータベースインスタンスとの接続を閉じます。

influx

create database awsblog
 
create user awsblog with password 'YourPassword'

quit 

次に、 Telegraf を追加します。(これは、メトリクスを収集、レポートするためのプラグイン駆動型のサーバ エージェントです)。

注: influxData のリポジトリを追加する必要がある場合があります。これらの追加の手順を追加するには、こちら を参照してください。

sudo apt install telegraf -y

Telegraf を開始し、有効化してみましょう。

sudo systemctl start telegraf
 
sudo systemctl enable telegraf

Telegraf が起動していることを確認します。

sudo systemctl status telegraf

基本構成を編集し、ファイル(/etc/telegraf/telegraf.conf)に保存します。 ファイルで次のセクションを探し、[[outputs.influxdb]] の後に追記します。

注:sudo を使用してファイルを保存する必要がある場合があります。これは、OSとユーザーの設定によって異なります。 nanoでは、CTRL-O でファイルをディスクに保存し、CTRL + X で nano エディターを終了します。

sudo nano /etc/telegraf/telegraf.conf

###############################################################################
# OUTPUT PLUGINS #
###############################################################################
# Configuration for sending metrics to InfluxDB
[[outputs.influxdb]]

database = "awsblog"
username = "awsblog"
password = "YourPassword"

Amazon EC2 インスタンス上での最終ステップとして、InfluxDB をデータソースとして使用するように Grafana (グラフィックエンジン)をセットアップします。 次のURI をクリックし、 Grafana UI にアクセスします。

http:// <EC2-PublicDNS>:3000 /

fig

デフォルトのユーザー名とパスワードを admin / admin から変更し、データソースをセットアップします。 InfluxDB インスタンスの URL がデータベースインスタンスのポート番号を持っていることを確認してください(URLの最後に :8086 があることを確認してください)。

fig

これで、テストする準備ができました。
EC2 コンソールを使用して、InfluxDB へのいくつかのレコードを挿入します。

influx

use awsblog
 
INSERT pressure,sensor=client001sensor01 value=1001,viscosity=34
INSERT pressure,sensor=client002sensor01 value=2101,viscosity=37
INSERT pressure,sensor=client003sensor01 value=0901,viscosity=38
INSERT pressure,sensor=client004sensor01 value=1201,viscosity=39
INSERT pressure,sensor=client005sensor01 value=1101,viscosity=60

quit

以降のステップでは、AWS IoT ルールからセンサーデータを取得し、 Lambda 関数を使用してデータを InfluxDB に挿入します。

Step 3 – Lambda 関数と AWS IoT Coreのリソースのセットアップ

Lambda関数の設定

新たな Lambda関数を Node.js 10.x で作成し、以下のコードを貼り付けます。ここでは、 blogLambda2InfluxDB という名前をつけます。

index.js のコード

const Influx = require('influx');

//This code writes data from IoT core rule via Lambda into InfluxDB 

exports.handler = async (event,context,callback) => {

    var pressureInputValue = JSON.parse(event.pressure);
    var viscosityInputValue = JSON.parse(event.viscosity);
    //Create clientID
    var clientid = JSON.stringify(event.clientid);
    var deviceid = JSON.stringify(event.deviceid);
    var sensorInputName = deviceid+clientid; 

    //var sensordatetime = JSON.stringify(event.sensordatetime);
    
    var result = writeToInfluxDB (pressureInputValue, viscosityInputValue,sensorInputName);
    
    callback(null, result);

  };

function writeToInfluxDB(pressureVar, viscosityVar,sensorVar)
{
    console.log("Executing Iflux insert");

    const client = new Influx.InfluxDB({
        database: process.env.INFLUXDB,
        username: process.env.INFLUXDBUSRNAME,
        password: process.env.INFLUXDBPWD,
        port: process.env.INFLUXDBPORT,
        hosts: [{ host: process.env.INFLUXDBHOST }],
        schema: [{
            measurement: 'pressure',
    
            fields: {
                pressureValue: Influx.FieldType.FLOAT, 
                viscosity: Influx.FieldType.FLOAT,
            },
    
            tags: ['sensorID']
        }]
    });
    
    client.writePoints([{
        measurement: 'pressure', fields: { pressureValue: pressureVar, viscosity: viscosityVar, },
        tags: { sensorID: sensorVar}
    }]) 
    console.log("Finished executing");
}    

Lambda のコンソールは、以下の画像のようになります。

fig

次に、いくつかの環境変数を以下のように追加します(ご自身の設定に合わせて値を入れてください)。

fig

Lambda 関数は、設定した環境変数を使用して InfluxDB への挿入を実行します。 Amazon EC2 インスタンス(InfluxDBサーバー)に合わせて、実行ロール、VPC、サブネット、およびセキュリティグループをを設定します。

fig

こちらにあるステップガイドラインに従って、Lambda のロールを作成して実行します(「実行ロールおよびユーザーアクセス許可」の見出しの下をご確認ください)

テストのために、ローカル環境からinflux utility にアクセスできるようにセットアップすることが可能です。

  • 次のコマンドを使用して、PC(AWS CLIがインストールされている場所)または EC2 で Lambda を作成します。
npm init
npm install —save influx
  • このリンク を参考にして、AWS Lambda 関数コード(上記 Step 3 の index.js のコードを参照)を index.js ファイルに貼り付け、それを圧縮して AWS Lambda コンソールにアップロードします。

AWS IoT Core のリソース設定

AWS IoT コンソールに移動し、Act メニューに移動します。 以下のステートメントと一致した場合に AWS Lambda 関数を呼び出すように、awsblog という 新たな IoT ルールを作成します。

SELECT pressure AS pressure, viscosity as viscosity, sensordatetime as sensordatetime, deviceid as deviceid, clientid as clientid FROM 'pressure/data'

次に、先程作成した、blogLambda2InfluxDB という AWS Lambda 関数を選択します。

fig

Step 4 – Grafana を用いてリアルタイムダッシュボードを開発

シミュレートされたデバイスからの時系列データが InfluxDB インスタンスに流れ始めたので、Grafana を使用して可視化ダッシュボードの開発を開始します。 Grafana のウェブ画面にアクセスするために、Grafana をホストする Amazon EC2 インスタンスにログオンし、http://ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com:3000/login に移動します。ここで、xxx-xxx-xxx-xxx は、 Amazon EC2 インスタンスの Elastic IP アドレスです。 上記の手順2で作成した Grafana のユーザー名とパスワードを利用します。

fig

次に、プラスボタンを押して、 Pressure and Viscosity というダッシュボードを作成します。

fig

次に、以下の画面のように適切なメトリックと集計方法を設定した新しいパネルを追加します。 Timeseries and Moving Average という名前に変更します。

fig

以下の画像のように、ダッシュボードに他のパネルを追加できます。追加するパネルや視覚化タイプによっては、外観が異なる場合があります。

fig

まとめ

AWS IoT Core、InfluxDB、Grafana を用いた時系列データの可視化は、IoT データの生成、収集、永続化、および、リッチなリアルタイムダッシュボードを生成をするのに効果的なアーキテクチャです。
このブログでは、シミュレーションデバイスを使用してデータを生成しましたが、振動、圧力、温度センサーなどの実際のIoTデバイスにおいても、このやり方をスムーズに流用できるでしょう。

このブログでは、AWS IoT Coreを使用してリアルタイムでデータを取り込む方法、およびオープンソースデータベースエンジン(InfluxDB)とオープンソース可視化プラットフォーム(Grafana)を使用してデータの可視化をする方法をお伝えしました。実際のIoTアプリケーションでも、多くの場合、時系列データに遭遇します。時系列データの可視化は、IoTの価値を提供することや、IoTセンサーによって生成されたデータを理解するための基本的な要件の1つと言えるでしょう。

また、いくつかの基本コンポーネントとネイティブなAWS機能を使用し、いかに IoT アプリケーションの開発と時系列データの可視化をシンプルに実現するかについてお伝えしました。 AWS IoT Core、ルールエンジン、AWS Lambda、Grafana、InfluxDBを活用することで、最小限のコード行数でソリューションをセットアップし、デプロイできます。加えて、一度データを AWS IoT Core に送る仕組みができてしまえば、ダッシュボードは簡単に開発およびカスタマイズができるため、データから所望の洞察を得るために、迅速なイテレーションを回すことができるでしょう。

原文はこちら。 翻訳はソリューションアーキテクト 飯田が担当しました。