GoogleComputeEngine(GCE)上にHadoopクラスタを構築して、MapReduceを実行してみる

## はじめに
* 手順としては[こちら](https://cloud.google.com/hadoop/what-is-hadoop?
_ga=1.131626703.1533406624.1415164692)に従っていく感じ
* 筆者の実行環境はMacOS X 10.9.5
* GoogleCloudPlatform(GCP)の課金アカウント等は持っている前提
* GoogleCloudStorage(GCS)で専用バケットを作っている前提

## [GoogleCloudSDK](https://cloud.google.com/sdk/)のインストール
以下のコマンドを打つ

```bash
curl https://sdk.cloud.google.com | bash
```
途中で何回か(yes/no)を求められる事になるが、"改善のためにgoogleに利用状況を送信しますか？"的な問い以外は全部yesにした。(Googleさんすいません)

### 認証
マシンに認証情報を登録して、GCPのAPIを叩けるようにする。

```bash
gcloud auth login
```
認証用のURLが表示されるので、そのURLを開く。認証番号的なものを入力させられた気がします(うろ覚え)

### デフォルトのプロジェクト登録
${PROJECT}は自分が構築したいプロジェクトのproject_idを入れる

```bash
gcloud config set project ${PROJECT}
```


## [bdutil](https://cloud.google.com/hadoop/setting-up-a-hadoop-cluster#setupscripts)のインストール
BigData(Hadoop)関係のユーティリティスクリプトであるbdutilをインストールする。
https://storage.googleapis.com/hadoop-tools/bdutil/bdutil-latest.zip (zip)
もしくは
https://storage.googleapis.com/hadoop-tools/bdutil/bdutil-latest.tar.gz (tar.gz)
をダウンロードして解凍する。自分は$HOMEに解凍した。解凍するとbdutil-0.36.4(2014/12/11現在)というディレクトリが出来るので、必要であればここにPATHを通しておく。(自分は面倒なので通さなかった)

## Hadoopクラスタの構築
bdutil-0.36.4に移動(PATHを通していない場合)して以下のコマンドを打つ

```bash
./bdutil <OPTIONS> deplpy 
```
OPTIONSの内容はこんな感じ(主要なのを記述、詳しくは./bdutil --helpを見る)

| Option              | 意味                                                         |
|---------------------|------------------------------------------------------------- |
| -b                  | デプロイ設定を置いておくGCSのバケット名(-Fがgsの場合はこのバケットにhadoopのfsが紐づく) |
| -F, --default_fs    | hadoopで使うファイルシステム。gsかhdfsが選べてデフォルトはgs(GCSのこと) |
| -z, --zone          | インスタンスを作るゾーン(地域) デフォルトはus-central-b           |
| -m, --machine_type  | インスタンスのタイプ(スペック) デフォルトはn1-standard-4          |
| -n, --num_workers   | ワーカーノード(HadoopでいうDataNode)の数                        |
| -P, --prefix        | インスタンス名につく接頭辞。マスターノード名が"{prefix}-m"、ワーカーノード名が"{prefix}-w-{n}"になる |
| -i, --image         | インスタンスに適用する[イメージ](https://cloud.google.com/compute/docs/images)。デフォルトだとdebian7が入る。 |
| -e, --env_var_files | インスタンスにどういうミドルウェアを入れるか。HiveとかSparkとか入れられる。 |

使用例としては最低限で指定するとこんな感じ

```bash
./bdutil -b hoge-storage -n 3 -P hoge-cluster deploy
```
設定を細かくしたい場合はこんな感じ

```bash
./bdutil -b hoge-storage -F gs -z asia-east1-b -m n1-standard-2 -n 3 -P hoge-cluster -i centos-6-v20141205 -e bigquery_env.sh,datastore_env.sh,extensions/querytools/querytools_env.sh,extensions/spark/spark_env.sh deploy
```

"-F gs"をあえて明示しているのは-eにextensions/querytools/querytools_env.sh(HiveとPigを入れるための設定)を指定するとdefault_fsが"hdfs"に切り替わるため。(ちょっとハマった)

querytools_env.shの中身をみるとこんな事が書いてあるが筆者がHadoopエコシステム初心者のため詳しい理由はちゃんと分かってません…w (HiveとかPigはMapReduceに比べて処理が重いので中間データの置き場はHDFSを使った方が良い、的な事を書いている気がする)
> Set the default filesystem to be 'hdfs' since Pig and Hive will tend to rely on multi-stage pipelines more heavily then plain Hadoop MapReduce, and thus be vulnerable to eventual list consistency. Okay to read initially from GCS using explicit gs:// URIs and likewise to write the final output to GCS, letting any intermediate cross-stage items get stored in HDFS temporarily.

## マスターノードにログイン
マスターノードにsshでログイン

```bash
./bdutil shell -b hoge-storage -P hoge-cluster
```

### 下準備

lsでhdfsの中身を確認。GCSのバケットの内容と一致することを確認。

```bash
hadoop fs -ls .
```
inputディレクトリを作成し、静的HTMLページを取得しhdfsに挿入

```bash
hadoop fs -mkdir input

curl http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/ClusterSetup.html > setup.html

hadoop fs -copyFromLocal setup.html input
```

## wordcountのJOBを実行

```bash
cd /home/hadoop/hadoop-install
hadoop jar hadoop-examples-1.2.1.jar wordcount input output
```
lsもう一回してoutputディレクトリが出来てればOK

```bash
hadoop fs -ls .
```


### JobTrackerのwebページ
http://<マスターノードの外部IPアドレス>:50030/jobtracker.jsp
でJobTrackerページが見れるらしいが自分は見れなかった(設定が足りない？50030のポートはリッスンしているっぽかった)
(2014/12/18追記)
インスタンスに対して50030に対するhttpアクセスが許可されてなかったからでした。許可設定したら見れました。

## あと片付け
deployコマンドと同じオプションでdeleteコマンドを実行するとインスタンスを削除できる
(必要ないオプションあるかも、未検証)

```bash
./bdutil -b hoge-storage -n 3 -P hoge-cluster delete
```