R&Dトレンドレポート

第11回 MapReduce処理をやってみよう![実践編2]

この記事を読むのに必要な時間:およそ 5 分

ReduceプログラムをPerlで書く

続けてReduceプログラムですがこちらも標準入力から読み込み,標準出力に出力するというプログラムになります。Sort&Shuffleフェーズでキー順にソートされたデータが渡されます。ネイティブ実装との違いはキーに対してバリューがリスト化されていないことです。Reduceプログラムではその点に注意しましょう。

入力です。

1287144000    迫力
1287144000    香川
1287144000    w
1287144600    利根川
1287144600    利根川
1287144600    キター
1287144600    !

次に出力です。

1287144000    1,迫力
1287144000    1,香川
1287144000    1,w
1287144600    2,利根川
1287144600    1,キター
1287144600    1,!

リスト2 Reduceプログラム(J2chRed.pl)

#!/usr/bin/perl
#
#

use strict;
use Data::Dumper;
use Encode qw(encode decode);
use utf8;

use constant LIMIT=>5;

my $hash;
my $_time;

# 標準入力から読み込み
while (<STDIN>)
{
  chomp;
  my @line = split(/¥t/, $_);

  my $time = $line[0];
  my $word = $line[1];

  $word = decode("utf8",  $word);

  # 最初の1行目のみ
  if ( ! $_time ) 
  {
    # 現在のキーを保持。
    $_time = $time;
  }

# キーである$timeが保持している値と変わった。
  if ( $_time != $time && $_time )
  {
    # バッファにたまったデータを出力する。
    showBuf($hash, LIMIT);

    # バッファを初期化
    $hash = undef;
  }

  # 単語ごとにカウントする。
  if ( ! exists ( $hash->{$word} ) ) 
  {
    $hash->{$word} =  1;  
  }
  else
  {
    $hash->{$word} += 1;
  }

  # 現在のキーを保持する。
  $_time = $time;

}

# 残ったバッファを出力する。
showBuf($hash, LIMIT);


sub showBuf
{
  my ($buf, $limit) = @_; 

  my @arr = sort{ $buf->{$b} <=> $buf->{$a} } keys %$buf;
  my $cnt = 0;
  foreach my $a ( @arr )
  {
    my $value = $buf->{$a};
    # キーバリューを出力する。セパレータはタブ。
    print $_time, "¥t", $value, ",", encode("utf8", $a), "\n";
    last if ( ++$cnt >= $limit ) ; 
  }
}

濃いグレーのハッチング部分ポイントです。

直前のキーを$_timeに保持し,現在のキーと比較することでキーが変わったことを検知します。これはキーがソートされているという前提でのみ動作しますが,Hadoopの場合,Reduce処理に渡されるデータは必ずソートされているという⁠お約束⁠があるため成立します。

動作確認

こちらもMap同様,コマンドラインで動作確認が可能です。ただし入力についてはキーでソートされている前提ですので,以下のようにsortコマンドを間にかませて実行しましょう。

$ cat 2ch_4.txt | perl ./J2chMap.pl | sort | perl ./J2chRed.pl
1287136800      2,メニュー
1287136800      2,実況
1287136800      2,中
1287136800      1,風
1287136800      1,天国
1287137400      4,覇
1287137400      3,ばん
1287137400      3,こん
1287137400      2,夜勤
・
・
$

著者プロフィール

脇本武士(わきもとたけし)

都内中小IT企業(メイサンソフト(株))に所属。某大手自動車会社でのシステム開発,運用を経て,現在は研究開発部署に席をお借りしています。DB周りの保守サポート,ウェブ技術開発を主に手がけてきました。現在は大規模計算フレームワークの活用とKVSに注目しています。普段はOS Xを使用していますが一番よく使うアプリはTerminalです(笑)。

R&Dトレンドレポート(てくらぼ)