Azure HDInsight(Hadoop) on Linuxを試してみる


Microsoft AzureのHadoopサービスであるHDInsight。Windowsベースなのが難だなと思ってきましたが、Linux(Ubuntu)ベースのものが追加されたので使ってみたメモ。

慣れの問題もあるでしょうがEMRよりはお手軽な感じはします。Impalaとか対話系SQL系が無いのが残念！ではありますが、EMRも含め、時代はSparkに向かっているのかなというのを感じます。

##注意！（最初にお読み下さい）

* Linux版のHDInsightは、新デザインのポータル(preview)じゃないとコントロールできないのですが、日本語表示だと、いろいろな機能がうまく動かないので注意が必要です。特に「クラスタの削除」、「クラスタのスケール変更」が出来ないのはしんどいです。

* またMacのAzure CLIツールの現行バージョンでは、Linuxを対象としたクラスタが管理できないようです（そもそも見えません）。

##やること

試してみるの以下の機能。

* sshで普通にログインしてhadoopコマンドが利用できるかの確認。
* HDFSもされることながら、Strageサービス(BLOB)を操作してみる。
* hiveコマンドを利用してみる。
* Hive REST APIを利用してみる。
* ExelからHiveを利用してみる。

この辺の機能が一通り使えれば使い物になるかと。

##環境

私はMacを使っているので全ての操作をMac上のChromeで行ないます（キャプチャはSafariも使ってますが）。

* クライアント（Mac El Capitan) + 最新版chrome。
* Microsoft Azure(2015/11/28時点) プレビュー版である新管理画面使います。

##準備

###Azureのアカウント取得

* [Azureのアカウント取得](https://azure.microsoft.com/ja-jp/pricing/free-trial/)（無料枠あります）


##HDInsightクラスタの作成

Azureのポータルにログインします。
2015年11月28日時点では、古いポータルデザインが表示されていますが、HDINSIGHTを選択すると、「一部の HDInsight クラスターはここに表示されない場合があります。すべてのクラスターを管理するには、今すぐ新しい Azure ポータルに切り替えてください。」と表示されるので、新しいポータルに移動します。

###HDInsightを選ぶ

Azure Portalにログインした後、+ Newを選択し、MARKETPLACEメニューの中からData + Analyticsを選択すると、一番上にHDInsightがあるはずなので、それを選択します。

>余談ですが、ClouderaとかHortonworksのイメージもあるようです（お試し的なもののようです）。

![hdinsight](http://www.bluecode.jp/qiita/hdil001.png)

###クラスタ基本情報の設定

ほとんどの項目が必須などで1つ１つ入力していきます。

####クラスタ名

基本、何でもいいです。ここではlinuxHDしてみました。
なお、FQDNで同じとなる名前のものがあると使えないので、他のものにした方がいいです。

####クラスタタイプ

クラスタタイプとしては普通にHadoopを。HBaseとかStormとかも選べます。

>SparkはLinux版では未だ提供されてないようです。スクリプト実行機能を使えばsparkもインストールできるようですが。

####OS

Linuxを選びます。これがメインですので。

>バージョンはUbuntu 12.04.5 LTSのようです。

####バージョン

バージョンは選択の余地はありませんのでそのままで。

####subscription

普通の人は1つだけでしょう。会社とかの人は適切なものを選択しましょう。

####Resource Grop

基本的にデフォルトのままでよいかと。

####ログイン情報

クラスタにログインするユーザーとsshユーザーを設定します。
ログインの方は標準でadminとなっていたのでとりあえずそのままにします。
sshログインでは、日常的に証明書ログインを利用しているのでそちらを選択しました。ID,PWによるログインでも何ら問題ないかと思います。

私は、ssh証明書でログインしたいので、その情報を登録しました。いわゆるid_rsa.pubの内容です。

![hdinsight](http://www.bluecode.jp/qiita/hdil002.png)

###ストレージ情報の設定

HDInsightで利用するStorageの情報を登録します。HDInsightでは、HDFSではなくStrage Service(BLOB)を利用することでいろいろなメリットを得ることができます。

新規に作成することも、既存のものを利用することもできます。ここでは新規に作成しました。

アカウント情報とコンテナ情報を指定します。

* アカウント:linuxhd
* コンテナ：testcontainer

としました。
ここの情報はMapReduce, Hive等でのinput,outputとして利用されるので、わかりやすい名前にしておきましょう。

![hdinsight](http://www.bluecode.jp/qiita/hdil003.png)

###利用するVMやノード数を設定する

HDInsightではHeaderノードとして最低つの2VMを必要とします。Workerノードは1VMから構成することができます。
なので、最小構成でも3つのVMが必要になります。まあ、1時間あたり、100円程度なのでよしとしましょう。

Workerノード数は後から変更することができますが、VMのタイプは変更できないようなので本番利用等ではきっちりサイジングを行う必要があるでしょう。

設定が終わったらCreateボタンを押して、クラスターを作成します。

![hdinsight](http://www.bluecode.jp/qiita/hdil004.png)

>Option設定で、プロビジョニング用のスクリプトを実行したりすることができるようです。sparkとかHueとかをインストールすることもできるようです。

準備が完了するまで待ちます。私が試した際は約20分くらいかかりました。

###動作の確認

リソースにクラスタとStrageが追加されます。クラスタを選択すると、状態を確認することができます。

statusがRunningになると利用準備完了です。

![hdinsight](http://www.bluecode.jp/qiita/hdil005.png)

##HDInsight 基本動作の確認

###ログイン

HDInsightの管理画面のSSHに関する情報に、ログイン用のホスト情報が表示されています。

ssh用のホスト名は、\<hostname>-ssh.azurehdinsight.netとなるようです。
ではsshでログインしてみましょう。

```bash
ssh tamaki@linuxHD-ssh.azurehdinsight.net
```
としたところ、Ubuntuのコンソールが表示されました！

hadoop versionコマンドを入力すると、下記のようになりました。

```bash
hadoop version

Hadoop 2.6.0.2.2.7.1-33
Subversion git@github.com:hortonworks/hadoop.git -r 4b63a8d70ee31c41965aa82d77b87a5e405b7a37
Compiled by jenkins on 2015-10-13T03:55Z
Compiled with protoc 2.5.0
From source with checksum af22522c2b309156285e52785ce3ae70
This command was run using /usr/hdp/2.2.7.1-33/hadoop/hadoop-common-2.6.0.2.2.7.1-33.jar
```

最新は2.7.1ですが、2.6なのでそんなに古くありません。

###HDFSへのアクセス

HDInsightではクラスタ作成時に指定したコンテナにHDFSがマップされます。ですのでBLOB制御コマンドも利用できますが、HDFS制御コマンドも利用できます。

hadoop fs コマンドでHDFSを見てみます。

```bash
hadoop fs -ls /

Found 9 items
drwxr-xr-x   - root   supergroup          0 2015-11-28 03:25 /HdiSamples
drwxrwxrwx   - yarn   hadoop              0 2015-11-28 03:18 /app-logs
drwxr-xr-x   - root   supergroup          0 2015-11-28 03:25 /example
drwxr-xr-x   - hdfs   supergroup          0 2015-11-28 03:04 /hdp
drwxr-xr-x   - hdfs   supergroup          0 2015-11-28 03:19 /hive
drwxr-xr-x   - mapred supergroup          0 2015-11-28 03:18 /mapred
drwxrwxrwx   - mapred hadoop              0 2015-11-28 03:18 /mr-history
drwxrwxrwx   - hdfs   supergroup          0 2015-11-28 03:20 /tmp
drwxr-xr-x   - hdfs   supergroup          0 2015-11-28 03:04 /user
```
初期設定でいろいろなディレクトリが出来ています。

###BLOBへのアクセス

BLOBを意識して利用する場合は、wasb://\<container_name>@\<strage_account>.blob.core.windows.net/というよう形式で制御可能のようです。

では、中身を見てみましょう。

```bash
hadoop fs -ls wasb://testcontainer@linuxhd.blob.core.windows.net/

Found 9 items
drwxr-xr-x   - root   supergroup          0 2015-11-28 03:25 wasb://testcontainer@linuxhd.blob.core.windows.net/HdiSamples
drwxrwxrwx   - yarn   hadoop              0 2015-11-28 03:18 wasb://testcontainer@linuxhd.blob.core.windows.net/app-logs
drwxr-xr-x   - root   supergroup          0 2015-11-28 03:25 wasb://testcontainer@linuxhd.blob.core.windows.net/example
drwxr-xr-x   - hdfs   supergroup          0 2015-11-28 03:04 wasb://testcontainer@linuxhd.blob.core.windows.net/hdp
drwxr-xr-x   - hdfs   supergroup          0 2015-11-28 03:19 wasb://testcontainer@linuxhd.blob.core.windows.net/hive
drwxr-xr-x   - mapred supergroup          0 2015-11-28 03:18 wasb://testcontainer@linuxhd.blob.core.windows.net/mapred
drwxrwxrwx   - mapred hadoop              0 2015-11-28 03:18 wasb://testcontainer@linuxhd.blob.core.windows.net/mr-history
drwxrwxrwx   - hdfs   supergroup          0 2015-11-28 03:20 wasb://testcontainer@linuxhd.blob.core.windows.net/tmp
drwxr-xr-x   - hdfs   supergroup          0 2015-11-28 03:04 wasb://testcontainer@linuxhd.blob.core.windows.net/user
```

こちらもいろいろ出来ています。

###BLOBへのファイルアップロード

BLOBへのファイルのアップロード（移動）は各種ツールで行うことが出来ますが、今回は、端末がMacということで、お馴染みのCyperDuckを利用しました。最新版では、Azure Storage Serviceに対応しているようです。

![hdinsight](http://www.bluecode.jp/qiita/hdil025.png)


>CLIツールも使いたかったのですが、LinuxのHDInsightの操作に制約があるようだったので、ここでの利用は見送りました。

ここではdata/data.csvというファイル名で、下記のファイルを作成し、アップロードしました。

```text
新橋店,100
新宿店,340
池袋店,874
渋谷店,400
```

BLOBは、フラットな階層で、ディレクトリという概念はありません。が、hoge/foo.txtという名前をつけることで、仮想的に階層を表現することはできます。

>なおCyberduckでdata/data.csvというファイル名をアップロードしたらdata:data.csvという名前になってしまったので、再度、サーバ上でdata/data.csvとリネームしました。

内容を確認してみます。

```bash
hadoop fs -cat wasb://testcontainer@linuxhd.blob.core.windows.net/data/data.csv

新橋店,100
新宿店,340
池袋店,874
渋谷店,400
```
fs -catで確認して見るとうまくアップロードされたのが確認できました。

##Hiveを使ってみる

何もしなくてもhiveコマンドは標準で使えるようになっています。コンソールでhiveと打ってみましょう。

```bash
hive

hive>show databases;
show databases
OK
default
Time taken: 0.44 seconds, Fetched: 1 row(s)
hive>
```

show databases;してみると、標準のHiveと同じようにdefaultが確認できます。
ここでは、defaultをそのまま使います。

>別のDBが使いたいなら、create database testdb;などとし、use testdb;とすればいいだけです。

###テーブルの作成（データとの紐付け）

先ほどアップロードした/data/data.csvを格納してクエリをかけてみます。
EXTERNALとすることで、drop tableしてもデータファイル自体は消えません。

```bash
hive> CREATE EXTERNAL TABLE sales(shop string, sales int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE LOCATION 'wasb://testcontainer@linuxhd.blob.core.windows.net/data/';
```

うまく作れたようです。
ではクエリを投げてみます。hiveといっても何も特別なことはありません。

```bash
hive> select * from sales;

OK
新橋店	100
新宿店	340
池袋店	874
渋谷店	400
Time taken: 0.828 seconds, Fetched: 4 row(s)
```

うまく動いているようです。
ここでは、ものすごく小さなファイルで試しましたが、ここまで動けば、あとは、巨大ファイルを投入し、必要に応じてノード数を増やせばいいだけです。すごい時代です。

##HiveをREST経由で利用する

hiveコマンドを使えるようにはなりましたが、いろいろ自動化するにはAPI経由で利用できれば便利です。
Hiveには標準でAPI([WebHCat](https://cwiki.apache.org/confluence/display/Hive/WebHCat+Reference))があるので、それを叩いてみます。

なお、cURLやwgetでも良いのですが、Basic認証等を突破する必要があるので、ローカルMacの上でPHPでAPIを叩くサンプルを書いてみました。

>なお、通信にはGuzzleライブラリを利用しています。Guzzleについては、[こちら](http://qiita.com/zaburo/items/13bfdc349e1421421c98)も参考にしてみてください。

```php
<?php

	require_once 'vendor/autoload.php';
	
	//Guzzle
	$client = new GuzzleHttp\Client();

	//APIのstatusを取得
	$get = $client->get('https://linuxhd.azurehdinsight.net/templeton/v1/status',[
		'auth' => ['admin','password'], //Basic認証対応
	]);

	//内容表示
	echo $get->getBody();

	echo "<br>========<br>";

	//Hive QL実行
	$post = $client->post('https://linuxhd.azurehdinsight.net/templeton/v1/hive?user.name=admin',[
		'auth' => ['admin','password'], //Basic認証対応
		'form_params' => [
			'execute' => "use default;select * from sales where shop like '新%';", //クエリ
			'statusdir' => 'wasb://testcontainer@linuxhd.blob.core.windows.net/output', //結果出力先
		],
	]);

	//内容表示
	echo $post->getBody();

```

なお、クエリのレスポンスとしては、クエリ結果が返るわけではなく、JobIDが返ってきます。
なので、JobIDを投げて、ステータスを確認したりします。

結果は、statusdirで指定されたディレクトリに出力されます。上記の場合では、コンテナ直下のoutputフォルダに出力されます。
処理が終わると、指定したディレクトリ下に、

* stdout（結果）
* stderr（エラー）
* exit（終了フラグ？）

ができるようです。

```text
新橋店	100
新宿店	340
```

LIKEが効いてます。

##ExcelからHDInsight Hiveを利用してみる

みんな大好きExcel。
ExcelからHDInsightのHiveを利用する方法としてODBC経由の方法を試してみます。

なお、およびPowerQuery経由でもデータを取得できるようですが、[ここ](https://azure.microsoft.com/ja-jp/documentation/articles/hdinsight-connect-excel-power-query/)を見る限り、出力結果を取り込むもので、クエリを投げたりはできないみたいです。

###Excelのインストール（省略）

Excelはインストールされているものとします。とりあえず2013を利用します。
たぶん2010, 2016でも動くのでないのでしょうか？

###ODBCの設定

では、ODBCのデータソースを設定してみます。

####ODBCドライバーのインストール

HDInsight Hive用の[ODBCドライバをダウンロード](http://www.microsoft.com/en-us/download/details.aspx?id=40886)してインストールします。使ってるExcelが32bitか64bitかでODBCも違うので気をつけます。

####ODBC データソースの設定

Windows10ならスタート画面の検索でodbcとか入れれば直ぐに見つかります。
まあ、HDInsight使ってる人なら直ぐに見つけられるでしょう。「追加」でソースを追加します。

![hdinsight](http://www.bluecode.jp/qiita/hdil010.png)

####Hive ODBCドライバの選択

Microsoft Hive ODBC Driverを選びます。

![hdinsight](http://www.bluecode.jp/qiita/hdil011.png)

####接続情報の設定

HDInsightに対する接続設定を行う画面が出ますので入力します。入力が完了したらTestをしてみましょう。
OKを押して設定を完了します。

![hdinsight](http://www.bluecode.jp/qiita/hdil012.png)


###ODBCを利用した読み込み

ここからはExcel上での作業です。データメニューを選択し、さらに、その他のデータソース、データ接続ウィザードと選択していきます。

![hdinsight](http://www.bluecode.jp/qiita/hdil013.png)

####ODBCの選択

データソースの選択画面が出てくるのでODBC DSNを選びます。

![hdinsight](http://www.bluecode.jp/qiita/hdil014.png)

####Hive ODBCの選択

ODBCのデータソースの中から設定したHDInsight Hive（前の手順で作成した名前）を選択します。

![hdinsight](http://www.bluecode.jp/qiita/hdil015.png)

####接続情報再確認

再度、接続情報を聞いてきますのでPasswordを入力します（足りないところがあれば足します）。

![hdinsight](http://www.bluecode.jp/qiita/hdil016.png)

####対象テーブル選択

認識されたHive上のテーブルが表示されます。接続対象となるテーブルを選択します。ここではsalesを選びます。

![hdinsight](http://www.bluecode.jp/qiita/hdil017.png)

####接続状態の保存

接続情報を保存するか聞いてくるので保存します。

>一度保存しておくと、Excelの「既存の接続」から選べば直ぐに呼び出せます。

![hdinsight](http://www.bluecode.jp/qiita/hdil018.png)

####読み込み位置の指定（とクエリの編集）

Excelの何処に取り込むかを聞いてくるので、適当なセルを選択します。
なお、ここで下部にある「プロパティ」を開き、「定義」タブを選択することで実行するクエリを編集できます。

![hdinsight](http://www.bluecode.jp/qiita/hdil019.png)

####Hive QLの編集

データインポートダイアログの「プロパティ」をクリックし、「定義」を見て下さい。
ここの、「コマンド文字列」を編集することでHiveに対するリクエストを編集できます。

![hdinsight](http://www.bluecode.jp/qiita/hdil023.png)

####接続情報の再々確認

うざいほど接続情報を聞いてきますが、素直に入力します。

![hdinsight](http://www.bluecode.jp/qiita/hdil020.png)

少し待ちますと、読込中という旨、セルに表示されます。

####読み込み完了

HiveからExcelにデータの取込が完了しました。便利？です。。

![hdinsight](http://www.bluecode.jp/qiita/hdil021.png)

###ノード数を変更する

処理が重いなら、ノード数を増やしましょう。管理画面のScaleメニューを操作することでWorker(Data) nodeの数を変更することができます。

>Hiveでは絶対的なリードタイムがかかります（よく言われるのはどんな軽い処理でもMR準備の15秒は絶対にかかる）。

しかしHDInsightでImpalaとかPrestoとかのNoMR系SQL on Hadoopに対応していないのが痛い。対応してほしい。
おそらく、そっち系はDataLakeのU-SQLを使えってことなのでしょうか。

![hdinsight](http://www.bluecode.jp/qiita/hdil024.png)

##その他

###Streaming

どうやら、標準で各ノードにインストールされている言語は、Python 2.7.3のようです。Javaは1.7.0_85。
Streaming処理を書くならPythonかJavaが無難なようです（JavaならMR直で書く方がいいですね）。

###開発環境

HDInsightを使えばいつでも大規模展開ができます。もちろん、有償の環境をいつもOnにしておくのは気持ちが落ち着きません。
なので、ローカルでロジックを開発し、検証がある程度できた時点でクラウドを使うというのがいいでしょう。

ローカルでMRやHive環境を作る方法は[ここ](http://qiita.com/zaburo/items/6086ded8cbb43e2ddd39)にあります。