SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine(コードジン) DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

Hadoop MapReduceプログラムを解剖する

サンプルコードを使って、MapReduceの構造を理解する

8.ロジックも見ておく

 プログラムの構造を理解したうえで、内部で何をやっているか、さらに詳しく理解しましょう。ロジック部分だけを抜き出してみました。

リスト4_1.ロジック部分のみ(MyMapperの処理部分)
// すべての単語に「1」という数値を付けて、出力する
 String line = value.toString(); // ①
 StringTokenizer tokenizer = new StringTokenizer(line); // ②
  while (tokenizer.hasMoreTokens()) { // ③
   word.set(tokenizer.nextToken()); // ④
   context.write(word, one); // ⑤
}
リスト4_2.ロジック部分のみ(MyReducerの処理部分)
// 同じキーに対して、すべてのバリュー(数値が大量に渡ってくる)を足し算して合計する
 int sum = 0;
 for (IntWritable val : values) { // ⑥
    sum += val.get(); // ⑦
 }
 result.set(sum); // ⑧
 context.write(key, result);  // ⑨
  1. Text型からString型へ変換(StringTokenizerで扱うため)
  2. StringTokenizerを作成(半角スペースで分解するため)
  3. トークを1つずつ取り出し
  4. キーとしてText型にワード、
  5. バリューとしてIntWritableの「1」を出力
  6. I am a programmer.
    I am trying the MapReduce Programming. 	
    ↓
    Mapper
    ↓
    I,1
    am,1
    a,1
    programmer.,1
    I,1
    am,1
    trying,1
    the,1
    MapReduce,1
    Programming.,1
    

     Mapperの処理で、すべての単語が分解され、1がバリューとして並び、シャッフルに渡ります。シャッフルは、キーでソートし、グルーピングしてくれるので、単語同士が集められ、1が並んでいる状態になるわけです。そして、同じキー同士でReducerのreduceが呼ばれます。Reducerにはキーが1つと、値が配列(Iterable)で渡って来ます。

  7. 値を1つずつ取り出し
  8. 合計値に足し
  9. IntWritableにセット
  10. キーと合計値を出力

 これで、Reducer処理は終わりです。

 1を出力しているのに、個数を数えるのではなく、値を足しているのはなぜでしょうか。これは、Combinerと関係があります。

 シャッフル時に、それぞれのMapからシャッフルに渡すレコードがどんどん増えてしまうと、MapReduceはCombinerを呼び出してレコードを減らそうとします。例えば、「the」や「a」のような単語はたくさん出てきます。しかし、Mapper処理がすべて終わらないと、最終的なtheのセットが作れません。待っているとどんどんたまってしまう。そこで、Combineという処理をします。

the,[1,1,1,1]
↓
Combine
↓
the,4

 これが何回か繰り返された後に、シャッフル処理が行われて、最終的なReduceには、数値の入った配列が渡される可能性があるのです。

the,[5,7,2,9]
↓
Reducer
↓
the,23

 この2つの処理は同じなため、ReducerをCombinerとして登録できるわけです。

日本語・・・

 ちょっと蛇足ですが、日本語の処理について言及しておきます。

 このサンプルは、半角スペースで分解するようになっているため、英語などのラテン語系の言葉では有効ですが、DBCS文字(日本語、中国語、韓国語等)の文章ではまったく役に立ちません。形態素解析などを事前にやらないと、同様のことができないことは、DBCS文化で暮らす私たちの試練ですね。

整合性

 もう1つ蛇足ですが、MapReduceジョブの記述は、同じことを何か所にも宣言しなくてはならず、整合性がとれていなければならないため面倒です。ちょっとしたウィザード等を作って、生成したほうが効率的だと感じました(作ればいいのですが)。

9.おさらい

 今回提示したサンプルでは、次のようなことが順次行われています。

  1. name.yone.comに、ジョブがサブミットされます。
  2. インプットとして/user/hdpadmin/inpputにあるファイル群が指定されています。
  3. MyMapper、MyReducerクラスを含んだJARが送信されます。
  4. TextInputFormatクラスによって、<LongWritable, Text>型で、先頭からのバイト数と各行、というレコードに分解され、量によってはSplit(断片)に分けられ、TaskTrackerへ配布されます。
  5. TaskTracker上で、レコードごとに、MyMapperクラスのmapメソッドが呼び出されます。MyMapperやmapメソッドの型定義は、レコードの型と一致していなければなりません。
  6. mapメソッドでは、すべての単語を分解し、キーとしてText型にし、バリューとしてIntWritableの1を付けて出力します。
  7. <単語,1>という組み合わせのレコード群が、ソートされ、グループ化されます。量が多いとCombine処理としてMyReducerが呼ばれることもあります。
  8. キーText、バリューIntWritable型のIterableが、キーごとにMyReducerクラスのreduceメソッドに渡されます。
  9. reduceメソッドでは、渡されたキーと、バリューの合計値(IntWritable)を出力します。
  10. TextFormatOutputによって、/user/yone/outputに出力ファイルが作成されます。

 この中で、1、2、3がMyDriverの処理、6がMyMapperの処理、9がMyReducerの処理です。4、5、7、8、10は、Hadoopフレームワークが処理します。

 いかがだったでしょうか。MapReduceのサンプルを理解することで、よりHadoop MapReduceの理解が深まることを祈ります。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
特集記事連載記事一覧

もっと読む

この記事の著者

米持 幸寿(ヨネモチ ユキヒサ)

日本アイ・ビー・エム公認 ソフトウェア・エバンジェリスト。alphaWorks、developerWorks、インキュベーション系製品、アセットなどのテクノロジーの推進をしつつ、テクノロジー戦略、エバンジェリストチームをリードしている。講演や執筆も多数。主な著書に「かんたんサーバーサイドJava」(翔泳社)、「Webサービス完全解説」(翔泳社)がある。developerWorks Japan ブログ 「米持幸寿のブログ

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/5582 2010/11/30 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー