ストリーム処理勉強会 大規模mqttを支える技術
-
Upload
keigo-suda -
Category
Internet
-
view
1.965 -
download
1
Transcript of ストリーム処理勉強会 大規模mqttを支える技術
⼤規模MQTTを⽀える技術(のための相談)
ストリームデータ処理技術勉強会2017/8/4
Future Architect Inc,Keigo Suda
どういった構成で何がポイントとなったかü どういった課題があったかü どのように対応したかü MQTTにプロトコル仕様などは話しません
物流IoTのメッセージングの話
* Technology Innovation Group * ビッグデータユニット リーダー* 最近の専⾨ -> ストリーム処理のあれこれ
須⽥桂伍 (すだ けいご)
@keigodasu
もくじl 全体の概要l メッセージングの話l MQTTプロダクト選定の話l これからの課題
全体の概要
全体の概要l 物流系のIoTなシステムl トラックなど⾞両等から位置情報やイベント情報を収集するための仕組みl クラウド側(AWS)からデバイスに対する制御処理もありl 数⼗万デバイスからの連携
システムの全体像
ローデータ配置先
ストリーム
集計・広範囲スキャン
アーカイブデータ配置先
時系列データ上り受付&プロトコル変換 全システム共通バス
ジオデータ サービスAPI
下り制御処理
サービス間接続
MQTTS
MQTTS
MQTTS
MQTTS
フィールド側 クラウド側
システムの全体像
ローデータ配置先
ストリーム
集計・広範囲スキャン
アーカイブデータ配置先
時系列データ上り受付&プロトコル変換 全システム共通バス
ジオデータ サービスAPI
下り制御処理
サービス間接続
MQTTS
MQTTS
MQTTS
MQTTS
フィールド側 クラウド側
これから話すところ(メッセージング)
メッセージングの話
メッセージング部分の詳細
イベント/コマンドデータ受付
センサデータ受付
バイナリデータ格納ストレージ
ブリッジアプリ
ブリッジアプリ
MQTT
MQTT
HTTPS
HTTPS
HTTPS
MQTTS
MQTTS
メッセージバス ストリームエンジン
ブローカーにMQTTからHTTPSへ変換し連携するブリッジアプリケーションを配置
直近の連携されたメッセージデータを永続化MQTTS
時系列データ⽣成
ジオデータ⽣成
通知データ⽣成
利⽤形態/メンテナンス単位にストリームアプリケーションはデプロイ
センサストリーム
イベントストリーム
センサデータの連携
イベント/コマンドデータの連携
バイナリデータの連携 センサデータ
イベントデータ
コマンドデータ
デバイスから定常的に発⽣するデータ
デバイスの状態変化などイベントをトリガーに発⽣するデータ
デバイスからのクラウド側へ要求を出す際に発⽣するデータ
イベント/コマンドデータ受付
センサデータ受付定常的に発⽣するセンサデータは、都度最新のデータを取得する、時間をおいた再送で情報を補填可能であるため、性能を重視しQoS=0(at most once)で連携
バイナリデータ格納ストレージ
ブリッジアプリ
ブリッジアプリ
センサデータの連携
イベント/コマンドデータの連携
バイナリデータの連携
状態の変化などイベントをトリガーに発⽣するイベントデータは、当該イベントに基づいてクラウド側での判断及び制御処理が⾏わるため、確実性を重視しQoS=1(at least once)で連携
画像などの⼀つのサイズが⼤きいバイナリデータは、バッファリングを⾏いながら連携する必要があるためHTTP(S)でプロトコルの機能を利⽤し連携
MQTT
MQTT
HTTPS
HTTPS
HTTPS
MQTT
MQTT
MQTT
QoS=0
QoS=1
QoS=1
データ種毎に応じた到達保証l 連携されるデータの種類や、処理特性に応じてメッセージ到達保証を調整l ⼊り⼝から分けてしまう⽅が扱いやすい(エラー時の切り分けとか)
クラウドからのフィールド制御l 基本はQoS=1(at least once)で連携し、アプリケーション側でのハンドリングl プロトコルで到達保証はほどほどに
フィールドトリガー
フェールドからのイベントデータ/コマンドデータをもとに、クラウド側で判断処理が⾏われ、その結果をもとにフェールドへの制御処理が⾏われるパターン。
クラウドトリガー
MQTT
MQTTMQTT
publish
publish
subscribe
subscribe
MQTT
HTTP
subscribe publish MQTT
HTTP
1. イベントもしくはコマンドデータが発⽣ 2. データ内容に応じた処理を実施
3. 処理結果もしくは次アクションを⽣成4. 処理結果をより取得し次アクションへ
2. プラットフォームより通知を作成3. 通知内容をプラットフォームより取得
4. 処理結果をもとにした次アクションへ(例:オブジェクトストレージからのダウンロード)
1. プラットフォームより通知処理が必要な処理が発⽣(例:エッジからのバイナリダウンロード処理)
クラウド側からエッジへ通知処理が⾏われ、その内容をもとにデバイスが次アクションを実⾏するパターン。
QoS=1 QoS=1
QoS=1 QoS=1
QoS=1 QoS=1
MQTT
MQTT→Kinesisへのブリッジアプリケーションl ブリッジアプリはMQTTトピックをサブスクライブし、Kinesis Producer
Library(以下KPL)を利⽤してKinesiへProduce処理を実施
Subscriber KPL
ブリッジアプリケーション
MQTT HTTPS
Subscribe Produce
Topic
ブリッジのシーケンス
Subscirber KPLMQTTブローカー Kinesis
Subscirber KPLMQTTブローカー Kinesis
データをSubscribe
KPLへメッセージをPut
KPLへメッセージをPut
KPLへメッセージをPut
データをSubscribe
データをSubscribeメッセージをバッファリング
メッセージに集約してKinesisへProduce
ブリッジアプリケーション
どのようにスケーラビリティを確保する?l MQTTブローカーにはクラスタリング機能を備えているものも多いが、あくまで内部
ルーティング,フォワード機能であることが多いl Apache Kafkaと同じノリで処理性能をスケールできない(できるものもある?)
MQTTブローカー#2
Publisher
MQTTブローカー#3MQTTブローカー#1
topic/a Topic/b Topic/c
Topic/aにPublish
forward
じゃあ・・・l トピックをシャーディングする?(some-topic/1, some-topic/2 ・・・)
l クライアント側でシャーディングを意識する必要あり。。。l クライアント側はロジックをあまり持たせたくない(不特定多数なので変更時の対応・・・)
ストレートレスに並べていく
ブリッジアプリ
MQTTブローカー
MQTTブローカー
MQTTブローカー
同⼀名のトピック
トピック
同⼀キュー名で全ブローカーにキューを作成どのノードにもパブリッシュできるようにする
ローカルのキューのみをサブスクライブし、KinesisへメッセージをProduce
オートスケーリング時はトピックキュー情報を取得し、同⼀の構成に初期化後参加する
構成情報管理
MQTT
全システム共通バス
ブリッジアプリトピック
ブリッジアプリトピック
オートスケール時のステップ1. EC2起動 2. 初期化 3. スケールアウト 4. スケールイン
1
2 1 2
1
2
負荷状況をもとにアラームが発⽕し、オートスケーリング(スケールアウト)が発動
EC2が新たに起動し、Lifecycle hook発⽕
1
2
MQTTブローカー上に存在するキュー情報を取得
取得したキュー情報をもとに同⼀のキューを作成
1 キュー作成後、ELBにアタッチされ処理を開始 1
2
負荷状況をもとにアラームが発⽕し、オートスケーリング(スケールイン)が発動
EC2がELBから外され、Lifecycle hookが発⽕
3 Lifecycle hookでキュー内の未処理データを全てKafkaへProduce後、Terminate
2
1
1
3
MQTTプロダクト選定
プロダクト選定にあたっての⽐較ポイントl ⽐較の際によく取り上げらえるポイント
l 対応しているMQTTバージョンl サポートされているQoSレベルl SSL/TLS対応l Retain対応l Will対応l WebSocket対応l クラスタリング機能 etc
実際のところ(今回の場合)l よく違いがでるのはサポートするQoSレベルとクラスタリング可能か、それ以外はだいたいサポートされて
いることが多い(と思う)。
l Exactly Onceの保証はそもそも難しい。(メッセージング/ストリーム処理でいつも話題にあがるあれ)
l 前述したようにデータ種や処理に応じてメッセージ到達保証はどのみち妥協しなくちゃいけない。
l となると、QoSは0,1さえサポートされていれば⼗分で、クラスタリング可能かどうかは前述したとおり重要ではなかった。(リトライ/冪等/アプリで重複排除・・・)
選定候補l 実績、情報が多いものから優先的に選択(ただでさえ情報少ないのに・・・)l スクラッチも考えたが、ただでさえ情報が少ないなか冒険かと思い⼀旦除外
vs
負荷実施条件を記載l メッセージサイズ 1KBl クライアント数 1,000 l リクエスト数 10req/sec(1クライアントあたり)l Retainはなしl Gatling + MQTTプラグイン+ ECSでクライアント数を調整(すごい便利!!)
MQTT
MQTT
MQTT
MQTT
MQTT
実施結果
ブローカー インスタンスタイプQoS=0 QoS=1
CPU Ave 99th CPU Ave 99th
c4.large(2 vCPU) 70% 0msec 1msec 70% 100msec 639msec
c4.xlarge(4 vCPU) 20% 0msec 1msec 20% 4msec 4msec
c4.xlarge(2 vCPU) 100% 終わらず
打ち切り終わらず打ち切り 100%
終わらず打ち切り
終わらず打ち切り
c4.xlarge(4 vCPU) 100% 0msec 1msec 100% 999msec 4,753msec
それぞれの特徴(QoS=0の時)Mosquitto(c4.large) RabbitMQ(c4.large)
処理がはけきれず途中で打ち切り
RabbitMQのMQTTプラグインl MQTTプラグインは、RabbitMQのExchange/Queueの仕組みの上で動くl Exchangeでの配送⽅法はTopicl この機構が原因?調査しきれず。。。
いろいろプロダクトいじってみてのつらみl ノウハウ少ない。。(本当にこれでいいのか常に不安)
l チューニングポイントのあたりをつけるところから⼿探りでスタートl 詳細な事例も少ないので構成パターンの検討も⼿探りでスタート
l パラメータが少ない。。l いざパラメーターチューニングをはじめだすと設定できる箇所が少ないl ⼿持ちが少なすぎて性能が頭打ちになった時に毎回詰んだ気持ちになる
課題とまとめ
結構⼼配。。。l 暖気なしELBがどれぐらい安定してリクエスト受け切れるか。。。
l ELBが暖気なし状態でさばける具合の探りが必要 l IoTってアクセスピーク特性ってあるようなないような
ありがとうございました!!