WindowsでPHP + Hadoop Streamingをやってみようとしたが挫折した

Hadoop Streamingのデバッグをローカルでやりたかったのでcygwin立ち上げてjava –versionって打ってみたら、WindowsのJavaのパスが通ってたので案外動くんじゃないかとやってみた。結論からいうとJavaさえ動けばHadoop自体はそれほどプラットフォームに依存しないのでcygwinでも簡単にHadoopは動いた。デバッグ用にスタンドアロンで実行するだけならcygwinでもいけそうだがHadoop Streamingはちょっと面倒だ。というか挫折した。

一応cygwinでhadoopする技をメモると

hadoopを/usr/localに配置

cd /usr/local
wget http://www.meisei-u.ac.jp/mirror/apache/dist//hadoop/core/hadoop-0.21.0/hadoop-0.21.0.tar.gz
tar zxf hadoop-0.21.0.tar.gz
ln -s hadoop-0.21.0 hadoop
rm -f hadoop-0.21.0.tar.gz

hadoopのcygwin用の設定

vim conf/hadoop-env.sh

export JAVA_HOME=$(cygpath -u $(cygpath -d 'C:\Program Files\Java\jdk1.6.0_21'))

JAVA_PLATFORMにclasspath -cp "$(cygpath -wp $CLASSPATH)"を追加

vim bin/hadoop-config.sh

JAVA_PLATFORM=`CLASSPATH=${CLASSPATH} ${JAVA} -cp "$(cygpath -wp $CLASSPATH)" -Xmx32m ${HADOOP_JAVA_PLATFORM_OPTS} org
.apache.hadoop.util.PlatformName | sed -e "s/ /_/g"`

テスト実行

cd /usr/local/hadoop
mkdir input
cp conf/*.xml input
bin/hadoop jar hadoop-mapred-examples-0.21.0.jar grep input output 'dfs[a-z.]+'

PHPでHadoopStremingしようとする

xamppのphpをムリからに使う

ln -s /cygdrive/c/xampp/php/php.exe /usr/bin/php

wordcountするmap/reduceファイルを作成

~/mapper.php

#!/usr/bin/php
<?php
while ( !feof(STDIN) ) {
   $line = trim(fgets(STDIN));
   foreach ( preg_split('/\s+/', $line) as $word ) {
       if ( $word !== '' ) {
           echo "${word}\t1\n";
       }
   }
}
?>

~/reducer.php

#!/usr/bin/php
<?php
$count = array();
while ( !feof(STDIN) ) {
   $line = trim(fgets(STDIN));
   if ( $line !== '' ) {
       list($key, $value) = preg_split('/\t/', $line);
       $count[$key]++;
   }
}

foreach ( $count as $key => $value ) {
   echo "${key}\t${value}\n";
}
?>

streamingテスト

chmod 0755 ~/*.php
cd /usr/local/hadoop
cat > input/word.txt
orange orange1 apple apple orange1 orange
(Ctrl + D)
cp mapred/contrib/streaming/hadoop-0.21.0-streaming.jar .
bin/hadoop jar hadoop-0.21.0-streaming.jar -input input/word.txt -output output -mapper /home/makoto_kw/mapper.php -reducer /home/makoto_kw/reducer.php

多分、cygwin -> xampp(windows)間のパイプ渡しがうまくいかないので動かない。cygwin側にphpを入れればいいかもしれないがcygwinにはphpのパッケージがないそうなので面倒でやめた。

map/reduceのデバッグならHadoopを使う必要は必ずしもない

冷静に考えるとHadoopStreamingはSTDIN >> map >> STDOUTとSTDIN >> reduce >> STDOUTをするただのf(x)なので入力と期待する出力を用意すればテストケースが簡単にかける。小さいテストデータなら単純にこんな感じで実行できる。

php ./mapper.php < word.txt | sort | php ./reducer.php

というわけでなんだか無駄な時間を費やした勉強にはなった。