Cloud上のHadoopへのデータ転送とSparkからの参照


[前回](http://qiita.com/y_t_p/items/d505db35b63a6700e1e6)作成したClusterへデータを転送して、Sparkから参照します。
ローカル(Mac)からのwebhdfsを使ったhdfsへのファイル転送やります。

##ローカル（Mac）からファイル転送
webhdfsはRESTのインタフェースを持っています。
前回紹介したようにBluemix上で払い出したHadoopのClusterには
ディフォルトでwebhdfsのURLが払い出されますのでそれを使います。

###hdfsの構成
Bluemix上のHadoopではhdfsのrootディレクトリ下に下図の構成がディフォルトで用意されます。

![image1.png](https://qiita-image-store.s3.amazonaws.com/0/31585/097e4aa8-93c2-44bc-77f4-89a46eb9530a.png "image1.png")

また、userディレクトリしたにプロビジョニング時のユーザーディレクトリが用意されますので、以後そちらのディレクトリ（/user/tanayu）にファイルを置いていきます。

![image2.png](https://qiita-image-store.s3.amazonaws.com/0/31585/273fb0da-7d2c-e396-0ecf-3f92ff4daa9d.png "image2.png")


###webhdfsを使ったディレクトリの参照
ここではcurlを使ってwebhdfsのRESTインタフェースを操作します。
ベースとなるURL:https://bi-hadoop-prod-4148.bi.services.us-south.bluemix.net:8443/gateway/default/webhdfs/v1/
は共通で、その後ろにrootディレクトリからのpathを書きます。
最後にopでオペレーションを指定しています。ここではLISTSTATUSを使ってディレクトリの情報を取得しています。

以下の例では/userのディレクトリの情報を参照します。
ユーザー名、パスワードはご自身の環境のものに置き換えてください。

```bash
curl -i -k -s --user <user name>:<password> --max-time 45 https://bi-hadoop-prod-4148.bi.services.us-south.bluemix.net:8443/gateway/default/webhdfs/v1/user?op=LISTSTATUS
```

コマンドを実行するとHTTP Statusと/userのディレクトリ情報がJson形式で
出力されます。
かなり見づらいですが、戻される情報は基本的にhdfs dfs -lsコマンドと差はありません。

![image3.png](https://qiita-image-store.s3.amazonaws.com/0/31585/9c37d7f1-8731-88a3-a94d-15fdd522276f.png "image3.png")

###webhdfsを使ったファイルの転送
次にローカルにあるファイルをwebhdfsを利用してBluemix上のClusterに配置します。

以下の例では/user/tanayuディレクトリの下にad_sample_log.csvファイルを作成しています。opはCREATEを利用します。

```bash
curl -i -L -k -s --user <user name>:<password> --max-time 45 -X PUT -T ad_sample_log.csv https://bi-hadoop-prod-4148.bi.services.us-south.bluemix.net:8443/gateway/default/webhdfs/v1/user/tanayu/ad_sample_log.csv?op=CREATE
```

下図は実行時のコンソールです。

![image4.png](https://qiita-image-store.s3.amazonaws.com/0/31585/6eeac67e-8c00-9938-4de7-71da8d50b8e8.png "image4.png")

ファイルが転送されたかの確認をLISTSTATUSで行います。

```bash
curl -i -k -s --user <user name>:<password> --max-time 45 https://bi-hadoop-prod-4148.bi.services.us-south.bluemix.net:8443/gateway/default/webhdfs/v1/user/tanayu?op=LISTSTATUS
```

以下はコマンドの戻り値です。
正常に作成されている事がわかります。

![image5.png](https://qiita-image-store.s3.amazonaws.com/0/31585/4386d08e-93ed-7a2c-7c11-6c4c626ca602.png "image5.png")


###webhdfsを使ったファイルの削除
最後にwebhdfsを使ったファイルの削除処理です。
先ほど転送したad_sample_log.csvファイルを削除します。

削除はop=DELETEでおこないます。

```bash
curl -i -L -k -s --user <user name>:<password> --max-time 45 -X DELETE https://bi-hadoop-prod-4148.bi.services.us-south.bluemix.net:8443/gateway/default/webhdfs/v1/user/tanayu/ad_sample_log.csv?op=DELETE
```

下図はコマンド実行時のコンソールです。

![image6.png](https://qiita-image-store.s3.amazonaws.com/0/31585/72e870e3-b7b6-71a7-dc6e-1aa1cde25250.png "image6.png")


ほぼwebhdfsの機能をそのまま使えそう。

##Sparkのプログラム作成
今回はhdfs上に配置したをSparkから参照して行数を表示するだけの簡単なプログラムです。

```scala
package org.tanayu.qiita

import org.apache.log4j.{Level,Logger}
import org.apache.spark.{SparkConf, SparkContext}

object sample {
  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName("qiita_sample")
    val sc = new SparkContext(conf)
    run(sc)
    sc.stop
  }
  private[qiita]
  def run(sc: SparkContext){
    val txt = sc.textFile("hdfs://user/tanayu/ad_sample_log.csv")
    println("count :" + txt.count());
  }
}
```

上記をbuildした.jarをscpで転送します。
以下はコマンドの例です。

```bash
scp  target/scala-2.11/bioc_sample-assembly-0.0.1.jar <user name>@bi-hadoop-prod-4148.bi.services.us-south.bluemix.net:
```

転送が終わるとhome_dirにファイルが転送されます。

以下は転送したjarの実行コマンドです。
ディフォルトだとINFOのログがいっぱい出てウザいので
log4jのレベルをWARNに設定しています。

```bash
spark-submit --conf spark.driver.extraJavaOptions=-Dlog4j.configuration=file:./log4j.properties --class org.tanayu.qiita.sample --master yarn-client  bioc_sample-assembly-0.0.1.jar
```

>Cloud上のHadoopのconfigurationは直接触れないので、
/etc/hadoop/conf/log4j.propertiesをhome_dirにコピーし中身を変更して
spark-submit時に渡しています。ちなみに書き換える部分は下記です。
hadoop.root.logger=WARN,console


下記は実行結果です。
![image7.png](https://qiita-image-store.s3.amazonaws.com/0/31585/2c44d59e-7661-7447-0d35-12cec9d1cbb5.png "image7.png")