Raspberry Pi 2 x 4台でHadoopの完全分散モードを動作させる 前編

hadoop_cluster-1

前回「完全分散モードでちょっと手こずっています」という終わり方をしてしまいましたが、その後参考になりそうなサイトが見つかったので、それをベースに何とか完全分散モードの動作確認までたどり着きました。

上記の内容をベースに、省略されていたり足りないところを補足しながら進めていきます。それから、補助的に以下のサイトも参考にさせていただいています。

なお、今回はとりあえず動かすことを目的としているので、余分な手順が含まれている可能性があります。予めご了承ください。

ではでは、4台のRaspberry Pi 2にRaspbianをインストールして、初回起動したところからスタートします。

。。。この検証のために新たにRaspberry Pi 2を2台買い足しましたともさ。。。

この4台は、

  • クライアント(Hadoopにアプリを投入するもの)
  • クラスタのマスタ
  • クラスタのスレーブその1
  • クラスタのスレーブその2

の役割を与えるつもりで用意したのですが、動作確認だけなら3台で大丈夫です。クライアントの操作はマスタ上でやってしまえばよいので。実際、今回の完全分散モード構築では、クライアント用マシンは何もしていません。ただ、個人的な都合で、今後HadoopのYARN上でSparkを動かすときにクライアントからクラスタにアプリを投入させるようにしたいので、今回一緒に準備してしまっています。

 

以下ではコマンド実行時の表記が、例えば

pi > $ sudo raspi-config

のようになっているときは、ユーザ”pi”のシェルでコマンドを実行していると解釈してください。

なぜこんなことをわざわざ書くかというと、Hadoopの環境構築が進んでいくと、どのユーザで何を実行すればよいのかが、次第にワケがわからなくなってくるからです。

では、さっそく。

Raspberry Piの基本設定

4台すべてのRaspberry Piで実行します。

Terminalを立ち上げて、

pi > $ sudo raspi-config
# 3 Boot Options -> B1 Console
# 4 Internationalisatoin Options -> I2 Change Timezone -> Asia -> Tokyo
# rapi-configの終了時にrebootを実行し、piユーザで再度ログインして以下を実行
pi > $ sudo apt-get update
pi > $ sudo apt-get install vim

 やっていることは、デスクトップの自動起動をやめること(不要なので)、タイムゾーンを合わせること、それから自分にとって使いやすいエディタ(vim)を入れているだけです。エディタは他に使い慣れたものがあるなら、いれなくて大丈夫です。

ホスト名と固定IPアドレスの設定

4台すべてのRaspberry Piで実行します。

ホスト名の変更と有線LANの固定IPアドレスの設定を行います。初期状態だとすべてホスト名がraspberrypiで区別がつきませんし、DHCPでIPアドレスが毎回変わるととても不便なので。

ここでは4台のRaspberry Piを以下のように設定します。

  • ホスト名:client00       IP:192.168.24.100
  • ホスト名:master01    IP:192.168.24.110
  • ホスト名:slave01        IP:192.168.24.120
  • ホスト名:slave02        IP:192.168.24.121

例えば一番上のように設定する場合は、以下の作業を行います。

pi > $ sudo vim /etc/hostname
# "raspberrypi"を"client00"に変更
pi > $ sudo vim /etc/hosts
# "raspberrypi"を"client00"に変更
pi > $ sudo vim /etc/network/interfaces
# 以下のように編集

# iface eth0 inet manual
iface eth0 inet static
address 192.168.24.100
netmask 255.255.255.0
gateway 192.168.24.1

pi > $ sudo reboot

 再起動が完了したら、普段使いの開発用PCのターミナル等で

$ ssh pi@192.168.24.100

でログイン可能かどうか確認し、ログイン先で

pi@client00 ~ $

 のように表示されていれば、ホスト名の変更まで完了しているのでOKです。

ここまでの作業は個別のRaspberry Piでやらなくちゃいけないので大変ですが、ここまでやれば以後はメインの開発用PCからSSHログインで作業できるのでラクです。

ユーザとグループの作成

4台すべてのRaspberry Piで実行します。

以下のようにして、Hadoop用のユーザとグループを作成します。

pi > $ sudo groupadd hadoop
pi > $ sudo useradd -m -g hadoop -G users hdfs
pi > $ sudo useradd -m -g hadoop -G users yarn
pi > $ sudo useradd -m -g hadoop -G users mapred
pi > $ sudo useradd -m -g hadoop -G users spark
pi > $ sudo useradd -m -g hadoop -G users storm
pi > $ sudo passwd hdfs
pi > $ sudo passwd yarn
pi > $ sudo passwd mapred
pi > $ sudo passwd spark
pi > $ sudo passwd storm

 useraddコマンドは、”-m”オプションで同時にホームフォルダも作るように指定しています(ちなみに、CentOSだとこのオプションしでも勝手に作成してくれます)。また、”-g”オプションでプライマリグループ、”-G”オプションでサブグループを指定しています。”users”グループはデフォルトで存在しているハズなので、改めて作る必要はないです。パスワードは、適当に決めてください。

ユーザ”spark”と”storm”はHadoopを動かしたいだけなら不要です。ここでは、今後SparkとStormも触る可能性があるので、ついでに作っておきました。

ネットワークの設定

4台すべてのRaspberry Piで実行します。

ホスト名からIPアドレスを参照できるように、”/etc/hosts”を編集します。

pi > $ sudo vim /etc/hosts

127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters

#127.0.1.1      master01
192.168.24.100  client00
192.168.24.110  master01
192.168.24.120  slave01
192.168.24.121  slave02

 元々は”127.0.0.1″と新しく設定したホスト名が紐づくように記述されていますが、このままだと後でDataNodeがNameNodeに接続できなくなってしまうので、コメントアウトしておきます。

