前回(http://d.hatena.ne.jp/lopnor/20080831/1220183688)サンプルプログラムを動かすところまで行きましたけど、今回は例のid:naoyaのhadoop streamingでアクセス解析(http://d.hatena.ne.jp/naoya/20080513/1210684438)するのをやってみます。というかなんとかたどり着いたのでまとめを書きます。 *ec2の使い方 id:rx7さんがとても丁寧に説明されている資料(http://d.hatena.ne.jp/rx7/20080528/p1)があるので、そちらを読めば完璧だと思います。僕もこれでec2が使えるようになりました。 *hadoop-ec2の使い方 https://codezine.jp/article/detail/2841がイントロダクション。http://d.hatena.ne.jp/lopnor/20080831/1220183688は超適当なまとめ。あんまり参考にならないかも。http://wiki.apache.org/hadoop/AmazonEC2が本家まとめ。ここまででサンプルプログラムの円周率の計算ができるようになるはず。
- hadoop streamingの説明 http://d.hatena.ne.jp/naoya/20080513/1210684438とhttp://d.hatena.ne.jp/naoya/20080531/1212245982の先にあるpptをぜひ。実はpptまでいって初めていろいろわかったことがあったので、ぜひ。
- ということで、hadoop streaming on ec2 まず、適当にアクセスログを用意します。
[danjou@luisa] $ mkdir ~/tmp/20080911
[danjou@luisa] $ cd ~/tmp/20080911
[danjou@luisa] $ cp /var/log/httpd/access_log .
つぎに、例のperlスクリプトmapper.pl、reducer.plを書きます。
#!/usr/local/bin/perl
# mapper.pl
# originally by id:naoya
use strict;
use warnings;
while (<>) {
chomp;
my @segments = split /\s+/;
printf "%s\t%s\n", $segments[8], 1;
}
#!/usr/bin/perl
# reducer.pl
# originally by id:naoya
use strict;
use warnings;
my %count;
while (<>) {
chomp;
my ($key, $value) = split /\t/;
$count{$key}++;
}
while (my ($key, $value) = each %count) {
printf "%s\t%s\n", $key, $value;
}
ローカルで実行してみましょう
[danjou@luisa] $ cat access_log | perl mapper.pl | perl reducer.pl
200 2740
302 117
404 2
という感じでステータスコードが数えられました。ではこれと同じことをhadoopでやってみましょう。作業ディレクトリは現状こんな感じ。
[danjou@luisa] $ ls
access_log mapper.pl reducer.pl
hadoop-ec2でクラスタを起動する前に、hadoop-ec2-env.shをいじっておきます。下記部分のCOMPRESS=trueのところを、COMPRESS=falseにしておいてください。trueのままでやると、結果ファイルが圧縮されてしまって、元に戻す方法をまだ僕は知らないのです><
# Boot parameters
MAX_MAP_TASKS=2
MAX_REDUCE_TASKS=2
#COMPRESS=true
COMPRESS=false
で、以下のようにして”hadoop-test”という名前のクラスタをワーカー2台で起動。
[danjou@luisa] $ hadoop-ec2 launch-cluster hadoop-test 2
処理に必要なファイルをファイルをマスタマシンに転送します。
[danjou@luisa] $ hadoop-ec2 push hadoop-test access_log
[danjou@luisa] $ hadoop-ec2 push hadoop-test mapper.pl
[danjou@luisa] $ hadoop-ec2 push hadoop-test reducer.pl
1ファイルずつかいっ!という感じですが。いよいよマスタにログイン。
[danjou@luisa] $ hadoop-ec2 login hadoop-test
Logging in to host ec2-00-00-00-00.compute-1.amazonaws.com.
__| __|_ ) Fedora 8
_| ( / 32-bit
___|\___|___|
Welcome to an EC2 Public Image
:-)
Base
--[ see /etc/ec2/release-notes ]--
[root@domU-00-00-00-00-00-00 ~]#
ログインしました。lsしてみると、さっき転送したファイルがありますね。
[root@domU-00-00-00-00-00-00 ~]# ls
access_log ec2-ami-tools-1.3-19974.noarch.rpm hadoop-init mapper.pl reducer.pl
今度は、access_logを分散ファイルシステムに突っ込みます。
[root@domU-00-00-00-00-00-00 ~]# hadoop fs -put access_log access_log
08/09/10 21:46:48 WARN fs.FileSystem: "domU-12-31-38-00-90-C6.compute-1.internal:50001" is a deprecated filesystem name. Use "hdfs://domU-00-00-00-00-00-00.compute-1.internal:50001/" instead.
08/09/10 21:46:49 WARN fs.FileSystem: "domU-00-00-00-00-00-00.compute-1.internal:50001" is a deprecated filesystem name. Use "hdfs://domU-00-00-00-00-00-00.compute-1.internal:50001/" instead.
08/09/10 21:46:49 WARN fs.FileSystem: "domU-00-00-00-00-00-00.compute-1.internal:50001" is a deprecated filesystem name. Use "hdfs://domU-00-00-00-00-00-00.compute-1.internal:50001/" instead.
08/09/10 21:46:49 WARN fs.FileSystem: "domU-00-00-00-00-00-00.compute-1.internal:50001" is a deprecated filesystem name. Use "hdfs://domU-00-00-00-00-00-00.compute-1.internal:50001/" instead.
なんかワーニングが出るんですけど、気にしない!
[root@domU-00-00-00-00-00-00 ~]# hadoop fs -ls 2>/dev/null
Found 1 items
/user/root/access_log <r 3> 506916 2008-09-10 21:46 rw-r--r-- root supergroup
こんな感じで、分散ファイルシステム側にファイルが置けました。では、いざ処理を実行してみましょう。
[root@domU-00-00-00-00-00-00 ~]# hadoop jar \
> /usr/local/hadoop-0.17.0/contrib/streaming/hadoop-0.17.0-streaming.jar \
> -input access_log \
> -output output \
> -mapper 'perl mapper.pl' \
> -reducer 'perl reducer.pl' \
> -file mapper.pl \
> -file reducer.pl
ここで、-fileというオプションが二つ渡されていますが、この指定をしておくと、実行するperlスクリプトが処理時に各ワーカーに転送されます。ですので、各ワーカーにいちいちインストールしなくてもいいので、今回みたいなec2のデフォルトのイメージでポイッと処理することができます。 で、結果を見てみると、
[root@domU-00-00-00-00-00-00 ~]# hadoop fs -ls output 2>/dev/null
Found 2 items
/user/root/output/_logs <dir> 2008-09-10 22:31 rwxr-xr-x root supergroup
/user/root/output/part-00000 <r 3> 23 2008-09-10 22:31 rw-r--r-- root supergroup
[root@domU-00-00-00-00-00-00 ~]# hadoop fs -cat output/part-00000 2>/dev/null
200 2740
302 117
404 2
つうことで、できたーーーーー!!コマンドラインで一瞬だったのにこっちはえらい時間がかかりましたな。ということで、やっぱり大量のデータでないとうまみはないですね。でも大量のデータだとものごっついおいしいです。これでやっと入門編が終わったので、これから実用的な使い方を考えていこうと思います。 あ、最後に
[root@domU-00-00-00-00-00-00 ~]# exit
logout
Connection to ec2-00-00-00-00.compute-1.amazonaws.com closed.
[danjou@luisa] $ hadoop-ec2 terminate-cluster hadoop-test
としてクラスタを終了させておしまいです。