[レポート] AWS IoT の賢い利用の仕方とプログラミングの勘所 #AWSSummit

2018.05.30

こんにちは、せーのです。
今日は2018/05/30より3日間に渡って東京、品川で開催されている「AWS Summit Tokyo 2018」からセッションリポートをいたします。

このレポートはTech上級 「AWS IoT の賢い利用の仕方とプログラミングの勘所」です。スピーカーはアマゾン ウェブ サービス ジャパン株式会社 技術統括本部 ソリューションアーキテクトの小梁川 貴史氏です。

レポート

  • 「こういう機能があります」という話をプログラムで表現するとどうなるか
  • 作らなくていいものを作っていないか
  • 開発を早くするためにご紹介します

本セッションの目的

  • 本セッションの対象者
    • IoTアプリの設計/開発者
    • AWS IoT Coreの機能を理解されている方

MQTTプログラミング

MQTTの通信方式

  • Brokerはpublisherからのメッセージを受け取り、topicへ向けて通信を送ることで当該topicを受信しているSubscriberはメッセージを受信できる
  • 通信の成功 = Brokerに対するメッセージの送信の成功(Subscribeは見ていない)
  • Subscribeは常時接続 = ニアリアルタイムの通信が行われる

SDK実装でpub/subをどう表現するか

  • クライアント生成
    • 引数でClientIDを指定
    • endpoint単位で重複を許さない
    • 重複した場合、最後に接続したClientIDが優先される
  • Credentialの設定
  • コネクションの詳細設定(オフライン時の動きとか)
  • コネクションを貼る。このときkeepalive packet送信間隔(sec) を引数に持つ、default 600(s)
  • Subscribe処理
    • コールバック関数にどのtopicから来たのかを振り分け条件として持てば、各Subscribeごとにメソッドを作る必要はない
  • Publish処理
    • payloadはjson型にして、それをstringに変換して送信

AWS IoT Coreで利用できるQoS

  • IoT Coreで利用可能なQoSは”0”と”1”、QoS=2は利用できない

sampleアプリ

  • 各言語のIoT Device SDK内にsampleアプリが入っているので、初期導入や動作確認で参考になる

必ずしもMQTTを選択する必要はない

  • 一回によるメッセージサイズ、プロトコルによってKinesis, S3などと使い分ける
  • 通信プロトコルの選択の目安
  • 機能差分観点
    • ニアリアルタイムの双方向通信: MQTT
    • データ送信しかない: MQTT or HTTP
  • コスト観点
    • 通信は固定線で利用可能: MQTT or HTTP
    • 通信はSIMを前提に考えている
      • メッセージ送信頻度が高い: MQTT
      • メッセージ頻度は低い: MQTT or HTTP
        • HTTPのhandshake, headerが通信コストに影響がある場合がある
    • MQTTをport443で利用できるようになりました
    • 8883portが空いてない企業などでも利用可能になった
  • AWS IoTにおけるMQTT常時接続 $0.063/year per device
  • HTTPリクエストはAWS IoTでは1msg, API Gatewayでは1requestのコストとなる
  • HTTPでリアルタイム性を求めるほどコストとなる

IoT Core機能の活用

Shadowアンチパターン

  • MQTTの通信におけるshadow操作の基本
    • Shadowの/getにpublishするとget/acceptedへのSubscriberに投げ返される
  • shadowの間違った使い方
  • update thing shadowをpublish(polling timeを15へ変更)
  • オペレータがshadowをアップデートすると/get/acceptedに情報が流れる
  • デバイスの初期登録時に/get/acceptedがほしいから/getに対してpublishをかける
  • どこか1台がルックアップすると全台にSubscribeがかかるのでコスト増、スケーラビリティが難しくなる
  • 大量のthingが1つのshadow/topicを参照するような設計は非推奨。
  • shadowにおいては、ここのhitngのshadowで管理
  • この場合get/acceptedより$aws/things/thing_name/shadow/update/acceptedを利用するほうがコントロールしやすい

ルールエンジンの組み込み関数/topicの有効利用方法

  • thing名の取得方法
    • payloadのjsonの中にthing名を入れる
    • MQTT接続の際に使ったclientIDをルールエンジンで取得する SELECT * as payload, clientid() as thing/name FROM ‘data/#’
    • MQTT topicを利用する
      • payloadを軽くし、MQTT topicと組み合わせて使いたい
      • topicデザインとしてdata/place/thing_nameのようにする SELECT * as payload, topic(2) as place, topic(3) as thing_name FROM ‘data/#’
  • Shadowの状態に合わせてルールを実行したい
    • thingが特定の状態のときにのみルールの実行をしたい SELECT * FROM ‘data/#’ WHERE get_thing_shadow(“thing_name”,,,)
  • 後続処理に合わせたルールエンジンの組み込み関数の利用
    • newuuid()を使って均等にKinesis Streamに分散する
  • その他
    • timestamp(): タイムスタンプ
    • parse_time(): フォーマット
    • lower() upper(): 大文字小文字化

2017年summitで発表したデザインパターンのupdate

インテリジェントシャドウパターン

  • アプリからアップデートを要求する
  • まずDynamoDBに入れてからLambdaを通じてIoTに流す
  • IoT Device MangaementのGroup機能
    • Thingの管理単位としてGroup論理表現できる
    • Group単位でのPolicy設定が可能
  • Index機能
    • queryをかけてThingを検索する
  • Jobs機能
    • 大量のデバイスをアップデートかけるときグループを指定してアップデートをかけたりステータスを確認したりできる

テンポラリトークン取得パターン

  • AWS IoTの証明書を利用したtoken取得
  • Role Aliasを作成してHTTPS get requestするだけでtokenが取れるようになった

まとめ

いかがでしたでしょうか。こちらは現場ですぐ使えそうなトラブルやアンチパターンでしたね。まずは一度自分でサンプルを作って確認してみたいと思います。