• Like
PHP と MySQL でカジュアルに MapReduce する
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

PHP と MySQL でカジュアルに MapReduce する

  • 6,548 views
Published

 

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
6,548
On SlideShare
0
From Embeds
0
Number of Embeds
6

Actions

Shares
Downloads
22
Comments
0
Likes
11

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. PHP と MySQL で カジュアルにMapReduce する @yuya_takeyama
  • 2. アジェンダ•MapReduce とは• 自作フレームワークMyMR の紹介
  • 3. お断り (1)ビッグデータの話は ありません
  • 4. お断り (2) 業務ではまだやってません
  • 5. お断り (3) Hadoop 未経験です ※MongoDB でのMapReduce ならやりました
  • 6. MapReduce とは
  • 7. 固有名詞として•Google の大規模データ処理フレームワーク•検索インデックスの作成とかに使われている
  • 8. 普通名詞として•Map/Reduce 関数でデータを 処理するプログラミングモデル• マシンを増やしただけスケール•Hadoop, MongoDB, CouchDB などが主な実装
  • 9. 入力処理の流れ ↓ Map ↓ Reduce ↓ 出力
  • 10. やや厳密な 入力 処理の流れ ↓ Map ↓ Shuffle ↓ Reduceより厳密には ↓もっと複雑らしいです 出力
  • 11. Map•入力データを受け取り• 複数の Key/Value ペアを出力
  • 12. Shuffle•Map による Key/Value を• Key ごとにまとめて出力
  • 13. Reduce•Shuffle による中間データを• 集約して答えを出力
  • 14. 複数の関数の入出力を経て最終的な答えを出力
  • 15. 文章中の単語の数を数える例 (word count)
  • 16. 入力•to be or not to be
  • 17. Map •<"to", 1> •<"be", 1> •<"or", 1> •<"not", 1> •<"to", 1> •<"be", 1>
  • 18. Shuffle •<"be", [1, 1]> •<"not", [1]> •<"or", [1]> •<"to", [1, 1]>
  • 19. Reduce • <"be", 2> • <"not", 1> • <"or", 1> • <"to", 2>
  • 20. MapReduce の利点•Map も Reduce も並列化すればスケールする•関数型っぽい考え方が活きる※ただし, Hadoop や MongoDB の MapReduce の Map と Reduce は 関数型言語のそれとはやや異なる (参照透過でなかったり)• パターンとして共有しやすい※手続き型のバッチ処理と比較して
  • 21. MongoDB について•通常は MapReduce を並列に実行することができない• それでも MapReduce は便利•何故か?
  • 22. スケーラビリティだけじゃない•プログラミングモデルとしての MapReduce にも価値がある• MongoDB で処理が完結•JS で関数ふたつ書くだけ
  • 23. MySQL でもMapReduce したい!!!
  • 24. というわけで作りました
  • 25. MyMR https://github.com/yuya-takeyama/mymr•MySQL を入出力とする• PHP で Map/Reduce を書く• コマンドラインで実行
  • 26. MyMR による処理の流れ•テーブルからレコードを読む•1 行 1 行に Map (PHP) を適用して 中間テーブルへ•MySQL による Shuffle•その結果に Reduce (PHP) を適用して 出力テーブルへ
  • 27. に よ る yM RM 文章中の単語の数を数える例 (word count)
  • 28. use MyMRBuilder; Map/Reduce の定義$builder = new Builder;$builder->setInputTable(root@localhost/db/texts);$builder->setOutputTable(root@localhost/db/word_counts);$builder->setMapper(function ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) {        $emitter->emit($word, 1);    }});$builder->setReducer(function ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum);});return $builder;
  • 29. use MyMRBuilder; Map/Reduce の定義$builder = new Builder;$builder->setInputTable(root@localhost/db/texts);$builder->setOutputTable(root@localhost/db/word_counts);$builder->setMapper(function ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) { 入出力テーブルの指定        $emitter->emit($word, 1);    }});$builder->setReducer(function ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum);});return $builder;
  • 30. use MyMRBuilder; Map/Reduce の定義$builder = new Builder;$builder->setInputTable(root@localhost/db/texts);$builder->setOutputTable(root@localhost/db/word_counts);$builder->setMapper(function ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) {        $emitter->emit($word, 1);    } この辺が Map});$builder->setReducer(function ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum);});return $builder;
  • 31. use MyMRBuilder; Map/Reduce の定義$builder = new Builder;$builder->setInputTable(root@localhost/db/texts);$builder->setOutputTable(root@localhost/db/word_counts);$builder->setMapper(function ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) {        $emitter->emit($word, 1);    }});$builder->setReducer(function ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum); この辺が Reduce});return $builder;
  • 32. 入力•to be or not to be
  • 33. Mapfunction ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) {        $emitter->emit($word, 1);    }}
  • 34. Map レコードを 連想配列として受け取るfunction ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) {        $emitter->emit($word, 1);    }}
  • 35. Mapfunction ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) {        $emitter->emit($word, 1);    }} text カラム内の 文字列をスペースで分割
  • 36. Mapfunction ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) {        $emitter->emit($word, 1);    }} Key/Value のペアとして 中間テーブルに INSERT
  • 37. Reducefunction ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum);}
  • 38. Reduce Key Value の配列function ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum);}
  • 39. Reduce Value を全て足すfunction ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum);}
  • 40. Reducefunction ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum);} 返り値の連想配列を レコードとして INSERT
  • 41. +----+--------------------+Map | id | text | +----+--------------------+ | 1 | to be or not to be | +----+--------------------+ ↓ レコードを連想配列として Map へ ↓ +----+---------+-------+ | id | key | value | +----+---------+-------+ | 1 | to | 1 | | 2 | be | 1 | | 3 | or | 1 | | 4 | not | 1 | | 5 | to | 1 | | 6 | be | 1 | +----+---------+-------+
  • 42. +----+--------------------+Map | id | text | +----+--------------------+ | 1 | to be or not to be | +----+--------------------+ ↓ レコードを連想配列として Map へ ↓ +----+---------+-------+ | id | key | value | +----+---------+-------+ | 1 | to | 1 | | 2 | be | 1 | | 3 | or | 1 | | 4 | not value には JSON で入れるので | 1 | | 5 | to 構造化データも使用可能 | 1 | | 6 | be | 1 | +----+---------+-------+
  • 43. +----+---------+-------+ | id | key | value |Shuffle +----+---------+-------+ | 1 | to | 2 | be | 1 | 1 | | | 3 | or | 1 | | 4 | not | 1 | | 5 | to | 1 | | 6 | be | 1 | +----+---------+-------+ ↓ キーで GROUP BY して ↓SELECT ↓ 値は GROUP_CONCAT ↓ `key`, +---------+--------+ GROUP_CONCAT(`value`) | key | values |FROM +---------+--------+ `中間テーブル` | be | 1,1 | | not | 1 |GROUP BY | or | 1 | `key` | to | 1,1 | +---------+--------+
  • 44. +---------+--------+ | key | values |Reduce +---------+--------+ | be | 1,1 | | not | 1 | | or | 1 | | to | 1,1 | +---------+--------+ ↓ キーと値の配列を Reduce へ ↓ +----+---------+-------+ | id | key | count | +----+---------+-------+ | 1 | be | 2 | | 2 | not | 1 | | 3 | or | 1 | | 4 | to | 2 | +----+---------+-------+
  • 45. +---------+--------+ | key | values |Reduce +---------+--------+ | be | 1,1 | | not | 1 | | or | 1 | 実際にはデリミタとして改行を使用| to | 1,1 | +---------+--------+ 改行区切りの JSON になる ↓ キーと値の配列を Reduce へ ↓ +----+---------+-------+ | id | key | count | +----+---------+-------+ | 1 | be | 2 | | 2 | not | 1 | | 3 | or | 1 | | 4 | to | 2 | +----+---------+-------+
  • 46. モチベーション•プログラミングモデルとしてのMapReduce を使いたい• MySQL を入出力にしたい•LL でサクッとやりたい
  • 47. モチベーション•プログラミングモデルとしてのMapReduce を使いたい• MySQL を入出力にしたい•LL でサクッとやりたい PHP である必要はあまり無い
  • 48. 今後の目標•非同期 INSERT による並列化• Hadoop へのシームレスな移行方法の提供
  • 49. まとめ•ビッグデータは無くともMapReduce は有効• MySQL でできたら便利なはず•PHP で書けたら楽しいはず
  • 50. リンク• MyMR on GitHub https://github.com/yuya-takeyama/mymr• PHP と MySQL でカジュアルに MapReduce する http://blog.yuyat.jp/archives/1706• もっとカジュアルに PHP と MySQL で MapReduce する http://blog.yuyat.jp/archives/1853
  • 51. ご清聴 ありがとうございました