集計して検索ワードランキング用のデータを生成することを考える。
次にMapperをrubyで書いてみる。ナス,193032 お弁当,39110 きゅうり,1039001 カレー 豚肉,90123 ズッキーニ,82919 パスタ トマト,1281032 からあげ,72920 じゃがいも キャベツ,402918 トマト,2101302 ナス ピーマン,822924 お弁当 おかず,291038 きゅうり サラダ,224703 豚肉 たまねぎ,90123 ハンバーグ,1038733 たいやき,547291 トマト,392018 お弁当 ウィンナー,39110 にんじん カレー,382027 キャベツ,1039200 なす トマト,2101302 卵 スープ,191938
次にReducerを書く。keyword_counter = Hash.new {|h,k| h[k] = 0 } ARGF.each do |log| log.chomp! keyword, user_id = log.split(',') keywords = keyword.split(' ') keywords.each do |keyword| keyword_counter[keyword] += 1 keyword_counter['__TOTAL__'] += 1 end end keyword_counter.each do |keyword, count| puts "#{keyword}\t#{count}" end
Hadoopで動かす前に動きを試してみる。keyword_counter = Hash.new {|h,k| h[k] = 0 } previous_keyword = nil ARGF.each do |log| log.chomp! keyword, count = log.split(/\t/) if keyword == previous_keyword keyword_counter[keyword] += count.to_i else if previous_keyword puts "#{previous_keyword}\t#{keyword_counter[previous_keyword]}" end previous_keyword = keyword keyword_counter[keyword] += count.to_i end end puts "#{previous_keyword}\t#{keyword_counter[previous_keyword]}"
問題なさそうだ。$ cat keyword.log | ruby keyword_mapper.rb | ruby keyword_reducer.rb
次はHadoopで実行してみる。
うまくいった!$ hadoop fs -put keyword.log $ hadoop jar /usr/local/hadoop/contrib/streaming/hadoop-streaming-1.1.2.jar -D mapred.child.env='PATH=$PATH:/home/hadoop/.rvm/bin' -input input -output output -mapper 'ruby keyword_mapper.rb' -reducer 'ruby keyword_reducer.rb' -file keyword_mapper.rb -file keyword_reducer.rb $ hadoop fs -cat output/part-00000 __TOTAL__ 32 おかず 1 お弁当 3 からあげ 1 きゅうり 2 じゃがいも 1 たいやき 1 たまねぎ 1 なす 1 にんじん 1 ウィンナー 1 カレー 2 キャベツ 2 サラダ 1 スープ 1 ズッキーニ 1 トマト 4 ナス 2 ハンバーグ 1 パスタ 1 ピーマン 1 卵 1 豚肉 2