データサイエ「ソ」ティストは語る

データサイエンティストではない、パチもんのデータサイエ「ソ」ティストのブログ

VirtualBoxとCDH5でお手軽Apache Spark検証環境の構築

ということで、実際には1台のコンピュータ上なうえ、仮想化のオーバーヘッドもあるので「分散並列」で「高速」な処理はできないのだけど、動作検証ができる環境の作り方。

前提

もっとも、上記の環境はあくまで手元がそうだから、というだけで、VirtualBoxは最新版をインストールすればよいし、ゲストOSもCDHがインストールできるならUbuntuでもSLES(Suse)でもなんでもよい。

VirtualBox仮想マシンを作成

CDH5*1をインストールし、Sparkを動かすための仮想マシンを作る。CPU4コア、メモリ8GBを割り振る。ディスクは80GBとしておく。

f:id:data_sciesotist:20140510150642j:plain
f:id:data_sciesotist:20140510150643j:plain

ゲストOSのインストール

別に特別なことはなく、普通にCentOSをインストール。今回は、ネットワークインストールでminimalを選択した。

f:id:data_sciesotist:20140510150644j:plain
f:id:data_sciesotist:20140510150645j:plain

なお、今回は/optHDFSの領域とする。CDH5ではext4とXFSが推奨されているようだけど、XFSはCentOS6ではブートパーティションで使えないなど、いろいろ面倒だったのでext4にした。

インストール後の初期設定

VirtualBoxのコンソールではいろいろ不便なので、まずはSSHの設定を行って、ホスト側のTeraTermから操作できるようにする。後々複数台の仮想マシン間で分散処理*2をするために、パスワードなしで公開鍵認証接続ができるようにしておく。

次に、こちらも後々HDFSの操作などで不便がないように、SELinuxはオフにしておく。/etc/sysconfig/selinuxファイルを編集する。

 SELINUX=disabled

ファイルを編集する場合、再起動後に有効になるので、適当なタイミングで再起動する。再起動前に、合わせてEPELレポジトリRepoforgeレポジトリを使えるようにし、最新の状態に更新しておく。*3

f:id:data_sciesotist:20140510150646j:plain
f:id:data_sciesotist:20140510150647j:plain

Oracle JDKのインストール

実際にやってみたところ、OpenJDKではCDH5は動作しなかった*4ので、OracleJDKを導入する。CDH5ではJDK7が推奨されているので、そちらを導入する。ちなみに、作業した日は、異常に繋がりが悪く、セッションがブチブチ切れていた。ダウンロード後にちゃんと書いてあるファイルサイズであることを確認する必要がある。
f:id:data_sciesotist:20140510150648j:plain

CDH5のインストール

ここから先は、基本的にはCDH 5 Quick Start Guide-Installing CDH 5 on a Single Linux Node in Pseudo-distributed Modeに書いてある通りにすればよい。というか、それ以上に詳しいことは知らない。

まずは、CDH5のレポジトリを使えるようにする。
f:id:data_sciesotist:20140510150650j:plain

で、ここから先は急にMarkdown形式になる(笑)。別のファイルにまとめていたからだけど。面倒なのでそのままコピペ。

# 参考
http://www.cloudera.com/content/cloudera-content/cloudera-docs/CDH5/latest/CDH5-Quick-Start/cdh5qs_yarn_pseudo.html

# 環境
* CentOS 6.5 minimalインストール
* epel、repoforgeレポジトリ導入
* SSH公開鍵認証

        Filesystem      Size  Used Avail Use% Mounted on
        /dev/sda6        24G  1.7G   21G   8% /
        tmpfs           3.9G     0  3.9G   0% /dev/shm
        /dev/sda1       186M   47M  130M  27% /boot
        /dev/sda2       4.0G  136M  3.7G   4% /home
        /dev/sda5        50G  180M   47G   1% /opt
* system-config-firewallの導入
* TCP 50070番を開けておく

# 一般ユーザーの作成

	# useradd -g users training
	# passwd training
	ユーザー training のパスワードを変更。
	新しいパスワード: training
	よくないパスワード: 辞書の単語に基づいています
	新しいパスワードを再入力してください: training
	passwd: 全ての認証トークンが正しく更新できました。

# JDKのインストール
Oracle版が必要

	# rpm -Uvh jdk-7uXX-linux-x64.rpm
	# alternatives --install /usr/bin/java java /usr/java/latest/jre/bin/java 200000
	# alternatives --install /usr/bin/javaws javaws /usr/java/latest/jre/bin/javaws 200000
	# alternatives --install /usr/bin/javac javac /usr/java/latest/bin/javac 200000
	# alternatives --install /usr/bin/jar jar /usr/java/latest/bin/jar 200000
	# update-alternatives --config java
	# update-alternatives --config javac
	# update-alternatives --config javaws
	# update-alternatives --config jar

# CDH5レポジトリファイルのインストール

	# yum install http://archive.cloudera.com/cdh5/one-click-install/redhat/6/x86_64/cloudera-cdh-5-0.x86_64.rpm
	# rpm --import http://archive.cloudera.com/cdh5/redhat/6/x86_64/cdh/RPM-GPG-KEY-cloudera

# 擬似分散モードでのインストール

	# yum install hadoop-conf-pseudo

# インストール結果・設定ファイルの確認

	# rpm -ql hadoop-conf-pseudo

