読者です 読者をやめる 読者になる 読者になる

Hadoop Streamingを動かしてみる

NLP.app Hadoop

NLP.appの課題をやりたいと挙手したので(2週間後なのでテストを挟んでもきっと大丈夫なはず)、Hadoopを動かしてみる。Hadoopはmake installとかやらない感じのようで、shellに設定をちょっと書いてやる(.zshrcとかをいじりたくなければ、conf/hadoop-env.shに書いてもいいらしい)。自分のMacBookだとこんな感じで書いた。小耳に挟んだ研究室の同期の話によると、JavaのバージョンとHadoopのバージョンによっては動かないらしいので、注意が必要。

HADOOP_HOME=/Users/yasuhisa/Downloads/hadoop
export PATH=$HADOOP_HOME/bin:$PATH
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home

最初はword countのプログラム(piの計算でもいいが)らしいので、(HADOOP_HOMEに)inputディレクトリを作っておいて、C++の適当なファイル達を放り込む。で、こうやるとwordカウントのプログラムが走る。簡単すぎてわろた。

/Users/yasuhisa/Downloads/hadoop% hadoop jar hadoop-0.20.2-examples.jar wordcount input output

ただ、これだとJavaからしか使えなくって面白くない。Hadoop Streamingを使うとRubyやPythonからも使えるということなので、RubyからStreamingのやつを使ってみることにする。この辺を参考にしつつ。

まっぱー。ここを変えるとBigramも簡単にできそう。

#!/opt/local/bin/ruby1.9

ARGF.each do |line|
  line.chomp!
  words = line.split(/\s/)
  words.each do |word|
    unless word.empty?
      printf("%s\t1\n", word)
    end
  end
end

りでゅーさー。たばねるだけ。

#!/opt/local/bin/ruby1.9

h = Hash.new
ARGF.each do |line|
  line.chomp!
  array = line.split(/\t/)
  key = array[0]
  value = array[1]
  if h.key?(key)
    value = h[key].to_i + 1
  end
  h.store(key, value)
end

h.each do |key, value|
  puts "#{key}\t#{value}"
  # printf("%s\t%d\n", key, value)
end

で、あとは走らせるだけ。StreamingならRubyでもC++でもなんでもいいやんなー、ということが分かる。

/Users/yasuhisa/Downloads/hadoop% hadoop jar contrib/streaming/hadoop-0.20.2-streaming.jar -input input -output word_count_file -mapper "ruby /Users/yasuhisa/ruby/maper.rb" -reducer "ruby /Users/yasuhisa/ruby/reducer.rb"

てら簡単。注意すべきこととしては

  • outputのディレクトリが存在しているとなんか怒られる
    • 毎回消すの面倒なんですが。。。どうにかすれば怒られないのかな
  • mapperとreducerのパスはフルパスで書かないと怒られた

という付近。今は一台のマシン(自分のMacBook)で動かしていたので、気が向いたら研究室のHadoop環境で遊ぶことにしよう。