CDH5の環境でSpark 2.0を試してみる

ClouderaのHadoopディストリビューション、CDH5の最新版(CDH5.8)には Apache Spark 1.6 が同梱されています。一方、今年の6月にはSparkの新しいメジャーバージョン、Spark 2.0がリリースされました。

***
2016/03追記： この記事公開時点ではβ版としてのリリースでしたが、2016年12月からSpark2.0はGAになっています。（Tech previewではありません）。なので、サブスクリプションを購入している場合はサポート対象です。

なお、Spark 2.0 release 2 というリリースが現時点の最新になっており [^1]、Spark 2.1からバックポートされたパッチも含まれています。ご利用になる場合はKnown Issue [^2] をご覧の上ご注意ください。 
***

ローカルで試すのは簡単ですが、既存のCloudera Managerで構築しているクラスタに導入するのは面倒です。放置していましたが、昨日のClouderaのブログで Spark 2.0 のβ版が利用できるようになったという良いニュースを発見。
<img width="900" alt="スクリーンショット 2016-09-30 8.36.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/bb53db34-74ca-a053-4f39-e1c12bcb0878.png">

早速手元の Cloudera Quickstart VMの環境で試してみました。。

- Apache Spark 2.0 Beta Now Available for CDH
http://blog.cloudera.com/blog/2016/09/apache-spark-2-0-beta-now-available-for-cdh/


#環境
* Spark 2.0
* CDH 5.8
* Cloudera Manager 5.8

#Spark 2.0をセットアップ
手元のCloudera Quickstart VMに導入します。

Spark 2.0のダウンロードページ。
https://www.cloudera.com/downloads/spark2/2-1.html

[2017/04/19 追記] Spark 2.1のリリースにより、URLが変わりました。

インストール手順は以下に記載されています。
http://www.cloudera.com/documentation/spark2/latest/topics/spark2_installing.html

## Cloudera ManagerでSpark 2.0をセットアップするための準備
### CSDファイルをダウンロード
Spark 2.0をCloudera Managerからセットアップするためのファイルをダウンロードします。URLは上記のダウンロードページを参照してください。

<img width="453" alt="スクリーンショット 2016-09-30 8.38.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/f97a6810-97f7-aad5-c67d-7bb0ee68026a.png">


### CSDをセットアップ
ダウンロードしたCSDファイルを所定の位置に配置する必要があります。詳細は下記も参照してください。
http://www.cloudera.com/documentation/enterprise/latest/topics/cm_mc_addon_services.html#concept_kpt_spj_bn


```
[cloudera@quickstart ~]$ sudo su -
[root@quickstart ~]# cd /opt/cloudera/csd/
[root@quickstart csd]# ls
[root@quickstart csd]# cp ~cloudera/Downloads/SPARK2_ON_YARN-2.0.0.cloudera.beta1.jar .
[root@quickstart csd]# chown cloudera-scm:cloudera-scm SPARK2_ON_YARN-2.0.0.cloudera.beta1.jar 
[root@quickstart csd]# chmod 644 SPARK2_ON_YARN-2.0.0.cloudera.beta1.jar 
[root@quickstart csd]# service cloudera-scm-server restart
Stopping cloudera-scm-server:                              [  OK  ]
Starting cloudera-scm-server:                              [  OK  ]
[root@quickstart csd]# 
```

### Parcelをアクティベート
Cloudera ManagerにログインしてCloudera Management Service を再起動します。

<img width="353" alt="スクリーンショット 2016-09-30 8.43.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/2b98b352-ac7a-f130-1e00-9b4fe629bdf7.png">

この操作によりSpark 2のParcelが表示されます。

<img width="995" alt="スクリーンショット 2016-09-30 8.53.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/3e66732e-e674-fb3a-c94d-2176181436a4.png">

iというアイコンをクリックしたところβ版と表示されました。

<img width="447" alt="スクリーンショット 2016-09-30 8.54.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/6b4a7c23-5149-823a-0db8-e9ed07e664f2.png">

以下の順序で各ノードに配布します。

- ダウンロード
- 配布
- アクティベート 

<img width="1016" alt="スクリーンショット 2016-09-30 8.54.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/44154289-5ae6-3885-8ec3-b946d392e709.png">

これで準備OKです。

<img width="1018" alt="スクリーンショット 2016-09-30 8.56.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/9d37a2ad-beac-d2cf-d6d5-f4f48c5765b4.png">


## Cloudera Manager から Spark2 サービスを追加

他のサービス（HDFSやImpala）と同様に Spark2サービスを追加します。今回は１ノードなので、History ServerもGatewayも同じノードに設定しました。Cloudera Managerのホームに戻り、サービスを追加します。