# /etc/hadoop/conf.pseudo/hdfs-site.xmlの書き換え
今回のインストールでは`/opt`以下にHDFSを作成するため。

	<property>
	   <name>hadoop.tmp.dir</name>
	   <value>/opt/hadoop/hadoop-hdfs/cache/${user.name}</value>
	</property>
	<property>
	   <name>dfs.namenode.name.dir</name>
	   <value>file:///opt/hadoop/hadoop-hdfs/cache/${user.name}/dfs/name</value>
	</property>
	<property>
	   <name>dfs.namenode.checkpoint.dir</name>
	   <value>file:///opt/hadoop/hadoop-hdfs/cache/${user.name}/dfs/namesecondary\
	</value>
	</property>
	<property>
	   <name>dfs.datanode.data.dir</name>
	   <value>file:///opt/hadoop/hadoop-hdfs/cache/${user.name}/dfs/data</value>
	</property>

# HDFSのフォーマット

	# mkdir /opt/hadoop
	# chown hdfs:hdfs /opt/hadoop
	# sudo -u hdfs hdfs namenode -format

# HDFS関連サービスの起動

	# service hadoop-hdfs-datanode start
	# service hadoop-hdfs-namenode start
	# service hadoop-hdfs-secondarynamenode start

# ディレクトリ構成とパーミションの設定

	# sudo -u hdfs hadoop fs -ls -R / # まだ何もない
	# sudo -u hdfs hadoop fs -mkdir -p /tmp/hadoop-yarn/staging/history/done_intermediate
	# sudo -u hdfs hadoop fs -chown -R mapred:mapred /tmp/hadoop-yarn/staging
	# sudo -u hdfs hadoop fs -chmod -R 1777 /tmp
	# sudo -u hdfs hadoop fs -mkdir -p /var/log/hadoop-yarn
	# sudo -u hdfs hadoop fs -chown yarn:mapred /var/log/hadoop-yarn
	# sudo -u hdfs hadoop fs -ls -R /
	drwxrwxrwt   - hdfs supergroup          0 2014-05-10 12:00 /tmp

	drwxrwxrwt   - hdfs supergroup          0 2014-05-10 12:00 /tmp/hadoop-yarn
	drwxrwxrwt   - mapred mapred              0 2014-05-10 12:00 /tmp/hadoop-yarn/staging
	drwxrwxrwt   - mapred mapred              0 2014-05-10 12:00 /tmp/hadoop-yarn/staging/history
	drwxrwxrwt   - mapred mapred              0 2014-05-10 12:00 /tmp/hadoop-yarn/staging/history/done_intermediate
	drwxr-xr-x   - hdfs   supergroup          0 2014-05-10 12:00 /var
	drwxr-xr-x   - hdfs   supergroup          0 2014-05-10 12:00 /var/log
	drwxr-xr-x   - yarn   mapred              0 2014-05-10 12:00 /var/log/hadoop-yarn

# YARNと関連サービスの起動

	# service hadoop-yarn-resourcemanager start
	# service hadoop-yarn-nodemanager start
	# service hadoop-mapreduce-historyserver start

# ユーザー用ディレクトリの作成

	# sudo -u hdfs hadoop fs -mkdir /user/
	# sudo -u hdfs hadoop fs -mkdir /user/training
	# sudo -u hdfs hadoop fs -chown training /user/training

# サンプルアプリケーションの実行(trainingユーザー)

	# su - training
	$ hadoop fs -mkdir input
	$ hadoop fs -put /etc/hadoop/conf/*.xml input
	$ hadoop fs -ls input
	Found 4 items
	-rw-r--r--   1 training supergroup       2133 2014-05-10 12:19 input/core-site.xml
	-rw-r--r--   1 training supergroup       1887 2014-05-10 12:19 input/hdfs-site.xml
	-rw-r--r--   1 training supergroup       1549 2014-05-10 12:19 input/mapred-site.xml
	-rw-r--r--   1 training supergroup       2375 2014-05-10 12:19 input/yarn-site.xml
	$ export HADOOP_MAPRED_HOME=/usr/lib/hadoop-mapreduce
	$ hadoop jar /usr/lib/hadoop-mapreduce/hadoop-mapreduce-examples.jar grep input output23 'dfs[a-z.]+'

# ブラウザで進捗の確認
50070番ポートを開けたうえで、`http://$HADOOP_HOST:50070`にアクセス

# 実行結果の確認

	$ hadoop fs -ls
	Found 2 items
	drwxr-xr-x   - training supergroup          0 2014-05-10 12:19 input
	drwxr-xr-x   - training supergroup          0 2014-05-10 12:24 output23
	$ hadoop fs -cat output23/part-r-00000
	1       dfs.safemode.min.datanodes
	1       dfs.safemode.extension
	1       dfs.replication
	1       dfs.namenode.name.dir
	1       dfs.namenode.checkpoint.dir
	1       dfs.datanode.data.dir

# Sparkのインストール

	# yum install spark-core spark-master spark-worker spark-python
	# vi /etc/spark/conf/spark-env.sh

ポート18080(Master)と18081(Worker)を開けておく。

# Sparkの起動

	# service spark-master start
	# service spark-worker start

# Sparkシェルの起動

	# su - training
	$ spark-shell

`http://192.168.0.181:18080/`と`http://192.168.0.181:18081/`でMasterとWorkerの動作を確認する。

# サンプルの実行

	> val textFile = sc.textFile("input/spark.txt")
	> textFile.count()
	> val linesWithSpark = textFile.filter(line => line.contains("Spark"))

f:id:data_sciesotist:20140510225451j:plain
f:id:data_sciesotist:20140510225204j:plain
f:id:data_sciesotist:20140510225221j:plain
f:id:data_sciesotist:20140510225227j:plain
おしまい。

*1:Cloudera's Distribution including Hadoopって言う正式名称は最近は使わない?

*2:もちろん、実際には1台のホスト内なのだけど。

*3:Repoforgeレポジトリは通常enabled=0で。

*4:詳しい仕組みは知らない。