[Azure][IoT][デザインパターン]IoTデバイスのStreamデータを簡単にリアルタイム処理するためのAzure各サービス概要


##TL;DR
Azureの各サービスを利用して、iOS・Androidアプリ、IoTデバイスから送信されるデータをリアルタイムに処理してRDB、HDFSに登録します。特定のサービスを利用すればここまでノンコーディングでイケます。あとはAppService（AzureのPaaS）やExcel（PowerBI）を利用してシステム連携も簡単にできます。
![イメージ](https://yoshiromasuhara.github.io/qiita/azure_grounddesign.png)

## Event Hubs
https://docs.microsoft.com/ja-jp/azure/event-hubs/event-hubs-what-is-event-hubs

唄い文句として毎秒数百万ものイベントを処理できるメッセージブローカーです。SDK(C、C#、Java)やAPIを利用してpublish・subscribeの処理を行います。通信プロトコルはAMQTまたはHTTPがサポートされております。（MQTTはない）
概要としてEventHubのpublishにはパーティションといった機能があり、2から32までの数を指定します。これは並列処理が多い場合に比例して数を増やします。（ただし性能があがるわけではない、決定後は変更できない）
subscribeではコンシューマーグループを介してデータにアクセスを行います。
Event Hubではメッセージの保持期間がありコンシューマーグループごとにメッセージの再取得・オフセット位置の指定が可能です。
![イメージ](https://docs.microsoft.com/ja-jp/azure/event-hubs/media/event-hubs-what-is-event-hubs/event_hubs_architecture.png)

メッセージのアクセスにはイベントハブの名前空間のSAS(Shared Access Signature)キーを利用して行います。
[利用料金](https://azure.microsoft.com/ja-jp/pricing/details/event-hubs/)はイベントの回数（¥2.86/100 万イベント）と接続時間（STANDARDで¥3.06/時間）で決定します。
例えばSTANDARDプランで1MB以内のイベントを100万回行い、送受信の時間が合わせて1秒で考えた場合、約850円ということになります。

## IoT Hub
https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-what-is-iot-hub

![イメージ](https://docs.microsoft.com/ja-jp/azure/iot-hub/media/iot-hub-what-is-iot-hub/hubarchitecture.png)
IoTに特化したメッセージブローカーで、JSONベースによる双方向通信が可能です。
RaspberryPiやArduinoも公式にサポートされており各種SDK（.NET,C,Python,java,Node.js）が揃ってます。
IoT機器単位でIDが割り振られAzure上で管理され、故障などを監視し特定のIDに対してメッセージ送信が可能です。
[利用料金](https://azure.microsoft.com/ja-jp/pricing/details/iot-hub/)は400,000件までの送受信で5,100円、6,000,000送受信で51,000円となり後述のEventHubsと比較すると割高です。
メッセージの最大サイズは256KBまでとなり、4KB毎に分割して送受信が発生します。
通信プロトコルはMQTT、AMQP、WebSockets、 HTTPの利用が可能で、SDKを利用することで簡単に利用可能です。（公式のサンプルはMQTT）

※参考
[Azure IoT Hub と Azure Event Hubs の比較](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-compare-event-hubs)


## Stream Analytics
https://docs.microsoft.com/ja-jp/azure/stream-analytics/stream-analytics-introduction

Azure上で扱っているデータに対してストリーミングでリアルタイム計算を簡単に設定できます。
>Azure ポータルでわずか数回クリックするだけで、ストリーミング データの入力ソース、ジョブの結果の出力シンク、SQL に似た言語で表現したデータ変換を指定して、Stream Analytics ジョブを作成できます。 

使い方の概略として、Azureのポータル画面にて入力・出力に紐付けるAzureのサービスを設定します。そしてクエリにてT-SQL形式で入力データのフィルタ／集計を行って出力先にデータを渡します。
例えば入力に"eventhubs1"といったEvent Hubsから"datalake1"に登録するクエリは以下のようになります。

```SQL
SELECT
    *
INTO
    [datalake1]
FROM
    [eventhubs1]
```

ここに集計関数、グルーピングも利用可能で、Storageに参照データとしてマスタデータを用意することでストリームデータと紐付けて登録することもできます。
グルーピングの一つの特徴として集計方法に以下の[３種類](https://msdn.microsoft.com/library/en-us/Dn835055.aspx)が用意されてます。

+ Tumbling Window : 特定の時間単位で連続したデータを処理対象とする
+ Hopping Window : 特定の時間単位で過去のデータも含めて処理対象とする
+ Sliding Windo : イベントの受信タイミングから過去n分間のデータを処理対象とする

※Tumbling Windowのイメージ
![イメージ](https://i-msdn.sec.s-msft.com/dynimg/IC759295.jpeg)

※Hopping Windowのイメージ
![イメージ](https://i-msdn.sec.s-msft.com/dynimg/IC759294.jpeg)

また関数を利用することで簡単なビジネスロジックを作成することも可能です。
Stream Analyticsの入力・出力に指定できるAzureサービスは以下となります。

#### 入力
+ Event Hubs
+ IoT Hub
+ Storage

#### 出力

+ Event Hubs
+ SQL Database
+ Storage（Blob・テーブル）
+ Sevice Bus（キュー・トピック）
+ DocumentDB
+ PowerBI
+ Data Lake

[利用料金](https://azure.microsoft.com/ja-jp/pricing/details/stream-analytics/)は稼働時間に対して発生します。標準ストリーミング ユニット（¥14.08/時間）を24時間30日間稼働した場合は約10,137円となります。


## Azure Functions
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-overview

Azureにおける最近流行りのサーバーレス（常駐プロセスを持たずにサーバーロジックが利用できる）となるFaaSです。
様々なイベントドリブンで起動可能で、Cronジョブ構文を使用したタイマーに基づくイベント、データ更新、Azureの各サービスイベント、Webhookなど一般的なFaaSサービスと遜色なく利用できます。

作成時はportal.azure.comから新規で「Function App」といったサービスで作成します。（少し迷った）
AzureにはAppServiceプランといった概念（APサーバー物理リソース）があり後述で紹介するAppService（PaaS）はAppServiceプラン上に配置されます。Azure Functionでは料金体系の考え方から従量課金（共有AppServiceプラン）または自前のAppServiceプランの2種類から選択できます。
利用可能な言語としてはC#,Javascriptとなりますが利用シーンごとのテンプレートを利用することで他言語も利用可能となります。

Azure Function内には複数のfunctionを作成することが可能で各々イベントドリブンで起動が可能となります。functionはトリガー・入力・出力の3種類の設定が必要となり、例えばEvent Hubsのデータにビジネスロジックを適用してSQL Databaseに登録する場合はトリガーに「Azure イベント ハブ」を指定し出力に「外部テーブル」からDBの接続情報を登録します。各指定可能なイベントは以下となります。

#### トリガー
+ タイマー
+ Azure イベント ハブ
+ Azure Queue Storage
+ Azure BLOB ストレージ
+ 外部ファイル
+ HTTP
+ Azure Service Bus
+ マニュアル

#### 入力
+ Azure BLOB ストレージ
+ 外部ファイル
+ 外部テーブル
+ Azure Table Storage
+ Azure DocumentDB ドキュメント
+ Azure Mobile テーブル レコード
+ ボットのフレームワーク

#### 出力

+ Azure イベント ハブ
+ Azure Queue Storage
+ Azure BLOB ストレージ
+ 外部ファイル
+ 外部テーブル
+ HTTP
+ Azure Service Bus
+ Azure Table Storage
+ Azure DocumentDB ドキュメント
+ Azure Mobile テーブル レコード

#### 出力の外部テーブルに指定可能なサービス

+ DB2
+ Dynamics 365 for Operations
+ Dynamics 365
+ Dynamics NAV
+ Google スプレッドシート
+ Informix
+ Dynamics 365 for Financials
+ MySQL
+ Oracle Database
+ Common Data Service
+ Salesforce
+ SharePoint
+ SQL Server
+ Teradata
+ UserVoice
+ Zendesk

[利用料金](https://azure.microsoft.com/ja-jp/pricing/details/functions/)について前述でも触れましたが自前のAppServiceプランではAppServiceの利用料金に準拠します。従量課金の場合は月々のメモリを使用した実行時間（¥0.001632/GB 秒）、回数（100 万実行回数あたり ¥20.40）で発生します。
※無料枠として実行時間（400,000 GB 秒）、回数（100 万実行回数）が用意されている


## Data Lake Store
https://docs.microsoft.com/ja-jp/azure/data-lake-store/data-lake-store-overview

AzureにおけるHDFSとなる大容量ストレージです。
公式から抜粋として

> 人為的な制限を受けずにデータすべてを 1 か所で分析できます。Data Lake Store では数十億個のファイルを保存できます。1 つあたりのサイズが 1 ペタバイトを超えるファイルも保存可能であり、これは他のクラウド ストアの 200 倍です。

とか

>数百 TB のデータを効率的に読み込みおよび書き込みする同時実行子を数千個使用して分析ジョブを実行可能です。

とか

>Hadoop (HDInsight クラスターで使用可能) から、WebHDFS 互換の REST API を使用してアクセスできます。

AzureのBlobストレージとの違いは以下です。
[Azure Data Lake Store と Azure BLOB ストレージの比較](https://docs.microsoft.com/ja-jp/azure/data-lake-store/data-lake-store-comparison-with-blob-storage)


現時点はプレビューといった扱いとなっており利用には申請が必要です。

前述のStreamAnalyticsからシームレスな登録が可能で、StreamAnalytics側の設定でファイルの出力箇所・形式（CSV/JSON）を指定することができます。
※例えば「logs/{date}/{time}」、timeの形式をHHと指定することで以下のようなディレクトリ構造で保存されます。
logs
 　|- 2017-04-01
 　|　　　　|-10_XXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXX00001.csv
 　|　　　　|-11_XXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXX00001.csv
 　|　　　　|-12_XXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXX00001.csv
 　|- 2017-04-02
 　|　　　　|-10_XXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXX00001.csv
 　|　　　　|-11_XXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXX00001.csv
 
Azureのポータル画面には「データ エクスプローラー」が用意されており各ファイルをUIから確認することも可能です。

[利用料金](https://azure.microsoft.com/ja-jp/pricing/details/data-lake-store/)について、ストレージは従量課金とパック料金の２種類用意されていて、重量課金は最初の100TBまで¥3.98/GB、次の100TB～1,000TBは¥3.88/GB、次の1,000TB～5,000TBは¥3.78/GB、以降は問い合わせとなります。
パックの方は契約容量毎に1TB：¥3,570(-12%)、10TB：¥32,640(-19%)、100TB：¥295,800(-27%)、500TB：¥1,356,600(-31%)、1,000TB：¥2,652,000(-33%)となります。（カッコ内は割引率）

## Data Lake Analytics
https://docs.microsoft.com/ja-jp/azure/data-lake-analytics/data-lake-analytics-overview

予め用意しているData Lake Storeに対してジョブを発行し分析を行うサービスです。
U-SQLを利用して入力先／出力先／データ集計が可能です。

※抽出するU-SQLの例

```

@searchlog =
     EXTRACT col1  string,
             col2  string,
             col3  long,
             filename string
     FROM "/logs/{*}/{filename:*}.csv"
     USING Extractors.Csv(skipFirstNRows:1);

@summarydata = 
    SELECT 
        col1,
        SUM(col3) AS col3sum
    FROM 
        @searchlog 
    GROUP BY 
        col1;

 OUTPUT @summarydata   
     TO "/Output/summarydata.csv"
 USING Outputters.Csv();

```

Extractors.Csvのパラメータについて、skipFirstNRowsは1行目のCSVヘッダを除外しています。抽出時は全項目を指定する必要がありますがsilentを利用することで特定項目のみ可能となります。
その他のパラメータは[こちら](https://msdn.microsoft.com/en-us/library/azure/mt492749.aspx)を参照してください。
また読み込みファイルに1つでも不備があるとエラーが発生します。
（StreamAnalyticsから直接転送していたファイルでエラーが発生し、同じファイルを手動でアップロードしたら動いた事もあります。。何か設定漏れかもしれないですが）

[利用料金](https://azure.microsoft.com/ja-jp/pricing/details/data-lake-analytics/)は時間毎の従量課金（¥204/分析時間）とパック料金の２種類用意されていて、¥10,200/100時間、¥45,900/500時間、¥81,600/1,000時間、¥367,200/5,000時間、¥663,000/10,000時間、¥2,958,000/50,000時間、¥5,304,000/100,000時間となっています。
また分析時に指定する「AU」といった項目があり1回のジョブ性能を1〜250の範囲で選択できます。1で0.03 USD/分となり250で8.33 USD/分となっています。


## App Service / SQL Database / Storage

多くの記事が溢れているので詳細は割愛しますが、ざっくり言うと以下です。

+ App Service : PaaS
+ SQL Database  : RDBMS
+ Storage : Fileストレージ（ホスティング可）

App Serviceについては以前投稿しているので参考にしていただけたらと思います。
[[Azure][PaaS][AppService]Webアプリ作成時の環境構築（ステージング環境準備、ベーシック認証、Gitからデプロイ）](http://qiita.com/freestylead/items/3a51bb551ad303f98f71)

## おわりに
EventHubs→StreamAnalytics→SQLDatabaseの構成は少しのT-SQLを記述するだけで簡単にStreamデータを扱うことが実現できました。PowerBIを利用すれば簡単にデータ可視化も実現できるので近いうちに深掘りしていこうかと :yum: