Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

AWSマネージドサービスをフル活用したヘルスケアIoTプラットフォーム基盤

 AWSマネージドサービスをフル活用したヘルスケアIoTプラットフォーム基盤

Hiroki Takeda

March 02, 2017
Tweet

More Decks by Hiroki Takeda

Other Decks in Technology

Transcript

  1. 自己紹介 2 武田 大輝(たけだ ひろき) * 2012/04 新卒入社 * Technology

    Inovation Group * サーバサイドエンジニア 4年 * インフラ(主にAWS)エンジニア 1年 Twitter はじめました @datake914 Qiitaも 書いてます @datake914
  2. ヘルスケアIoTプラットフォーム? IoTデバイスデータを活用して、ヘルスケア領域のアクターを繋ぐ サービスを展開するための基盤 7 データ収集・分析・蓄積基盤 Y社 X社 Z社 介護 サービス

    予防・安全 サービス 医療 サービス EC サービス ヘルパー 高齢者 介護事業者 家族 医療従事者 ケアマネージャ ECサービサー … … IoTデバイスデータを 活用したアプリ サービスを提供 本日の領域 IoTデバイスデータを 収集・分析・蓄積
  3. 11

  4. Big Data Pipeline 13 Collect STORE PROCESS ANALYZE CONSUME Amazon

    S3 Amazon DynamoDB Amazon RDS AWS IoT Amazon SQS Amazon Machine Learning Amazon EMR AWS Lambda Amazon Redshift Amazon Kinesis Analytics Amazon QuickSight Amazon Glacier AWS Data Pipeline Amazon Kinesis Streams Amazon Kinesis Firehose AWS API Gateway AWS Import/Export Snowball Amazon ElastiCache
  5. まずはインプットの整理 18 モバイル アプリケーション プロトコル :HTTP 同時アクセス :初年度140msg/s -> 5年後3000msg/s

    メッセージ保証 :At least once バイタルセンサー プロトコル :MQTT or HTTP 同時アクセス :初年度550msg/s -> 5年後12000msg/s メッセージ保証 :At most once 施設センサー プロトコル :MQTT or HTTP 同時アクセス :初年度70msg/s -> 5年後1000msg/s メッセージ保証 :At most once Recent Target
  6. メッセージの複製, 分散, 再取得, 分散取得, 順序保証が求められる • AWSマネージドならAmazon Kinesis Streams •

    OSSならApache Kafkaが無難 プロダクトの選択肢として… 20 Self Managed AWS Managed Amazon Kinesis Streams Amazon DynamoDB Stream Amazon SQS
  7. Kinesis vs Kafka - 基本機能 21 KinesisとKafkaの基本的な機能はほぼ同等 Enable Enable 順序保証

    Enable Enable 複数配信 最大7日間 設定次第 データ保持期間 Enable Enable シャーディング 3AZ Enable レプリケーション 全レプリカ書込後 選択可能 Ack Amazon Kinesis Streams Yes No AWSマネージド 上限なし(~shards) 上限なし(~nodes) 拡張性
  8. Kinesis vs Kafka - スループット リニアにスケールするためスループットはお金次第 • コストパフォーマンスの良し悪しは一概には言えない(後述) • もろもろ小回りが利くのはKafka

    Case1 : 1KB/msg × 10000msg/sec = 10MB/secをPUT 22 1stream, 10shard 3node(m4large × 3) 1topic, 3partition, 3replica, acks=all $ bin/kafka-producer-perf-test.sh --topic test --num-records 10000000 ¥ --record-size 1024 --throughput 10000 --producer-props bootstrap.servers=<host>:9092 acks=all 10000000 records sent, 9996.893606 records/sec (9.74 MB/sec) どちらも (当然)捌ける
  9. Kinesis vs Kafka - スループット Case2: 0.1KB/msg × 100,000msg/sec =

    10MB/secをPUT Case3: 2MB/msg × 5msg/sec = 10MB/secをPUT 23 1000msg/shardの上限があるため、 1stream, 100shard必要 ※KPLで集約を行うことでより少ないshardで対応可(後述) 1MB/shardの上限があるため、 1MBを超えるメッセージのPUTは不可
  10. 運用・保守の負荷は (当前) Kinesisの方が低い Kinesis vs Kafka - 運用・保守 24 N/A

    by yourself リソース監視 CloudWatch連携 by yourself 性能監視 UpdteShardCount API1発 by yourself スケーリング N/A by yourself チューニング N/A by yourself バージョンアップ N/A zookeeper フェイルオーバー Amazon Kinesis Streams N/A by yourself 死活監視 最低限ケアすべきは スロットルエラーのみ 基本的には全て自前で 頑張る必要がある
  11. Kinesis vs Kafka - コスト 条件次第で変わるので参考程度に… • 1KB/msg, 1consumer/msg •

    1日あたりデータトラフィックはmsg/secの12時間分 • データ保持期間は24時間 • KafkaはKinesisと同等の可用性(3node, 3replica)を担保 25 $0.00 $250.00 $500.00 $750.00 $1,000.00 … put payload … shard … data transfer … EBS volume … EC2 computing (m4.large) (msg/sec) 2,000 1,000 5,000 10,000 20,000
  12. Kinesis vs Kafka - 結論 • Kinesisを採用 • スモールスタートという特性上、作りこみ不要かつ 初期のランニングコストが低いKinesisがマッチ

    • 規模が拡大したときにKafkaへの移行も視野に入れる • Kafkaも決してハマらないわけではない 26
  13. プロトコル別に受け口を用意し、連携元にKinesisを意識させない • HTTPの場合はWEB API経由 • MQTTの場合はMQTTブローカー経由 Amazon Kinesis Streams MQTT

    Broker Subscriber Client キューイングシステムへの連携をどうするか 27 Amazon Kinesis Streams Client HTTP API {API}
  14. HTTP APIサーバをどうするか EC2インスタンス上に自前のAPIサーバを構築 • API Gatewayのサービス制限が懸念される • エンドポイントは極力AWS依存度を低くしたい • Kinesis

    Producer Libraryを利用したい (後述) 28 Yes No AWSマネージド HTTPS HTTP/HTTPS プロトコル AWS IAM認証, APIキー認証, カスタム認証(Lambda) 実装次第 認証 1000rps 設定次第 スループット 60 上限なし エンドポイント数 10MB 設定次第 ペイロード上限 Amazon API Gateway API Server on Amazon EC2
  15. MQTT Brokerをどうするか • メッセージのロストは許容前提 • 膨大なデバイス数を想定し、柔軟にスケール (アウト) したい • SubscriberはKinesisにPUTするのみ

    29 Broker Cluster Multi-Subscriber Kinesis … Publisher 同一トピックに 対する分散された Subscriber 分散された Broker Cluster こんなイメージ…
  16. MQTT Brokerをどうするか • メッセージのロストは許容前提 • 膨大なデバイス数を想定し、柔軟にスケール (アウト) したい • SubscriberはKinesisにPUTするのみ

    30 Broker Cluster Multi-Subscriber Kinesis … Publisher 同一トピックに 対する分散された Subscriber 分散された Broker Cluster こんなイメージ… MQTTブローカーって そもそもこんな気軽にスケールしない
  17. MQTT Brokerをどうするか • AWS IoTはスケールを前提としたアーキテクチャ • QoS2非対応 • Retain非対応 •

    OSSだとVerneMQ, EMQあたりがクラスタ組めてよさそう 31 Self Managed AWS Managed AWS IoT EMQ ルールエンジンで Kinesis連携までできるし 使えるんじゃね?
  18. AWS IoTの性能は如何に ルールエンジンは賢くKinesis連携してくれるのか? 32 AWS IoT デバイス ゲートウェイ ルール エンジン

    特定トピックに メッセージがPUTされたときに Kinesisにメッセージ送信 デバイスゲートウェイは自動的にスケールと謳われているが Subscriber相当のルールエンジンもいい感じにスケールするのか? ボトルネックにならないか?
  19. AWS IoTの性能は如何に ルールエンジンの処理時間を測定 33 AWS IoT デバイス ゲートウェイ ルール エンジン

    メッセージが Publishされた時刻 Kinesisへ Putされた時刻 0 200 400 600 1000 5000 … 50.0 percentile … 平均 … 99.9 percentile 59msec 60msec 50msec 48msec 454msec 194msec 5000msg/s 1000msg/s (msec) (msg/s) ※クライアント数は500
  20. AWS IoTよさそうだけど… 34 • 結構お高い ($8/million msg) • 1000msg/sでひと月運用するとPublishメッセージだけで$20736 •

    カスタム価格というものがあるらしいが…? • ルールエンジンを利用するとKinesisへPUTするまでに データの集約ができない OSSも視野に入れて現在鋭意検証中
  21. Collect層の構成 35 Amazon Kinesis Streams HTTP AWS IoT (仮) API

    Server on EC2 HTTP MQTT MQTT HTTP Gateway MQTT Gateway
  22. とにもかくにもまずは生データの格納 • 要件追加にも柔軟に対応できるよう限りなく生のデータ保持は必須 • 生データはAWS Lambdaを利用してAmazon S3に集約 • 容量制限なし •

    高可用性 (99.99%) • 高耐久性 (99.999999999%) • 低コスト 40 Amazon S3 AWS Lambda Amazon Kinesis Streams S3が本基盤における データレイクとなる Kinesis Firehose は利用しない (*1) *1) 現時点では東京リージョンで利用できない、S3に格納するまでに加工処理ができない等の理由による。 指定件数でBatch取得 圧縮してPUT 1秒に複数回ポーリング
  23. リアルタイム処理は大きく2パターン • 単一レコードに対する簡易な処理はAWS Lambda • 複数レコードに対する高度な処理 (ウィンドウ集計など) はSpark Streaming 42

    AWS Lambda Amazon Kinesis Streams Amazon EMR 指定件数でBatch取得 1秒に複数回ポーリング Kinesis Client Libraryをラップした Spark Streaming用のライブラリ (*1) により、指定間隔でポーリング *1) http://spark.apache.org/docs/latest/streaming-kinesis-integration.html
  24. Process&Analyze層の構成 43 Amazon Kinesis Streams AWS Lambda Amazon EMR AWS

    Lambda Amazon EMR Amazon S3 バ ッ チ 処 理 リ ア ル タ イ ム 処 理
  25. ポイント① - データの重複を前提とする Kinesis Streamsから連携されるデータは重複を前提として、 処理は冪等性を保証すべし 44 Amazon Kinesis Streams

    Producer 何らかのエラー時に Producerがリトライを 行うことでメッセージが 重複する可能性がある Producer側で重複を排除 (exactry onceを実現) するのは高コスト AWS Lambda Amazon EMR Amazon EMR メッセージに一意なIDを持たせるなどして Consumer側で重複を排除できるように ID: 123456 ID: 123456
  26. Store層の構成 47 Amazon Kinesis Streams AWS Lambda Amazon EMR AWS

    Lambda Amazon EMR Amazon S3 Amazon RDS Amazon DynamoDB Amazon ElastiCache
  27. ポイント - データストアは用途で使い分ける 48 Amazon S3 Amazon RDS Amazon DynamoDB

    Amazon ElastiCache 全ての生データを保持。 アプリケーションからの参照はない。 ユーザ情報などのマスタデータや バッチ集計結果などを保持。 アプリケーションから参照・更新される。 ストリーム処理による分析結果や時系列データ など大量・高頻度連携されるデータを保持。 アプリケーションから参照のみされる。 RDSのマスタデータをキャッシュ。 ストリーム処理におけるデータの 問い合わせに対して高速に応答する。 主用途 TB~PB ~GB GB~TB MB データ サイズ コスト 低 高 アクセス 頻度 低 高
  28. 構成まとめ 53 Amazon S3 Amazon ElastiCache Amazon DynamoDB Amazon RDS

    AWS Lambda AWS Lambda Amazon EMR Amazon EMR Amazon Kinesis Streams AWS IoT API Server on EC2 API Server on EC2 Collect PROCESS ANALYZE STORE CONSUME
  29. ポイント (再掲) • データ収集層 • 連携頻度/データ種の増加に柔軟に対応できること • AWSマネージドサービスは便利な反面、サービス制限や課金体系を考 慮して見極めること •

    データ処理層 • データの重複を前提として、冪等性を担保すること • 単一障害点は割り切り • データストア層 • 中心となるデータストア(生データ保持)はS3一択 • データの特性に応じて「どう使い分けるか」が重要 54
  30. • データ入力時に指定するパーティションキーをもとに格納先の シャードを決定 • 全シャードに均等にレコードが分散されるようにパーティション キーは設定すべき Amazon Kinesis Streamsの分散方式 56

    Stream 0~2128-1の範囲で ハッシュキーを保持 データ パーティションキー + レコードの内訳 Shard1 hashkey: 264 ~ 2128-1 Shard1 hashkey: 0 ~ 264-1
  31. リシャーディング Shardを分割・結合することでスループットを調整 57 Split Stream 1Shard PUT: 1000msg/s 1MB/s Stream

    2Shard PUT: 2000msg/s 2MB/s Stream 1Shard PUT: 1000msg/s 1MB/s Marge hashkey: 0 ~ 2128-1 hashkey: 0 ~ 264-1 hashkey: 264 ~ 2128-1 hashkey: 0 ~ 2128-1
  32. リシャーディング - 実行方法 APIで実行 (※管理コンソール上からもできます) 58 $ aws kinesis split-shard

    --stream-name <stream-name> ¥ --shard-to-split <shard-id> --new-starting-hash-key <hashkey> シャードID及び 分割位置となるハッシュキーを 指定する必要がある • 従来の方式(分割) $ aws kinesis merge-shards --stream-name <stream-name> ¥ --shard-to-merge <shard-id> --adjacent-shard-to-merge <shard-id> 結合対象のシャードIDを 指定する必要がある(*1) • 従来の方式(結合) $ aws kinesis update-shard-count --stream-name <stream-name> ¥ --target-shard-count <shard-count> --scaling-type UNIFORM_SCALING シャード数の指定 だけで均等にリシャーディング してくれる • 新方式(分割・結合)
  33. リシャーディング - 使い分け • 新方式は便利な反面、制約が存在 • 1日2回まで… • リシャード後のシャード数は1/2~2倍まで •

    1日1,2回の定期運用でリシャーディングを行う場合は新方式 • 柔軟にオートスケールさせたい場合などは従来の方式 59
  34. オートスケール CloudWatch + SNS + Lambdaで実現 AWS Lambda Cloud Watch

    Alerm Amazon Kinesis Streams Amazon SNS ① Kinesisが発行するメトリクスを アラームの条件として設定 ② 閾値を超過した 場合にSNS通知 ③ SNS通知をトリガーに ラムダ関数を起動 ④ Lambda関数により リシャーディングを実行 & 閾値再設定
  35. オートスケール - 閾値どうするか 例. シャード単位で高度に実施 (※未検証) 利用するメトリクス: IncomingRecords (拡張シャードメトリクス) •

    特定シャードにおいて5分に渡り、1秒あたりレコード数が総許容 レコードの80%を超える場合に該当シャードを分割する • 特定シャードにおいて30分に渡り、1秒あたりレコード数が総許容 レコードの20%を下回る場合に該当シャードを結合する 有料 結合対象のシャードを どうするかなど色々考慮する 必要がある…はず
  36. オートスケール - まとめ • リシャーディングに必要な時間、流量の変動周期等を考慮して 適切に閾値を設定すべし • 全シャードに均等にデータがPUTされるようパーティションキーを 設定することでシンプルなリシャーディングが可能に •

    シャード数を増やす方はいいが、減らす方は慎重に • 特にシャード単位で高度にスケールする場合はテスト重要 • 分割は自動、結合は運用という割り切りもあり
  37. Kinesis Producer Library • Kinesis StreamsのレコードPUTに特化した高度なライブラリ • KPLはC++製、Java wrapperを通じて利用 •

    Linux, OS X, Windowsサポート (*1) • 非同期的にレコードの集約・収集を行ってくれる 64 *1) 最新バージョンv0.12.3では未サポート recordB recordA recordC recordD recordC recordB recordD recordA KPL recordB recordA recordC recordD Kinesis Streams 複数レコードを Kinesisの1レコードに まとめる(集約) 複数レコードを まとめてKinesisに PUTする(収集) 2レコード 1リクエスト で連携
  38. Kinesis Producer Library - メリット 小さなレコードが大量連携される場合にコスト削減が可能 例. 0.25KB/msg × 10000msg/s

    = 2.44MB/secを捌く場合 • 通常 : 10shard, 10,000payload unit/s • KPL利用 : 03shard, 100payload unit/s(25KBに集約) 65 約$650/月削減!!! 0 250 500 750 通常 KPL (ドル) レコードサイズが 小さければ小さいほど、 連携頻度が高ければ高いほど 効果あり … put payload … shard
  39. Kinesis Producer Library - 注意点 • 集約・収集のためにレコードを内部でバッファリングするため、設定した サイズ or 時間

    or 数 (*1) に達するまで処理遅延が発生する可能性がある。 • 集約・収集のためにレコードを内部でバッファリングするため、 KPLが動作するEC2障害時などはメッセージがロストする可能性がある。 66 *1) RecordMaxBufferedTime, AggregationMaxCount, AggregationMaxSize, CollectionMaxCount, CollectionMaxSizeの設定値