Share
Embed
Transcript
67 slides
-
自己紹介 2 武田 大輝(たけだ ひろき) * 2012/04 新卒入社 * Technology
Inovation Group * サーバサイドエンジニア 4年 * インフラ(主にAWS)エンジニア 1年 Twitter はじめました @datake914 Qiitaも 書いてます @datake914 -
ヘルスケアIoTプラットフォーム? IoTデバイスデータを活用して、ヘルスケア領域のアクターを繋ぐ サービスを展開するための基盤 7 データ収集・分析・蓄積基盤 Y社 X社 Z社 介護 サービス
予防・安全 サービス 医療 サービス EC サービス ヘルパー 高齢者 介護事業者 家族 医療従事者 ケアマネージャ ECサービサー … … IoTデバイスデータを 活用したアプリ サービスを提供 本日の領域 IoTデバイスデータを 収集・分析・蓄積 -
ユーザ規模感 • ユーザ数100人程度の規模からスモールスタート • 将来的(5年後)には600万人まで拡大させたい 8 Recent Target (千人) …
ヘルスケアサービス従事者 … 高齢者・家族 0 2,000 4,000 6,000 8,000 2017 2018 2019 2020 2021 -
デバイス規模感(全くの未定) • ユーザ数、施設数に比例して増加 • 将来的には数100万台規模まで拡大させたい 9 (千台) … 施設センサー …
バイタルセンサー Recent Target 0 200 400 600 800 2017 2018 2019 2020 2021 -
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 -
サービス・プロダクトの選定にあたって AWSフルマネージドサービスを積極的に活用 • 予測不能なビジネスの成長規模 • 短期間でのスモールスタート • 限られた構築メンバ 14 Applications
Self Managed on AWS AWS Fully Managed Middle Ware OS Hard Ware Network AWS AWS Customer < -
サービス・プロダクトの選定にあたって AWSフルマネージド一辺倒ではない • AWSフルマネージドサービスのサービス制限 • I/Oに比例した利用料急増の可能性 • AWSに完全依存したくない 15 Applications
Self Managed on AWS Only AWS Fully Managed Middle Ware OS Hard Ware Network AWS AWS Customer -
まずはインプットの整理 17 モバイル アプリケーション アプリケーションの利用に基づく 行動ログ(誰が,いつ,どこで,何した)を連携 バイタルセンサー スマートベッドやスマートバンドなどから バイタルデータを連携 (要件未確定)
施設センサー 駐車場センサーやエアコンセンサーなどから 施設機器情報を連携 (要件未確定) Recent Target -
まずはインプットの整理 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 -
メッセージの複製, 分散, 再取得, 分散取得, 順序保証が求められる • AWSマネージドならAmazon Kinesis Streams •
OSSならApache Kafkaが無難 プロダクトの選択肢として… 20 Self Managed AWS Managed Amazon Kinesis Streams Amazon DynamoDB Stream Amazon SQS -
Kinesis vs Kafka - 基本機能 21 KinesisとKafkaの基本的な機能はほぼ同等 Enable Enable 順序保証
Enable Enable 複数配信 最大7日間 設定次第 データ保持期間 Enable Enable シャーディング 3AZ Enable レプリケーション 全レプリカ書込後 選択可能 Ack Amazon Kinesis Streams Yes No AWSマネージド 上限なし(~shards) 上限なし(~nodes) 拡張性 -
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) どちらも (当然)捌ける -
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は不可 -
運用・保守の負荷は (当前) 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 死活監視 最低限ケアすべきは スロットルエラーのみ 基本的には全て自前で 頑張る必要がある -
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 -
Kinesis vs Kafka - 結論 • Kinesisを採用 • スモールスタートという特性上、作りこみ不要かつ 初期のランニングコストが低いKinesisがマッチ
• 規模が拡大したときにKafkaへの移行も視野に入れる • Kafkaも決してハマらないわけではない 26 -
プロトコル別に受け口を用意し、連携元にKinesisを意識させない • HTTPの場合はWEB API経由 • MQTTの場合はMQTTブローカー経由 Amazon Kinesis Streams MQTT
Broker Subscriber Client キューイングシステムへの連携をどうするか 27 Amazon Kinesis Streams Client HTTP API {API} -
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 -
MQTT Brokerをどうするか • メッセージのロストは許容前提 • 膨大なデバイス数を想定し、柔軟にスケール (アウト) したい • SubscriberはKinesisにPUTするのみ
29 Broker Cluster Multi-Subscriber Kinesis … Publisher 同一トピックに 対する分散された Subscriber 分散された Broker Cluster こんなイメージ… -
MQTT Brokerをどうするか • メッセージのロストは許容前提 • 膨大なデバイス数を想定し、柔軟にスケール (アウト) したい • SubscriberはKinesisにPUTするのみ
30 Broker Cluster Multi-Subscriber Kinesis … Publisher 同一トピックに 対する分散された Subscriber 分散された Broker Cluster こんなイメージ… MQTTブローカーって そもそもこんな気軽にスケールしない -
MQTT Brokerをどうするか • AWS IoTはスケールを前提としたアーキテクチャ • QoS2非対応 • Retain非対応 •
OSSだとVerneMQ, EMQあたりがクラスタ組めてよさそう 31 Self Managed AWS Managed AWS IoT EMQ ルールエンジンで Kinesis連携までできるし 使えるんじゃね? -
AWS IoTの性能は如何に ルールエンジンは賢くKinesis連携してくれるのか? 32 AWS IoT デバイス ゲートウェイ ルール エンジン
特定トピックに メッセージがPUTされたときに Kinesisにメッセージ送信 デバイスゲートウェイは自動的にスケールと謳われているが Subscriber相当のルールエンジンもいい感じにスケールするのか? ボトルネックにならないか? -
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 -
AWS IoTよさそうだけど… 34 • 結構お高い ($8/million msg) • 1000msg/sでひと月運用するとPublishメッセージだけで$20736 •
カスタム価格というものがあるらしいが…? • ルールエンジンを利用するとKinesisへPUTするまでに データの集約ができない OSSも視野に入れて現在鋭意検証中 -
Collect層の構成 35 Amazon Kinesis Streams HTTP AWS IoT (仮) API
Server on EC2 HTTP MQTT MQTT HTTP Gateway MQTT Gateway -
Kinesisの手前にプロトコルに特化した受け口をそれぞれ用意 ポイント② - 多様なプロトコルに対応できること 37 Amazon Kinesis Streams API Server
on EC2 HTTP AWS IoT (仮) MQTT ??? 別のプロトコルに対応する場合は 受け口が横並びに増える -
とにもかくにもまずは生データの格納 • 要件追加にも柔軟に対応できるよう限りなく生のデータ保持は必須 • 生データは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秒に複数回ポーリング -
バッチ処理はS3 + EMR (Hadoop) S3からデータをHDFSにコピーし処理 • あくまでEMRは処理エンジン(データを永続化しない) • データ処理後にEMRクラスタをシャットダウンできる •
スポットインスタンスを活用できる 41 Amazon S3 AWS Lambda Amazon Kinesis Streams Amazon EMR S3DistCp -
リアルタイム処理は大きく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 -
Process&Analyze層の構成 43 Amazon Kinesis Streams AWS Lambda Amazon EMR AWS
Lambda Amazon EMR Amazon S3 バ ッ チ 処 理 リ ア ル タ イ ム 処 理 -
ポイント① - データの重複を前提とする Kinesis Streamsから連携されるデータは重複を前提として、 処理は冪等性を保証すべし 44 Amazon Kinesis Streams
Producer 何らかのエラー時に Producerがリトライを 行うことでメッセージが 重複する可能性がある Producer側で重複を排除 (exactry onceを実現) するのは高コスト AWS Lambda Amazon EMR Amazon EMR メッセージに一意なIDを持たせるなどして Consumer側で重複を排除できるように ID: 123456 ID: 123456 -
ポイント② - 単一障害は割り切り EMRはマスタノードが単一障害点となるが、再実行すればよし • リアルタイム層は、DynamoDBに保持しているKinesisの Checkpoint情報をもとに処理を再実行 • バッチ層は素直にS3からデータを再取得して処理を再実行 45
Amazon Kinesis Streams Amazon EMR Amazon Dynamo DB CheckPointから処理再開 Amazon EMR S3から再ロード -
Store層の構成 47 Amazon Kinesis Streams AWS Lambda Amazon EMR AWS
Lambda Amazon EMR Amazon S3 Amazon RDS Amazon DynamoDB Amazon ElastiCache -
ポイント - データストアは用途で使い分ける 48 Amazon S3 Amazon RDS Amazon DynamoDB
Amazon ElastiCache 全ての生データを保持。 アプリケーションからの参照はない。 ユーザ情報などのマスタデータや バッチ集計結果などを保持。 アプリケーションから参照・更新される。 ストリーム処理による分析結果や時系列データ など大量・高頻度連携されるデータを保持。 アプリケーションから参照のみされる。 RDSのマスタデータをキャッシュ。 ストリーム処理におけるデータの 問い合わせに対して高速に応答する。 主用途 TB~PB ~GB GB~TB MB データ サイズ コスト 低 高 アクセス 頻度 低 高 -
今のところアプリケーションのみ 独立した複数アプリケーションに対しWEB API経由でデータ提供 • コンシューマにKVS, RDSを意識させない • データストアとコンシューマを疎結合にする 50 Amazon
DynamoDB Amazon RDS アプリケーションA アプリケーションB … API Server on EC2 -
構成まとめ 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 -
ポイント (再掲) • データ収集層 • 連携頻度/データ種の増加に柔軟に対応できること • AWSマネージドサービスは便利な反面、サービス制限や課金体系を考 慮して見極めること •
データ処理層 • データの重複を前提として、冪等性を担保すること • 単一障害点は割り切り • データストア層 • 中心となるデータストア(生データ保持)はS3一択 • データの特性に応じて「どう使い分けるか」が重要 54 -
• データ入力時に指定するパーティションキーをもとに格納先の シャードを決定 • 全シャードに均等にレコードが分散されるようにパーティション キーは設定すべき Amazon Kinesis Streamsの分散方式 56
Stream 0~2128-1の範囲で ハッシュキーを保持 データ パーティションキー + レコードの内訳 Shard1 hashkey: 264 ~ 2128-1 Shard1 hashkey: 0 ~ 264-1 -
リシャーディング 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 -
リシャーディング - 実行方法 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 シャード数の指定 だけで均等にリシャーディング してくれる • 新方式(分割・結合) -
リシャーディング - 使い分け • 新方式は便利な反面、制約が存在 • 1日2回まで… • リシャード後のシャード数は1/2~2倍まで •
1日1,2回の定期運用でリシャーディングを行う場合は新方式 • 柔軟にオートスケールさせたい場合などは従来の方式 59 -
オートスケール CloudWatch + SNS + Lambdaで実現 AWS Lambda Cloud Watch
Alerm Amazon Kinesis Streams Amazon SNS ① Kinesisが発行するメトリクスを アラームの条件として設定 ② 閾値を超過した 場合にSNS通知 ③ SNS通知をトリガーに ラムダ関数を起動 ④ Lambda関数により リシャーディングを実行 & 閾値再設定 -
オートスケール - 閾値どうするか 例. ストリーム単位でシンプルに実施 利用するメトリクス: IncomingRecords • ストリーム全体において5分に渡り、1秒あたりレコード数が総許容 レコードの80%を超える場合に総シャード数を2倍にする
• ストリーム全体において30分に渡り、1秒あたりレコード数が総許容 レコードの20%を下回る場合に総シャード数を1/2倍にする -
オートスケール - 閾値どうするか 例. シャード単位で高度に実施 (※未検証) 利用するメトリクス: IncomingRecords (拡張シャードメトリクス) •
特定シャードにおいて5分に渡り、1秒あたりレコード数が総許容 レコードの80%を超える場合に該当シャードを分割する • 特定シャードにおいて30分に渡り、1秒あたりレコード数が総許容 レコードの20%を下回る場合に該当シャードを結合する 有料 結合対象のシャードを どうするかなど色々考慮する 必要がある…はず -
オートスケール - まとめ • リシャーディングに必要な時間、流量の変動周期等を考慮して 適切に閾値を設定すべし • 全シャードに均等にデータがPUTされるようパーティションキーを 設定することでシンプルなリシャーディングが可能に •
シャード数を増やす方はいいが、減らす方は慎重に • 特にシャード単位で高度にスケールする場合はテスト重要 • 分割は自動、結合は運用という割り切りもあり -
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リクエスト で連携 -
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 -
Kinesis Producer Library - 注意点 • 集約・収集のためにレコードを内部でバッファリングするため、設定した サイズ or 時間
or 数 (*1) に達するまで処理遅延が発生する可能性がある。 • 集約・収集のためにレコードを内部でバッファリングするため、 KPLが動作するEC2障害時などはメッセージがロストする可能性がある。 66 *1) RecordMaxBufferedTime, AggregationMaxCount, AggregationMaxSize, CollectionMaxCount, CollectionMaxSizeの設定値