本当はここでIPv6も無効にする方がよいのかもしれませんが、とりあえずこのまま進めます。

 SSHの設定

ホスト名:master01のRaspberry Piのみで実行します(クライアント名:client00の方ではないので注意)。

クラスタのマスタとなるマシンが、パスフレーズの入力なしで他のRaspberry Pi(自分自身を含む)にアクセスできるように、SSHの公開鍵を他のマシンにコピーします。

pi > $ ssh-keygen
pi > $ ssh-copy-id pi@client00
pi > $ ssh-copy-id pi@master01
pi > $ ssh-copy-id pi@slave01
pi > $ ssh-copy-id pi@slave02

pi > $ su -l hdfs
hdfs > $ ssh-keygen
hdfs > $ ssh-copy-id hdfs@client00
hdfs > $ ssh-copy-id hdfs@master01
hdfs > $ ssh-copy-id hdfs@slave01
hdfs > $ ssh-copy-id hdfs@slave02
hdfs > $ exit

pi > $ su -l yarn
yarn > $ ssh-keygen
yarn > $ ssh-copy-id yarn@client00
yarn > $ ssh-copy-id yarn@master01
yarn > $ ssh-copy-id yarn@slave01
yarn > $ ssh-copy-id yarn@slave02
yarn > $ exit

pi > $ su -l mapred
mapred > $ ssh-keygen
mapred > $ ssh-copy-id mapred@client00
mapred > $ ssh-copy-id mapred@master01
mapred > $ ssh-copy-id mapred@slave01
mapred > $ ssh-copy-id mapred@slave02
mapred > $ exit

pi > $ su -l spark
spark > $ ssh-keygen
spark > $ ssh-copy-id spark@client00
spark > $ ssh-copy-id spark@master01
spark > $ ssh-copy-id spark@slave01
spark > $ ssh-copy-id spark@slave02
spark > $ exit

pi > $ su -l storm
storm > $ ssh-keygen
storm > $ ssh-copy-id storm@client00
storm > $ ssh-copy-id storm@master01
storm > $ ssh-copy-id storm@slave01
storm > $ ssh-copy-id storm@slave02
storm > $ exit

suコマンドでユーザを切り替えながら、各ユーザで鍵の作成とコピーを行います。クラスタ構成のためのものなので、基本的にpiユーザの鍵の作成とコピーは不要なのですが、以下ではマスタ用マシンのpiユーザで作成した設定ファイルをクライアントとスレーブにコピーする形で環境を構築していくので、scpコピーの際にいちいちパスフレーズを入力しないで済むように、ついでに設定してしまっています。

suコマンドは一応”-l”オプションをつけて、環境変数を引き継がせないようにしています。元のユーザに戻るときに”exit”ではなく”su”を使うと、どんどん新しいシェルにログインすることになるので注意です。

ssh-keygenコマンドで鍵を作成する際には、特に何も入力せず、Enter連打でOKです。

こちらも、Hadoopを動かすだけならsparkユーザとstormユーザの作業は必要ありません。

 

と、事前準備だけでも結構色々やらなくてはいけなかったので、Hadoop本体の設定は次回とさせてください。

 

最後に、今回のRaspberry Pi 2 x 4台でクラスタを作った際のお役立ちアイテムをご紹介。

一番問題になるのは電源の確保だと思います。基本的にRaspberry Piは1台につき1A以上の電流が必要ですが、個別に充電アダプタを用意しているとあっという間にコンセントが埋まってしまうので、上記を導入しました。各ポートで最大2.4A、6ポート合計で10Aまで供給可能なので、Raspberry Pi 2 x 4台に加え、有線LANのスイッチングハブの電源供給までやっても余裕です。

ちなみに同様の製品だとAnkerのものが有名みたいですが、レビューを読んでいるとポートが壊れたとか発火したとかいうレビューをちらほらあって穏やかではなかったので、今回はサンワ製にしました。昼夜運転するような使い方はさすがに怖いので試していませんが、クラスタのテストに数時間動作させるぐらいなら、今のところ問題なく使えています。

それからLANのハブです。今回は手元にあった小さめの安いものを使いましたが、もっと口が多くて速度も出るものを買っておいた方が、後々も役に立つと思います。

電源ケーブルとLANケーブルとで机の上でカオスになってきたので購入しました。また、上でもちょっと書きましたが、6個口のUSB電源とかを使うと発火とかの心配がないわけではないので、安全確保のため、難燃性プラスチックを採用したこちらの中にUSB電源を突っ込んでおくことにしました。

hadoop_cluster-2

こんな感じになりました。

ちなみに、Raspberry Piを連結しているスペーサーですが、M3のネジだと自分で穴を広げないとギリギリ入らないので、電子部品ショップで実際に穴に合うサイズ(M2.6らしい)のスペーサーを探してきました。ただ、家に帰って実際積み上げてみると微妙に高さが足りなかったので、結局スペーサーを買い足すハメになってしまいました。。。Ethernetコネクタ・USBコネクタの高さギリギリのスペーサーだと、重ね合わせた時に上に来るRaspberry Piの下側の配線(半田付け部分)と接触してしまうので、20mmぐらいのスペーサーがおすすめです。

。。。と、ここまで書いておいて「そう言えば俺、3Dプリンタ持ってたじゃん!」ということに気づいてしまいました。こういうときこそ使いどきだというのに。。。

まあ、既製品ゆえにカッコ良く積み上がっているので、これはこれで良しとします。