JTPAのギークサロンに参加してきた。今回は参加者がラップトップ持ち込みでコーディングしていくハッカソン形式で、会場入りする前までにHadoopが使える環境を自前で用意しておく必要があった。もうそれだけで、いつものギークサロンよりハードルが高いのだが、当日は15人ほどのギークたち(中には3日前にベイエリアに来たばかりという学生もいた)が集まって、おのおのラップトップとにらめっこしながらHadoopと戯れていた。
1月13日(金)にPalo Altoで行われた今回のギークサロンをホストしてくださった山中仁氏が、EC2上にHadoopクラスタを構築する方法を、参加者向けの資料としてWeb上に準備してくださり、「Hadoop=未知の領域」だった自分でもすんなりHadoopクラスタを組むことができた。だが残念なことに、この資料自体がEC2上に一時的に立てたサーバーに置かれており情報が恒久的には残らないとのこと(山中氏談)なので、山中氏に一部転載の許可をいただき、自分なりの咀嚼も含めてEC2上にHadoopクラスタを構築する手順を書き留めておくことにした。
概要
Hadoopは並列分散処理を行うための仕組みなので、当然のことながら複数台のマシンを用意する必要がある。自前で物理的なマシンを並べたり、ローカルに仮想マシンを並べたりすることも可能だが、手っ取り早くHadoopを動かすのであれば、Amazon EC2を使うのが時間的にも金銭的にも手軽である。
大まかな手順としては、まずHadoopをコントロールするためのLinuxマシンをEC2上に用意する。そこにHadoopとEC2 API Toolsをインストールして、Hadoopを利用するための環境をセットアップする。計算処理を行うためのHadoopクラスタを立ち上げ、処理用の入力データをアタッチして、メインとなる処理を実行する。最後に処理結果の出力データを抽出する。
Amazon EC2へのサインアップ
なによりも先に、AWS (Amazon Web Services)、およびEC2 (Elastic Compute Cloud)が使えなければならないので、AWSのアカウントを持っていない場合は、以下のサイトを参考にしてサインアップしよう。
AWSにサインアップしたら(既にAWSアカウントを持っている場合も同じ)、AWSのホームページの右上にあるMy Account / ConsoleからAWS Management Consoleをクリックする。
EC2上でLinuxマシンを起動
管理コンソールが開いたらEC2のタブを選択する。左側のNavigationメニューにあるRegionは[US East]にしておく(インスタンス費が一番安いので)。今回AWSにサインアップしたばかりの人は、無料なので気にすることはないだろう。
次にEC2上でクライアントとして起動させるLinuxのマシンイメージ(AMI)を選択する。Linuxのディストリビューションは好みもあるだろうが、ここではUbuntu 10.10の公開AMIリストからEBS上でブートできる64ビットマシンを使うことにする。なお、Ubuntuの他のバージョンの公開AMIリストは、EC2スターターズガイドから辿ることができる。US EastリージョンでEBSブータブルな64ビットマシンのAMIを探すと、ami-cf33fea6
というAMIが見つかる。後ほど検索に使うのでイメージIDをメモしておく。
管理コンソールに戻り、Regionが[US East]になっていることを確認して、EC2 Dashboardに表示されている[Launch Instance]ボタンをクリックする。
[Launch Classic Wizard]を選択して、[Continue]ボタンをクリックする。
[Community AMIs]タブを選択して、上部の検索フォームに先ほどメモしておいたami-cf33fea6
を入力すると、UbuntuのAMIが見つかるので[Select]ボタンをクリックする。
インスタンスの種類は一番下のスペックでも十分なのでMicroインスタンスを選択。Availability Zoneは[us-east-1c]を選んで、[Continue]ボタンをクリックする。
このページはデフォルトのまま[Continue]ボタンをクリック。
このページも基本デフォルトのままでもいいが、他にもEC2のインスタンスを立ち上げている場合は、EC2 Dashboardでインスタンスを見つけやすいように名前を付けておくといいだろう。
UbuntuにSSHでアクセスする際に使用するRSA秘密鍵/公開鍵の鍵ペアを新たに作成する。鍵ペアの名前をここではec2-hadoop
として、[Create & Download your Kay Pair]をクリックすると、ec2-hadoop.pem
というファイルがダウンロードされる。SSHでアクセスする際に必要になる秘密鍵なので、うっかり消さないように要注意(失くしたらまた新しい鍵ペアを作らなければならない)。
UbuntuにSSHでアクセスできるようにするためファイアウォールに穴を開ける。[Create a new Security Group]のラジオボタンを選んで、Group NameとGroup Descriptionはわかりやすいようなものを入力しておく。[Create a new Rule]でSSHを選択して[Add Rule]ボタンをクリックする。右側の一覧にSSHが追加されたことを確認したら[Continue]ボタンをクリックする。
最後にウィザードで設定した内容の確認ページが表示され、[Launch]ボタンをクリックすると、EC2上にUbuntuのインスタンスが作成・起動される。
EC2の管理コンソールで左側のNavigationメニューからInstancesを選ぶと、インスタンスの起動状態が確認できる。
最後に必須ではないが、もし今回AWSにサインアップしたばかりであれば、Elastic IPが1つ無料で使えるらしいので、インスタンスにグローバルIPを割り当てておくといいだろう。NavigationメニューからElastic IPsを選び、[Allocate New Address]ボタンをクリックすると、さらにダイアログが出てくるので[Yes, Allocate]ボタンをクリックする。
追加されたElastic IPを右クリックすると、[Release]と[Associate]というプルダウンが出てくるので、[Associate]をクリック。Elastice IPを割り当てるインスタンスに、先ほど起動させたhadoop-client
を選択して[Yes, Allocate]ボタンをクリックする。
Elastic IPを使わない場合は、インスタンス起動時に割り当てられるパブリックDNS名でアクセスすることになる。NavigationメニューのInstancesからhadoop-client
のインスタンスを選択して、画面下部に表示される詳細情報にあるPublic DNSをメモしておこう。Elastic IPを使えばインスタンスを再起動しても同じIPアドレスでアクセスできるが、パブリックDNSはインスタンスが起動するたびにコロコロ変わる。短時間で遊ぶ分にはパブリックDNSでも十分だろう。
えらくスペースを割いてしまったが、ここまではHadoopはまったく関係ない。EC2上にLinuxマシンを立ち上げたに過ぎない。
HadoopとEC2 API Toolsのインストール
EC2をセットアップする過程でダウンロードしたSSH用の秘密鍵を使って、UbuntuのインスタンスにSSHでログインして、Hadoopに必要なソフトをインストールしていく。WindowsならばTeraTermやPuTTYを使う。Linux/Macならばターミナルからアクセスする。
ダウンロードした秘密鍵(ec2-hadoop.pem
)は、~/.ssh
ディレクトリに移動してパーミッションを600
に変更する。ファイル名も秘密鍵だとわかるようにid_rsa.ec2-hadoop
に変更しておく。
local$ mv ~/Downloads/ec2-hadoop.pem ~/.ssh/id_rsa.ec2-hadoop local$ chmod 600 ~/.ssh/id_rsa.ec2-hadoop
インスタンスにElastic IPを割り当てた場合はIPアドレスを、Elastic IPを使っていない場合はパブリックDNSを、接続先のホストとして指定することになる。Ubuntuコミュニティが提供しているAMIには予めubuntu
というユーザーが作られているので、このアカウントを使ってログインする。sshで指定するオプションが非常に長くなるので、~/.bashrc
あたりにエイリアスを書いおこう。
export EC2_HADOOP_HOST="ec2-50-17-70-166.compute-1.amazonaws.com" export EC2_HADOOP_KEY=~/.ssh/id_rsa.ec2-hadoop alias ec2hadoop="ssh -i $EC2_HADOOP_KEY ubuntu@$EC2_HADOOP_HOST"
これでec2hadoop
とタイプするだけで、Ubuntuにログインできるようになる。
local$ . ~/.bashrc local$ ec2hadoop The authenticity of host 'ec2-50-17-70-166.compute-1.amazonaws.com (50.17.70.166)' can't be established. RSA key fingerprint is 66:65:ef:40:2a:49:67:e2:dd:4e:42:d3:00:a2:f4:ad. Are you sure you want to continue connecting (yes/no)? yes ubuntu$
まずはHadoopとEC2 API Toolsを動作させるためにJDKをインストールする。
ubuntu$ sudo apt-add-repository "deb http://archive.canonical.com/ lucid partner" ubuntu$ sudo apt-get update ubuntu$ sudo apt-get install sun-java6-jdk
次にEC2 API Toolsをインストールする。
ubuntu$ sudo apt-add-repository ppa:awstools-dev/awstools ubuntu$ sudo apt-get update ubuntu$ sudo apt-get install ec2-api-tools
最後にHadoopをダウンロードして、/usr/local
に展開する。
ubuntu$ wget www.gtlib.gatech.edu/pub/apache/hadoop/core/hadoop-1.0.0/hadoop-1.0.0.tar.gz ubuntu$ tar -zxf hadoop-1.0.0.tar.gz ubuntu$ sudo mv hadoop-1.0.0 /usr/local/hadoop
UbuntuにHadoop、EC2 API Toolsをインストールする方法は、EC2スターターズガイドでも紹介されているので参考に。
EC2-Hadoopクラスタの設定
HadoopにはデフォルトでEC2上にクラスタを構築する機能が搭載されている。これを利用するために必要なセットアップを行っていく。
まず、HadoopがEC2にアクセスするためのX.509証明書と秘密鍵を、AWSの管理コンソールからダウンロードする。AWSの管理コンソールの右上にあるアカウントメニューから[Security Credentials]をクリックする。
Access Credentialsの[X.509 Certificates]タブを選択して[Create a new Certificate]をクリックする。
[Download Private Key File]ボタンと[Download X.509 Certificate]ボタンをそれぞれクリックすると、秘密鍵とX.509証明書がダウンロードされる。ダウンロードが完了したら[Close]ボタンをクリックする。
ダウンロードしたX.509証明書と秘密鍵を、EC2上のUbuntuにscpでアップロードする。Windowsの場合は、WinSCPを使うといいだろう。
local$ cd ~/Downloads local$ mv pk-XXXXXXXXXXXXXXXXXXXXXXXXXXXX.pem pk.pem local$ mv cert-XXXXXXXXXXXXXXXXXXXXXXXXXXXX.pem cert.pem local$ scp -i $EC2_HADOOP_KEY ~/Downloads/{pk,cert}.pem \ ubuntu@$EC2_HADOOP_HOST:/home/ubuntu
なお、Ubuntuの環境はHadoopの利用専用で、かつ自分以外に他のユーザーが使わないという前提で設定している。もし、既存の共用Linux環境で設定する場合は、秘密鍵の保存ディレクトリやパーミッションを適切に設定するように。
Ubuntuに再度SSHでログインして、HadoopとEC2 API Toolsを使う上で必要になる環境変数を~/.profile
に追記していく。
local$ ec2hadoop ubuntu$ vi .profile
# 以下のスクリプトを追記する export JAVA_HOME="/usr/lib/jvm/java-6-sun" export EC2_HOME="/usr/lib/ec2-api-tools" export HADOOP_HOME="/usr/local/hadoop" export PATH="$PATH:$EC2_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/src/contrib/ec2/bin" export EC2_PRIVATE_KEY="$HOME/pk.pem" export EC2_CERT="$HOME/cert.pem"
~/.profile
を読み込んで、ec2-describe-instances
コマンドが実行できることを確認する。
ubuntu$ . .profile ubuntu$ ec2-describe-instances
UbuntuがHadoopクラスタとの通信するために使うアクセスキーを、id_rsa-gsg-keypair
というファイルに保存する。id_rsa-gsg-keypair
ファイルは$EC2_PRIVATE_KEY
が保存されているディレクトリと同じにする必要がある。また、パーミッションは600
に設定する。
ubuntu$ ec2-add-keypair gsg-keypair | tail -n +2 > id_rsa-gsg-keypair ubuntu$ chmod 600 id_rsa-gsg-keypair
最後にhadoop-ec2-env.sh
を編集して、HadoopのEC2クラスタ用の環境変数を設定する。
ubuntu$ vi $HADOOP_HOME/src/contrib/ec2/bin/hadoop-ec2-env.sh
設定が必要な箇所は18~25行目にある3つの変数。
- AWS_ACCOUNT_ID
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
AWS_ACCOUNT_ID
は、AWSのSecurity Credentialsページの右上、Account Numberに表示されている12桁の数字(設定時はハイフンを取り除く)。
次にアクセスキーを作成する。同じくSecurity CredentialsページにあるAccess Credentialsの[Access Keys]タブを選択して[Create a new Access Key]をクリックする。
AWS_ACCESS_KEY_ID
には、作成したアクセスキーの[Access Key ID]欄の文字列を指定する。AWS_SECRET_ACCESS_KEY
には[Show]をクリックしたときに表示される文字列を設定する。
hadoop-ec2-env.sh
を保存したら、いよいよHadoopのクラスタを立ち上げる。
ubuntu$ hadoop-ec2 launch-cluster hadoop-cluster 2
3番目の引数hadoop-cluster
はクラスタ群に付ける名前なので任意で構わない。最後の引数では起動するスレーブクラスタの数(今回は2台)を指定している。クラスタの起動にはかなり時間がかかるので、コーヒーでも飲みながら待つこととしよう。
これでHadoopを使うための準備は完了である。EC2をセットアップするところから説明してきているので非常に面倒な気もするが、物理マシンや仮想マシンを自前で用意するよりもずっと楽なはず。
クラスタの起動が完了したら、Hadoopのマスタークラスタにログインして、試しにサンプルの円周率計算ソフトを実行してみよう。
ubuntu$ hadoop-ec2 login hadoop-cluster cluster# hadoop jar $HADOOP_HOME/hadoop-0.19.0-examples.jar pi 10 10000000 Number of Maps = 10 Samples per Map = 10000000 Wrote input for Map #0 Wrote input for Map #1 Wrote input for Map #2 Wrote input for Map #3 Wrote input for Map #4 Wrote input for Map #5 Wrote input for Map #6 Wrote input for Map #7 Wrote input for Map #8 Wrote input for Map #9 Starting Job 12/01/19 21:41:34 INFO mapred.FileInputFormat: Total input paths to process : 10 12/01/19 21:41:35 INFO mapred.JobClient: Running job: job_201201192136_0001 12/01/19 21:41:36 INFO mapred.JobClient: map 0% reduce 0% 12/01/19 21:41:48 INFO mapred.JobClient: map 10% reduce 0% 12/01/19 21:41:53 INFO mapred.JobClient: map 20% reduce 0% 12/01/19 21:42:00 INFO mapred.JobClient: map 30% reduce 0% 12/01/19 21:42:01 INFO mapred.JobClient: map 40% reduce 0% 12/01/19 21:42:03 INFO mapred.JobClient: map 50% reduce 0% 12/01/19 21:42:04 INFO mapred.JobClient: map 60% reduce 0% 12/01/19 21:42:09 INFO mapred.JobClient: map 70% reduce 0% 12/01/19 21:42:11 INFO mapred.JobClient: map 80% reduce 0% 12/01/19 21:42:14 INFO mapred.JobClient: map 90% reduce 6% 12/01/19 21:42:17 INFO mapred.JobClient: map 100% reduce 20% 12/01/19 21:42:22 INFO mapred.JobClient: map 100% reduce 26% 12/01/19 21:42:23 INFO mapred.JobClient: map 100% reduce 100% 12/01/19 21:42:24 INFO mapred.JobClient: Job complete: job_201201192136_0001 12/01/19 21:42:24 INFO mapred.JobClient: Counters: 16 12/01/19 21:42:24 INFO mapred.JobClient: File Systems 12/01/19 21:42:24 INFO mapred.JobClient: HDFS bytes read=1180 12/01/19 21:42:24 INFO mapred.JobClient: HDFS bytes written=255 12/01/19 21:42:24 INFO mapred.JobClient: Local bytes read=366 12/01/19 21:42:24 INFO mapred.JobClient: Local bytes written=1066 12/01/19 21:42:24 INFO mapred.JobClient: Job Counters 12/01/19 21:42:24 INFO mapred.JobClient: Launched reduce tasks=1 12/01/19 21:42:24 INFO mapred.JobClient: Launched map tasks=10 12/01/19 21:42:24 INFO mapred.JobClient: Data-local map tasks=10 12/01/19 21:42:24 INFO mapred.JobClient: Map-Reduce Framework 12/01/19 21:42:24 INFO mapred.JobClient: Reduce input groups=2 12/01/19 21:42:24 INFO mapred.JobClient: Combine output records=0 12/01/19 21:42:24 INFO mapred.JobClient: Map input records=10 12/01/19 21:42:24 INFO mapred.JobClient: Reduce output records=0 12/01/19 21:42:24 INFO mapred.JobClient: Map output bytes=320 12/01/19 21:42:24 INFO mapred.JobClient: Map input bytes=240 12/01/19 21:42:24 INFO mapred.JobClient: Combine input records=0 12/01/19 21:42:24 INFO mapred.JobClient: Map output records=20 12/01/19 21:42:24 INFO mapred.JobClient: Reduce input records=20 Job Finished in 50.49 seconds Estimated value of PI is 3.14146444
3.141
までしか計算合ってないが…とりあえず動いていることは確認できた。
立ち上げたクラスタをそのまま放置してしまうとEC2で課金されてしまうので、不要になったらクラスタを落としておこう。自分はギークサロンの前日に準備だけして当日まで放置しておいたら、HadoopのクラスタがLinuxのSmallインスタンスとして起動することもあり(マスタークラスタ1台とスレーブクラスタ2台の計3台分)、一晩で$6くらい課金されてしまったorz
hadoop-ec2 terminate-cluster hadoop-cluster
参考サイト
- Running Hadoop on Amazon EC2 – Hadoop Wiki
- Hadoop Tutorial Module4: MapReduce – Yahoo! Developer Network
- blogeyeの実装に学ぶ、Amazon EC2/S3でのHadoop活用術 – CodeZine
- Amazon EC2/S3を使ってみた – まとめ (Amazon Web Services関連エントリ目次) – RX-7乗りの適当な日々
後編に続く
3 コメント