2011年3月11日金曜日

MapperとReducerをPHPで実装

スズキです。

こちらでアルゴリズムをおさらいしたMapReduceですが、
http://blog.suz-lab.com/2011/03/mapreducestreaming.html
今度は、MapperとReducerをPHPで実装して、実際に実行してみます。

インプットファイルは同じものを利用します。

--------【input.txt】--------
suzuki
sato
tanaka
kobayashi
takahashi
--------

そして、Mapperは下記のように実装しました。

--------【mapper.php】--------
#!/usr/bin/php
<?php
while(!feof(STDIN)) {
  $line = trim(fgets(STDIN));
  $chars = str_split($line);
  foreach($chars as $char) {
    if(preg_match("/[0-9A-Za-z]/", $char)) {
      print($char . "," . "1\n");
    }
  }
}
?>
--------

Mapperを実行すると、下記のようになります。

$ cat input.txt | ./mapper.php
--------
s,1
u,1
z,1
u,1
k,1
i,1
s,1
a,1
t,1
o,1
t,1
a,1
n,1
a,1
k,1
a,1
k,1
o,1
b,1
a,1
y,1
a,1
s,1
h,1
i,1
t,1
a,1
k,1
a,1
h,1
a,1
s,1
h,1
i,1
--------

今回の実装や実行方法ではあまり関係ないのですが、
下記のように、Mapperの結果のソートもしておきます。

$ cat input.txt | ./mapper.php | sort
--------
a,1
a,1
a,1
a,1
a,1
a,1
a,1
a,1
a,1
b,1
h,1
h,1
h,1
i,1
i,1
i,1
k,1
k,1
k,1
k,1
n,1
o,1
o,1
s,1
s,1
s,1
s,1
t,1
t,1
t,1
u,1
u,1
y,1
z,1
--------

この結果に対するReducerは以下のように実装しています。

--------【reducer.php】--------
#!/usr/bin/php
<?php
while(!feof(STDIN)) {
  $line = trim(fgets(STDIN));
  $data = split(",", $line);
  if(preg_match("/[0-9A-Za-z]/", $data[0])) {
    $results[$data[0]] += $data[1];
  }
}
foreach($results as $key => $val) {
  print($key . "," . $val . "\n");
}
?>
--------

実際にReducerまで実行すると以下のようになり、
想定通りの結果となりました。

$ cat name.txt | ./mapper.php | sort | ./reducer.php
--------
a,9
b,1
h,3
i,3
k,4
n,1
o,2
s,4
t,3
u,2
y,1
z,1
--------

次はAWSの"Elastic MapReduce"で実行してみよう。
--------
http://www.suz-lab.com

0 コメント: