YARN上でジョブを走らせてみる（普通のjar編）


## Outline

HadoopのYARN上で色々なアプリを動かすことになったのでテスト環境を作ってみた。

今回はYARNに対して、sparkでもmapReduceでもない、普通のjar（hadoopへの依存が何もないjar）を実行してみる。

## 環境

### メインマシン

実際に動かしているハード。
WebUIなどの動作確認に使う。

### Client

OS: Ubuntu14.04 （AWS EC2）
Hadoop: 2.5.2
Java: 8

### HDFSクラスタ

擬似分散モード：http://qiita.com/uryyyyyyy/items/a7ac8dc088b6fc2d115d
完全分散モード：http://qiita.com/uryyyyyyy/items/ebd732d3935ee404f4e7
ここではResourceManagerとnameNodeは同じhostにあるとする。

OS: Ubuntu14.04 （AWS EC2）
ユーザー: ubuntu
IP: PublicIP, PrivateIP
Hadoop: 2.5.2
port: 全開放（22, 80, 8020, 8032, 8088, 50070が開いてればたぶん大丈夫）

Clientとhadoopクラスタは同じsubnetにいて、privateIPでアクセスできる状態とする。

## 事前準備

以下、clientでの操作を基本とする。

### Clientへ各種インストール

```bash:terminal
# java
sudo add-apt-repository ppa:webupd8team/java -y
sudo apt-get update
sudo apt-get install oracle-java8-installer -y

# Hadoop
# めんどくさいのでHomeにそのまま置く
wget http://ftp.meisei-u.ac.jp/mirror/apache/dist/hadoop/common/hadoop-2.5.2/hadoop-2.5.2.tar.gz
tar zxvf hadoop-2.5.2.tar.gz
```

### 環境変数など設定

http://qiita.com/uryyyyyyy/items/a7ac8dc088b6fc2d115d
別記事の通りに、

- hadoop-env.sh
- /etc/profile
- core-site.xml
- hdfs-site.xml

を編集する。

### HDFSにJarを置けるようにする。

別記事参照
http://qiita.com/uryyyyyyy/items/056e79ea0d326326f416

今回はmyJarsというフォルダを作る。

```bash:master_terminal
./hadoop-2.5.2/bin/hdfs dfs -mkdir /myJars
```


## Jarの作成

YARN上で普通のjarを実行する場合、ApplicationMasterというものが別途必要になる。

以下を参照。ここで、ApplicationMasterが全体のstatus管理、Containerが各自の実行したいjar（というかコマンドから実行する全てのapplication）となる。
http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html

### ApplicationMaster

こちらに用意した。
https://github.com/uryyyyyyy/hadoopSample/tree/master/yarnAppMaster

内容の説明は長くなるので後で。

### 普通のjar

こちらに用意した。
https://github.com/uryyyyyyy/hadoopSample/tree/master/yarnNormalJar

見てわかるように、何も依存せずに、引数を`println`するだけの簡単なもの。

## 実行してみる

### Clientの用意
`hadoop jar`とかのコマンドでもいいのだけど、せっかくなのでJarから実行してみる。

こんなのを用意した。
https://github.com/uryyyyyyy/hadoopSample/tree/master/yarnClient

pomになっているのは、sbt-assemblyだとyarn-clientが上手く行かなかったため。（詳細は後述。）

### 実行

```bash:client_terminal
java -jar .yarnClient-0.1.0.jar [ResourceManagerのIP] hdfs://[NameNodeのIP]/　myJars/yarnAppMaster-assembly-1.0.jar myJars/yarnNormalJar-assembly-1.0.jar com.example.yarn.app.master.ApplicationMaster com.example.yarn.app.normal.HelloWorld
```

### 結果確認

http://[PublicIP]:8088/cluster/
で確認できる。

ApplicationMasterのlogを見ると、別のnodeでコンテナを立ち上げてる様子がわかるので、そのコンテナを見に行くとちゃんと結果が表示されている。

```text:applicationMaster_log
Launching container Container: [ContainerId: container_1443051828634_0008_01_000002, NodeId: ip-172-31-3-4.ap-northeast-1.compute.internal:35927, NodeHttpAddress: ip-172-31-3-4.ap-northeast-1.compute.internal:8042, Resource: <memory:1024, vCores:1>, Priority: 0, Token: Token { kind: ContainerToken, service: 172.31.3.4:35927 }, ]
completedcontainer_1443051828634_0008_01_000002
```

```text:container_log(1443051828634_0008_01_000002)
----start----
myArgs
----finish----
```

## ハマったところなど。

### ジョブがたまってると後続が動かない。
自分の手元では擬似分散モードで動かしたのでnodeが一つしかない。その状態でなんかの拍子に応答が帰ってこないジョブがあったりすると、以降のジョブ実行命令はずっと待機することになる。。

### yarn-clientがsbtでfatJar化できない。
yarn-commonとyarn-apiあたりが、同じpackageのpackage-info.classを持っていて衝突してしまうっぽい。
詳しく調べてないが、色々見たらmavenのshadePluginなら解決できてたっぽいのでそれを使った。

### ApplicationMasterがいないと常にFAILになる。
ApplicationMasterを経由しないで普通のjarの実行も出来るのではと思い試してみたら、動作はするしstdOutには結果が出てきたものの、ジョブとしてはfailになる。

## まとめ

あとでJava版も書くかも。