Azure Data Lake Analytics(U-SQL) とその他類似環境を比較する

@Saint1991さんの [BigQuery vs Athena vs RedShift vs Hive](https://qiita.com/Saint1991/items/8c19fd9cbaccf2284083) に乗っかって、Azure Data Lake Analyticsと他の環境を比較してみました。

ただ、データが@Saint1991さんのものとは全く異なるので、詳細な比較はできませんが、桁単位程度ではあっているのではないかと推察します。

## 比較対象

* ADLA (Azure)
* BigQuery (GCP)
* Athena (AWS)
* RedShift (AWS)
* Hive (オンプレOpenStack)

## ストレージ料金

Azure Data Lake Storeについて、トランザクション料金が別になっていますが。

|項目    |       Storage料金 | 転送料金|
|:-----------------|-------------------|--------------------|
| ADLS  | $0.039/GB  |      $0.087/GB  |
| S3  | $0.025 / GB |      $0.14 / GB       |
| GCS | $0.023 / GB |    $0.14 / GB   |

## トランザクション料金

以下のように観点が異なるので、直接は比較しずらいところです。

* ADLA $2/時間 (AU単位) ->  $ 0.033/分AU 0.00055/秒AU
* Athena， BigQuery: $5 / TB (スキャン量)
* RedShift: dc2.large 1台辺り $0.314 / hour -> $ 0.0052/分 , $0.000087/秒


## データフォーマット
ADLSにHDInsightからアクセスできたり、ADLAからAzure SQLなどへのアクセスがありますが、ADLAが直接アクセスできるファイルはCSV/TSVがメインになるようです。サードパーティーが提供するアセンブリを追加すると、OutputterやExtractorを拡張できるので一応できなくは無いという程度です。

* [elastacloud/parquet-usql ](https://github.com/elastacloud/parquet-usql)
* [Querying Multi-Structured JSON Files with U-SQL in Azure Data Lake ](https://www.sqlchick.com/entries/2017/9/4/querying-multi-structured-json-files-with-u-sql-in-azure-data-lake)
* [sindhudweep/Orcneas ](https://github.com/sindhudweep/Orcneas)
* [U-SQL Avro Example](https://github.com/Azure/usql/tree/master/Examples/AvroExamples)

|項目    |  CSV |TSV|JSON|Parquet|ORC|Arvo|
|:-----------------|-----------|---------|-----|-----|-----|-----|
| ADLA  | In/Out |     In/Out  |(In)|(In/Out)|(In)|(In)|
| BigQuery  |  In/Out |    - |In/Out|-|-|In/Out|
| Athena |  In/Out |     In/Out  |In|-|-|In|
| RedShift |  In/Out |     In/Out  |In|-|-|In|
| Hive |  In/Out |     In/Out  |In|In/Out|-|In/Out|

## Schemaの検出

U-SQLでは、Extractorに型を記述する必要がありますが、スキーマ定義が必要ではありません。

|項目    |  Schema検出 |
|:----|-----|
| ADLA  | Ok |     
| BigQuery  | Ok |   
| Athena | - |    
| RedShift | - |     
| Hive |  - |    

## パフォーマンス

手元にあった34GBのデータを使いましたので、少々条件が違います。カラム数や条件に合う行数も異なるので、まったく違うかもしれませんが、ざっくりと比較するにはよいかと思います。

### クエリー１

```U-SQL
@count = SELECT COUNT( * ) AS count
    FROM @input
    WHERE column1.Length != 0;

OUTPUT @count
    TO @outputFile
    USING Outputters.Csv(outputHeader:true);
```
リードは20.11 GBとなりました。

### クエリー2

```U-SQL
@randsamp = SELECT * 
    FROM @input
    WHERE (column1.Length == 0) AND (new Random().Next() < 17000000 / 352824342);

@nonnull = SELECT * 
    FROM @input
    WHERE (column1.Length != 0);

@out =
    SELECT *
    FROM @randsamp
    UNION ALL
    SELECT *
    FROM @nonnull;
```
リードは45.40 GBとなりました。
 

### 結果
結果は以下のようになります。このサイズだと並列化をこれ以上やってもスピードは上がらないので、やはり他のエンジンほどは速くならないようです。

コストは時間とスキャンサイズでそれぞれ試算しましたが、コスト面で見た場合はそれほどドラスティックには違わないので、恐る恐る使う感覚にはならないように思います。

|項目    | クエリー1 | クエリー2 |クエリー1 コスト | クエリー2 コスト|
|:----|-----:|-----:|-----:|-----:|
| ADLA 5AU  | 192 sec |  720 sec | $ 0.528 | 　$ 1.98 |
| ADLA 20AU  | 72 sec | 228 sec  | $ 0.792 | 　$ 2.50 |
| BigQuery  | 2 sec | 26 sec|$ 0.000012 | 　$ 0.265 |
| Athena | 7 sec | 115 sec | $ 0.21 | 　$ 0.42 |  
| RedShift(large 1台) | 7 sec| 355 sec|　$ 0.0006 | 　$ 0.03 |

# 結論

クエリーのインタラクティブ性を求めるならBigQueryやAthena、ある一定量のクエリーが見込めて、固定的に何度も使いたいならRedShift、凝った前処理や、データ変換を気軽にやりたいならADLAという感じでしょうか？Hadoop環境まではいらないが、SQLクエリーだけだと対応できない処理が多い場合は、ADLAも悪くないという感じに思っていればよさそう。