AEMでのmapper・reducerの作り方で気づいたこと


Beautiful evening light, Boeing 747-400….AEMって略し方でいいんでしょうか。 Amazon Elastic Mapreduceのことです。

今アクセス解析に奮闘中。最初はガシガシ解析して、その結果をそのままデータベースに放り込む・・・なんて考えていたら、データベースサーバそのものが落ちちゃって。こりゃあ作戦一から考え直さんとイカン!と思い、いろいろ調べていたら、いろんなところでAWSのmapreduceが使われているとのこと(クックパッド然りモバゲ然り?)。

物は試しと、自分でもmapreduceを触ってみることにしました。ちなみに自分はhadoopだのmapreduceだの全く知らなかったエセエンジニアですわ・・・^^;

Creative Commons License photo credit: wbaiv

mapreduceのmの字も知らないので、mapper・reducerをJavaで書くことが難しかったので、今回はHadoop Streaming でチャレンジ。PHP・C++・RubyやPythonなどでも使える、ということなのですが今回は解析を速く・大量処理なのでメモリを抑えて組みたいので、とっつきやすくかつ速そうな言語を選ばないと・・・と思ったので、Rubyを選択。

わーRuby初めてだー!なんだ?{ }でくくらないで end とかで済ます書き方はー!?if ~ then とかシェルに似てるぞ~?とか変なところで四苦八苦したのですが、一応解析できました。

本題の、AEMでmapper・reducerを作って気づいたことはこんな感じ。

mapper・reducerのキーは日本語でもOK!

今解析している内容として、パラメータの検索語句からのアクセス数を集計しているので、どうしても mapper、reducerの入出力値に日本語が混じります。例えば…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# accesslog (デコード済み)
# GET /foo/bar/test.cgi?word=テスト1&pay=1
# GET /foo/bar/test.cgi?word=テスト2&pay=1
# GET /foo/var/test.cgi?word=テスト1&pay=0
# というものだった場合...

# mapper.rb
ARGF.each do | line |
  line.chomp!
  unless line.empty?
    #..アクセスログ解析..
    puts "#{word}-#{pay}\t1"
  end
end

mapperの出力値は#{word}-#{pay} 1というものでもOKでした。つまり「テスト1-1 (タブ) 1」のような感じで。お金を払っている人が「テスト1」と検索した回数=1みたいな感じで出力したかったんですけれど、これでばっちりでした。もちろん #{word}\t#{pay} 1、つまり「テスト1 (タブ) 1-1」という形でもOKだと思います。

また、日本語というと文字コードの問題も捨てられませんが、少なくともUTF-8、EUCではこのやり方はOKでした。AEMでのキー処理に、文字コードは関係ないのかな?

mapper・reducerの出力は「タブ区切り」で「key value」

自分がいろいろ見てなかったからかもしれません。先人様のスクリプトを参考にさせていただきながらこんな失態を犯してしまうとは情けない。・・・てな感じですが、なんとなくこの部分って重要視されてないような。key,valueの組み合わせでmapper・reducerの入出力をすること、という説明ではあるのですが、てっきりカンマ区切りでもいいのかと思ってスクリプト作ったら、なんだか期待しない結果が得られてしまって。何だろうと思ったら、出力はタブで区切ること、とのことで。

タブに変更したら、ばっちり変換ができました。

AEMでの出力結果は、Mapreduceを作ったインスタンス分だけ結果が出る

Management Consoleでもコマンドラインでも、Mapreduceを設定する際、インスタンス数を決める箇所があります。解析を行うとその数字+1(メインマシンと子マシン)分の part-0000~n までが output に出力されます。

なので、Mapreduceで解析後に何かする場合は、いったんこれをひとまとめにする作業をしなければいけません。

・・・せっかくだから出力結果を統合してくれればよかったのになぁ。

1GBのアクセスログをインスタンス2つと4つで解析した時の時間の違い

2つの場合は41分、4つの場合は35分でした。なんだかインスタンス立ち上げに時間がかかるような気が・・・もったいないけど仕方ないですね。

記事の最後でこんなことを言って申し訳ないのですが、そうは言ってもmapreduce知らない人が組んだ結果です。会社にアドバイスを求められる誰かがいればいいのですが・・・いないので、こうしたらいいのでは的な情報を募集中でございます。

解析って難しいですね。