♦️

Greengrassを使ったIoTのアーキテクチャ

2022/03/21に公開

IoTのアプリケーションをAWSのGreengrassを使って構築したので、その概要についてまとめます。

作ったもの

以下の図の通りです。建設現場のセンサで取得したデータをラズパイ(ここでGreengrassが動いている)に送り、クラウドのDBに保存してタブレットで閲覧するというアプリです。

システム構成

以下がシステム構成です。この記事で触れるのは、左側の「センサからのデータを受け取ってクラウドに送信&受信」する部分、というか、ほぼGreengrassについての内容となります。

Greengrassとは?

教科書的に言うと、AWSの機能をエッジデバイスに拡張するサービスです。もっとざっくり言うと、Greengrassを使えばデバイス上でLambdaを動かせる、とまずは認識いただければ良いと思います。(Lambdaを動かせること自体は、Greengrass全体の機能の一部ではありますが)

ただし、クラウドの上で動かすLambdaとはいくつか違いがあり、例えば、クラウドの上で動かすLambdaはタイムアウト15分という制約がありますが、Greengrass上で動かすLambdaは上限なしで常駐させることが可能です。

(引用:AWS Black Belt)

Greengrassを使用するメリット

個人的には以下3つがあると思っています。

  1. MQTTを使ったクラウドへのデータ送信が簡単に作れる
    Greengrass用のSDKが用意されており、クラウドにMQTTを使ってデータを送信する処理がすごく簡単に書けます。以下がNode.jsのコードです。例えば以下コードを数秒おきに定期的に呼び出すように実装するだけで、クラウドへの定期的なメッセージ送信が実現できます。
import ggSdk from "aws-greengrass-core-sdk";
const iotClient = new ggSdk.IotData();
iotClient.publish( { topic, payload }, publishCallback);
  1. デプロイの制御が簡単にできる
    仮に、デプロイする対象のエッジデバイスが複数台あったとしても、数クリックでデプロイできます。自力で各デバイスにデプロイする仕組みを作ろうと思うと、結構大変だと思うので、助かります。

  2. ログの管理がしやすい
    設定さえ行えば、各エッジデバイスのログをCloudWatch Logsに送ることができます。ただし、挙動に少しクセがあるので、後述します。

設定〜デプロイの大まかな流れ

3つのステップがあります。詳細は公式のドキュメントを参照いただく前提で、それぞれのステップについて、概要をつかんでいただくためにざっくり記載します。

デバイスの設定

ラズパイにGreengrass Coreのインストールパッケージをダウンロードして、インストールコマンドを実行します。これを行うことで、AWS上のGreengrassの画面に、インストールしたデバイスが表示されます。
詳細な手順は、以下の公式ドキュメントに記載があり、その通りに実施すればいけると思います。
https://docs.aws.amazon.com/ja_jp/greengrass/v2/developerguide/quick-installation.html

マイコンポーネント(Lambda)の作成

Greengrassでは、必要なモジュールをコンポーネントと呼ばれる単位でデプロイします。以下のような画面で、Lamdaを使ってコンポーネントを作成できます。

コンポーネントのデプロイ

上記ステップで作成したマイコンポーネントとは別に、AWSで既に用意されているパブリックコンポーネントというものも存在します(CloudWatch Logsとの連携用など)。必要に応じてこれらを組み合わせて選択肢、デプロイします。

はまったポイント

  • Greengrass自体にバグが残っている
    Greengrass(V2)は2020年の年末にリリースされた、比較的新しいサービスであるため、バグがちょくちょく残っています。一番ハマったのは、「メッセージの送信を許可するトピックの設定に、”hello/#”のようにワイルドカードを挟むと、メッセージが二重に送信されるバグ」を踏んだ時でした。こちらは、AWSのサポートに連絡してやりとりしていく中で、バグであることがわかり、修正いただきました。

  • その他
    JavaScriptには新ver用のsdkがないため、パブリックコンポーネントであるLegacySubscriptionRouterを入れないとメッセージの送信ができなかったり、メモリ増やすにはLambdaのメモリだけでなくJVMの設定が必要だったり、いろいろとハマりましたが、ここでは詳細は割愛します。後者については、NCDCの茨木さんが以下の記事で紹介しています。

https://zenn.dev/ibaraki/articles/351f648e719ed0

実運用に向けたポイント

CloudWatch Logsへのログの送信

パブリックコンポーネントであるLogManagerをデプロイすると、CloudWatchにログを送れますが、挙動に少しクセがあります。設定の具体的な手順については以下を参考にさせていただきました。

https://dev.classmethod.jp/articles/greengrass-v2-log-manager/

少しクセがあるというのがどういうことかと言うと、ログをリアルタイムでは送ることはできず、デバイスに新しいログファイルが生成されるタイミングで送られます(設定したにもかかわらず、ログがなかなかCloudWatch Logsに送られないので、結構ハマりました)。ちなみに、Greengrass V1の時はリアルタイムに送られてた、、
そして、デバイスに新しいログファイルが生成されるタイミングがいつかと言うと、以下のいずれかになります。

  • 1時間経過&次の時間帯の新しいログが出力された場合
  • ログファイルのサイズ上限(デフォルト1024KB)をオーバーした場合

上記の条件を踏まえて、よりリアルタイムに近づけようと思うと、ログファイルのサイズ上限を小さくするしか手段はなさそうです。なので、厳密にリアルタイムで見るにはデバイスにsshするしかないと思われます。

まとめ

  • Greengrassを使うと、エッジデバイス(ラズパイなど)から簡単に クラウドにデータを送れます。
  • たまにバグと出くわしたり、トラブルが起きた時の情報がまだ少ないです
    →抱え込みすぎず、サポートなどを有効に活用しましょう

Discussion