<img width="346" alt="スクリーンショット 2016-09-30 8.57.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/07f703a3-6581-ac57-f93b-ab7783e7ef2e.png">

「サービスを追加します」を選ぶと Spark 2 が選べるようになっています。

<img width="950" alt="スクリーンショット 2016-09-30 8.58.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/cec88577-1f66-5a79-1591-30255f963d5d.png">

画面の指示に従い進みます。
<img width="949" alt="スクリーンショット 2016-09-30 8.59.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/92e1e7ac-f94d-a2fb-71e1-074252675562.png">
導入中...

<img width="962" alt="スクリーンショット 2016-09-30 9.02.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/6dec4278-b872-7327-6dd2-3dc8a2683ca6.png">

これでSpark 2が利用できるようになりました。

<img width="963" alt="スクリーンショット 2016-09-30 9.02.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/c80c3bf9-b3b4-6abb-3876-5b9350d38b6f.png">


## Spark 2サービスの起動
Spark 2サービスが追加されています。

<img width="947" alt="スクリーンショット 2016-09-30 9.02.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/9e35b89f-01c1-0252-da9e-7c3e1b0a64eb.png">

Spark 2サービスのページ

<img width="963" alt="スクリーンショット 2016-09-30 9.03.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/67c7032d-cb53-917c-99e0-489715481ac8.png">



# Spark 2を試す
セットアップしたSpark2.0で簡単なコードを実行します。テスト用に適当なファイル(今回はwordsというファイル)をHDFSにアップロードしておきます。

```
[cloudera@quickstart ~]$ hdfs dfs -put /usr/share/dict/words 
```

アップロードしたら spark2-shell (spark-shellではない)をYARN上で実行します。

```
[cloudera@quickstart ~]$ spark2-shell --master yarn-client
Warning: Master yarn-client is deprecated since 2.0. Please use master "yarn" with specified deploy mode instead.
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel).
16/09/29 17:04:05 WARN util.Utils: Your hostname, quickstart.cloudera resolves to a loopback address: 127.0.0.1; using 192.168.2.130 instead (on interface eth1)
16/09/29 17:04:05 WARN util.Utils: Set SPARK_LOCAL_IP if you need to bind to another address
16/09/29 17:04:17 WARN spark.SparkContext: Use an existing SparkContext, some configuration may not take effect.
Spark context Web UI available at http://192.168.2.130:4040
Spark context available as 'sc' (master = yarn, app id = application_1475193637312_0001).
Spark session available as 'spark'.
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 2.0.0.cloudera.beta1
      /_/
         
Using Scala version 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_67)
Type in expressions to have them evaluated.
Type :help for more information.

scala>
```

## 行数のカウント
アップロードしたファイルの先頭３行を表示し、行数をカウントします。

```
scala> sc.textFile("/user/cloudera/words").take(3)
res1: Array[String] = Array(1080, 10-point, 10th)

scala> sc.textFile("/user/cloudera/words").count()
res0: Long = 479829                                                             
```

## 円周率の計算
http://spark.apache.org/examples.html
上記のページにあるサンプルコードを利用して円周率を計算します。

```
scala> val count = sc.parallelize(1 to 100).map{i =>
     |   val x = Math.random()
     |   val y = Math.random()
     |   if (x*x + y*y < 1) 1 else 0
     | }.reduce(_ + _)
count: Int = 81                                                                 
scala> println("Pi is roughly " + 4.0 * count / 100)
Pi is roughly 3.24

scala> :quit
[cloudera@quickstart ~]$ 
```

## （おまけ）WebUI (History Server) のスクリーンショット

<img width="949" alt="スクリーンショット 2016-09-30 9.13.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/6a49944f-946b-83a8-fdc6-9563929a827d.png">

ジョブ一覧

<img width="960" alt="スクリーンショット 2016-09-30 9.13.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/d1a9c7ea-e9dc-578a-d432-90ee1deec4d7.png">

ジョブ

<img width="669" alt="スクリーンショット 2016-09-30 9.15.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/13776/d9264264-cc36-7bce-9718-a6b2467fd3ff.png">



# まとめ
このようにCDH5環境でSpark2.0をセットアップして動作させることができました。Spark 2系をCloudera環境で利用することはできますが、いずれSpark 2.xがCDHに同梱され、もっと簡単にセットアップできるようになるでしょう。楽しみです。

[^1]: https://www.cloudera.com/documentation/spark2/latest/topics/spark2.html
[^2]: https://www.cloudera.com/documentation/spark2/latest/topics/spark2_known_issues.html