Cloudera Manager + EC2 で Mahout を5分（ぐらい）で動かす

##ゴール

HadoopやMahoutはインストールから動く状態まで持っていくのに、慣れないうちは結構時間かかってしまいます。

しかし、これをさくっと終わらせることができます。
<br/>

そう、Cloudera Managerならね。
<br/>

さらにこれにEC2を組み合わせると、さらにさくっと終わらせることができます。
<br/>

そんな訳で、今回はClouderaManager + EC2の組み合わせを利用して、まっさらな状態から

 - Hadoopのインストール
 - クラスタ構築
 - Mahoutのインストール
 - デモ実行

までを5分（ぐらい）で終わらる手順を示したいと思います。

※注
 - サーバがEC2でなくても、大体似た感じでいけると思います
 - ほんとに5分（ぐらい）で終わるかどうかは、回線速度やサーバスペックによります。信じちゃいけません。
<br/>

##前提としている知識

- EC2に関する基本的な知識
- Hadoopに関する基本的な知識
- sshといった基本的なUNIXコマンドに関する知識
<br/>

##今回使ったもの

- Cloudra Manager 4.8（CDH4.5）
- Server(Cloudra Manager用)
 - AWS EC2 m1.large EBS 20GB
 - OS：Ubuntu 12.04
- Server(Hadoopクラスタ用)
 - AWS EC2 m1.medium x2台
 - OS：Ubuntu 12.04

今回は著者の財布の事情で、ClouderaManagerとCDH（Hadoopクラスタ）それぞれ推奨インスタンスタイプの中で、最も低スペックなインスタンスタイプを選択しています。

また、とりあえず動かすだけが目的なので、EBSも20GBしか割り当てていません。

いずれも用途に合わせて適切に選択してください。
<br/>

##手順1. ClouderaManager 用のインスタンスを用意する

最初にClouderaManagerを動かすインスタンスを用意します。

###ClouderaManager用SecurityGroup作成

まず、AWS マネージメントコンソール上でSecurityGroupを以下の内容で作成します。

![seburitygroup2.png](https://qiita-image-store.s3.amazonaws.com/0/27278/f1177960-44e3-21d2-fbf3-4e831178daab.png)

- inbound
 - TCP 22, 7180, 7182, 7183, 7432を0.0.0.0/0から許可
 - ICMP の echo Reply を0.0.0.0/0から許可

いずれもリクエスト元が特定できる環境で利用する場合、そのIPに絞りましょう。

\#CloudFomation用意した方がよかったかも、、、
<br/>

### インスタンス作成

マネージメントコンソールからEC2インスタンスを作成します。

前述の以下の構成で作成しています。
- AWS EC2 m1.large EBS 20GB
- OS：Ubuntu 12.04

SecurityGroupは先ほど作成したものを指定します。

こんな感じです。

![instanceconfirm.png](https://qiita-image-store.s3.amazonaws.com/0/27278/cdf369c5-0262-07b2-b2c7-ca8985662cf9.png)

今回はOSにUbuntuを選択していますが、<a href="http://www.cloudera.com/content/cloudera-content/cloudera-docs/CM4Ent/latest/Cloudera-Manager-Installation-Guide/cmig_cm_requirements.html#cmig_topic_4">他にもCentOS等様々なOSで利用可能です。</a>
<br/>

##手順2 Cloudera Mnager をインストールする

<a href="http://www.cloudera.com/content/support/en/downloads.html">ここ</a>からインストーラをダウンロードします。


Cloudera Standard 4

と

Cloudera Enterprise 4

がサイト上にはありますが、現バージョンだとインストール時にどれを入れるのか選ぶので、どちらでも変わりません。（たぶん）

cloudera-manager-installer.bin

がダウンロードできたら、先ほど作成したインスタンス上にアップロードし、以下のようにClouderaManagerをインストールします。

```bash
$chmod 744 cloudera-manager-installer.bin
$sudo ./cloudera-manager-installer.bin
```

インストーラが起動したら、各種ライセンスへの同意が求められるので、同意します。

ポート7180へアクセスしてね的な文言が出れば、ClouderaManagerのインストールは無事完了です。
<br/>

2014/2/17 追記開始
***
ClouderaManagerをhttps経由で接続できるようにするために、以下の手順で鍵を作成します。

```shell-session
$ keytool -validity 180 -keystore cm.key -alias jetty -genkeypair -keyalg RSA
Enter keystore password:
Re-enter new password:
What is your first and last name?
  [Unknown]:
What is the name of your organizational unit?
  [Unknown]:
What is the name of your organization?
  [Unknown]:
What is the name of your City or Locality?
  [Unknown]:
What is the name of your State or Province?
  [Unknown]:
What is the two-letter country code for this unit?
  [Unknown]:
Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
  [no]:  yes

Enter key password for <jetty>
        (RETURN if same as keystore password):
Re-enter new password:

$ sudo mv cm.key /etc/cloudera-scm-server/
$ sudo chown cloudera-scm:cloudera-scm /etc/cloudera-scm-server/cm.key
$ sudo chmod 600 /etc/cloudera-scm-server/cm.key
```

***
2014/2/17 追記終了

##手順3 ClouderaMnagerを設定する

ではさっそく、インストールしたマシンのポート7180へブラウザからアクセスします。

アクセスできない場合はiptablesや、EC2であればSecurityGroupの設定を疑いましょう。

![login.png](https://qiita-image-store.s3.amazonaws.com/0/27278/c9a3211e-4178-7ed9-0937-2ef5a90ee466.png)

上記ログイン画面が表示されたら、以下のIDとパスワードでログインします。

ID : admin
Pass : admin
<br/>

###パスワード変更とエディション選択

ログインに成功したら以下のようにエディションを聞かれます。

![edition.png](https://qiita-image-store.s3.amazonaws.com/0/27278/143260de-56da-283e-6fd6-6df7f7e447d1.png)

ここでエディションを選択する前に、 **先に右上のadminリンクからパスワードを一応変えておきましょう。** 
<br/>

2014/2/17 追記開始
***

パスワードの変更が終了したら、ClouderaManagerをhttps経由で接続できるようにするために、以下の設定を行います。

上部メニュー内の「設定」を選択し、設定画面へ遷移します。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/27278/cb86a384-67a5-efeb-8288-91eff07d8a7e.png)
<br/>

左メニューからセキュリティを選択します。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/27278/3314eba4-b6bf-77c6-7b2c-f0a5a3dc422b.png)
<br/>

以下を設定します

「管理コンソールで TLS 暗号化を使用する」にチェック

「TLS Keystore ファイルのパス」に鍵の配置先を指定。今回の例であれば/etc/cloudera-scm-server/cm.key

「Keystore パスワード」に先ほどの鍵作成時に指定したパスワードを入力

![4.png](https://qiita-image-store.s3.amazonaws.com/0/27278/05c0fffd-f237-eab6-d7ea-ff389f10b7f8.png)

「変更の保存」ボタンを押します

以下の手順でClouderaManagerを再起動します

```shell-session
$ sudo /etc/init.d/cloudera-scm-server restart
```

再起動完了後、管理コンソールにhttpsでポート7183番にアクセスします。

アクセスできない場合は少し待ってから再度アクセスしてください。

***
2014/2/17 追記終了
<br/>

パスワードの変更が完了したら、戻ってエディションを適切に選択します。

とりあえずMahoutを動かすだけであれば無償のStandardで十分ですので、ここではStandardを選択してみます。

そうすると、以下のような画面が表示されます。

![logined.png](https://qiita-image-store.s3.amazonaws.com/0/27278/af009784-30be-07d0-24bd-365736cc5f3d.png)

今回はEC2を利用しているため、この画面が表示されましたが、EC2でない場合は別画面が表示されるはずです。

EC2かどうかはCloudra Managerが勝手に判断してくれます。

既にHadoopクラスタへ参加させたいインスタンスが起動してる場合は、画面中央の「従来の、、、」ボタンをクリックします。

今回はまだインスタンスを作成していないので、画面右下にある「続行」ボタンをクリックします。
<br/>

###「インスタンスの仕様の入力」

![instace.png](https://qiita-image-store.s3.amazonaws.com/0/27278/b9df25ac-9457-2303-c881-215296ea9fd0.png)

Hadoopクラスタに参加させるインスタンスのOS、インスタンタイプ、台数、クラスタ名を入力します。

適宜選択してください。

今回は著者がお小遣い制で財布がアレなので、M1.mediumを2台、Ubuntuで用意します。クラスタ名はデフォルトです。

###「資格情報を入力してください。」

![input_auth.png](https://qiita-image-store.s3.amazonaws.com/0/27278/4b8bba30-682b-1830-ad8e-3a61eb36482d.png)

AWSのアクセスキーと秘密アクセスキーを入力します。

未作成の場合はページ内に記載されている方法で作成してください。
<br/>

「インスタンス認証方法」の欄は、Hadoopクラスタを構成するインスタンスへログインする鍵に関する設定です。

新規作成と、既存の鍵を利用する方法のいずれかが選択できます。今回は新規作成することにします。
<br/>

以上の入力が完了したら右下の「確認」ボタンを押して、各コンポーネントのインストールを開始させます。

後の画面は特に入力する情報はありませんので、ひたらすら次の画面へ進み続けます。

以下の「おめでとうございます！」画面が出たら設定完了です。

![conguratuation.png](https://qiita-image-store.s3.amazonaws.com/0/27278/627e1aa3-b152-5164-3a56-7621f4dde55f.png)
<br/>

##手順4. Hadoopの動作確認

では、問題なくインストールできたか、Hadoopを利用してみます。

先ほどの「おめでとうございます！」画面右下の「続行」ボタンを押すと、以下の画面が表示されます。

![home.png](https://qiita-image-store.s3.amazonaws.com/0/27278/31a10c33-22bf-2845-fecc-3b7e7edfb510.png)

\#なんかエラーたくさん出てますが、ストレージが少なすぎて怒られているだけなので気にしません
<br/>

まず、画面左にある「ステータス」内の「mapreduce1」 のリンクを選択します。

そうすると、遷移した画面左の「MapReduce サマリ」に「JobTracker Web UI」のURLが表示されます。

このURLからJobTrackerのIPが判断できます。

EC2の場合、おそらくここに記載されるURLはPrivateDNSの値になっていると思いますが、リンクのとび先はPublicDNSの値になっています。
<br/>

###JobTrackerにログインしてみる

では、このPublicDNSに対してSSHでログインしてみます。

このとき、鍵は「資格情報を入力してください。」画面でダウンロード or アップロードした鍵を利用します。

今回はClouderaManagerからダウンロードした鍵を利用します。パスワードはありません。

```bash
$chmod 600 .ssh/cm_cloud_hosts_rsa
$ssh -i .ssh/cm_cloud_hosts_rsa ubuntu@PublicDNSの値
```
<br/>

###jobを実行する

無事ログインできたら、HadoopにJobを投げてみましょう。

お約束の円周率計算を試してみます。

```bash
$sudo -u hdfs hadoop jar /usr/lib/hadoop-0.20-mapreduce/hadoop-examples.jar pi 4 1000

〜

Job Finished in 38.23 seconds
Estimated value of Pi is 3.14000000000000000000
```

上記のように、最後に円周率が表示されれば成功です。
<br/>

##手順5. Mahoutのインストール

では次にMahoutをインストールします。

MahoutはCDHがインストールされていれば、パッケージからインストールできます。

しかし、Mahoutはすべてのノードへインストールする必要はありません。

今回の場合であれば、JobTracekerのみで十分です。

JobTracekerへは先ほどSSHでログインしていますので、そのまま下記コマンドでインストールします。

```bash
$sudo apt-get install mahout
```

今回はUbuntuを利用しているのでapt-getでインストールを行いましたが、<a href="http://www.cloudera.com/content/cloudera-content/cloudera-docs/CDH4/latest/CDH4-Installation-Guide/cdh4ig_topic_24_2.html">CentOSの場合はyum、SLESの場合はzypperでインストールできます</a>
<br/>

##手順6. Mahoutの動作確認

無事、mahoutが動くか、<a href="http://gihyo.jp/dev/serial/01/mahout/0005">こちら（ステマ）</a>のK-Meansを一通り実行してみます。

```bash
$mkdir mahout-test
$chmod 777 mahout-test
$cd mahout-test
$wget http://image.gihyo.co.jp/assets/files/dev/serial/01/mahout/0005/gihyo-mahout-kmeans-sample.arff
$sudo -u hdfs mahout arff.vector --input gihyo-mahout-kmeans-sample.arff --output gihyo-mahout-kmeans-sample.vector --dictOut gihyo-mahout-kmeans-sample.dict
$sudo -u hdfs mahout kmeans --input gihyo-mahout-kmeans-sample.vector --output gihyo-kmeans-output --maxIter 3 --numClusters 10 --clusters gihyo-kmeans-null-cluster --clustering -dm org.apache.mahout.common.distance.EuclideanDistanceMeasure
$sudo -u hdfs mahout clusterdump --input gihyo-kmeans-output/clusters-3-final --output gihyo-kmeans-dump.text
$less gihyo-kmeans-dump.text

CL-982{n=85 c=[78.059, 25.435, 85.553] r=[12.353, 15.756, 11.195]}
CL-984{n=95 c=[24.453, 83.432, 26.011] r=[13.750, 10.934, 13.895]}
CL-989{n=82 c=[28.488, 86.683, 75.256] r=[16.418, 7.903, 15.898]}
CL-990{n=136 c=[76.191, 76.331, 23.368] r=[14.351, 14.748, 14.287]}
CL-992{n=74 c=[15.162, 17.486, 63.865] r=[9.854, 11.768, 18.609]}
CL-994{n=116 c=[77.940, 74.741, 73.172] r=[13.315, 12.853, 14.808]}
CL-996{n=159 c=[73.541, 23.943, 32.094] r=[14.628, 14.952, 16.634]}
CL-997{n=85 c=[24.776, 56.459, 75.129] r=[14.978, 9.690, 15.707]}
CL-998{n=66 c=[45.652, 19.106, 81.924] r=[11.790, 10.550, 12.252]}
CL-999{n=102 c=[25.225, 32.461, 23.314] r=[14.708, 15.426, 12.943]}

```

無事、クラスタリングされましたー！

\#動作確認が目的なので、K-Meansのイテレーションの回数は3回に減らしてあります
<br/>

##忘れずにやっておくこと

終わったら、EC2のインスタンスは落としましょう。お金かかるよー

尚、Cloudera ManagerがプロビジョニングしたインスタンスはStopできないので、Terminateで停止（というか廃棄）させます。

##まとめ

このように文章にすると長くなってしまいますが、実際にやってみると、とても簡単にHadoopとMahoutを構築することができます。

ClouderaManager（+ CDH）はとても便利ですね！

このように構築のコストを下げるだけでなく、様々な機能で運用コストも下げてくれます。
<br/>

しかし、いいことばかりではありません。

CDHでインストールできるMahoutはバージョンが少し遅れています。（現在の最新バージョンは0.8、CDHでインストールされたバージョンは0.7）

ここら辺は使い分けですね。
<br/>

明日の担当は、自分が本日担当であることを思い出させてくれた @sudabon さんです！