• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
PHP と MySQL でカジュアルに MapReduce する
 

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

on

  • 7,149 views

 

Statistics

Views

Total Views
7,149
Views on SlideShare
5,774
Embed Views
1,375

Actions

Likes
10
Downloads
21
Comments
0

19 Embeds 1,375

http://blog.yuyat.jp 487
http://yuyat.jp 415
http://work.blog.eggplant.org.uk 319
https://twitter.com 51
http://webcache.googleusercontent.com 18
https://si0.twimg.com 14
http://www.yuyat.jp 13
http://hrfmsd.tumblr.com 12
https://twimg0-a.akamaihd.net 10
http://coderwall.com 9
http://a0.twimg.com 6
http://us-w1.rockmelt.com 6
http://b.hatena.ne.jp 3
http://blog-test.yuyat.jp 3
http://jackbagii.tumblr.com 3
http://timedtext.yuyat.jp 2
http://cache.yahoofs.jp 2
http://ss.dotbranch.com 1
http://localhost 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

    • PHP と MySQL で カジュアルにMapReduce する @yuya_takeyama
    • アジェンダ•MapReduce とは• 自作フレームワークMyMR の紹介
    • お断り (1)ビッグデータの話は ありません
    • お断り (2) 業務ではまだやってません
    • お断り (3) Hadoop 未経験です ※MongoDB でのMapReduce ならやりました
    • MapReduce とは
    • 固有名詞として•Google の大規模データ処理フレームワーク•検索インデックスの作成とかに使われている
    • 普通名詞として•Map/Reduce 関数でデータを 処理するプログラミングモデル• マシンを増やしただけスケール•Hadoop, MongoDB, CouchDB などが主な実装
    • 入力処理の流れ ↓ Map ↓ Reduce ↓ 出力
    • やや厳密な 入力 処理の流れ ↓ Map ↓ Shuffle ↓ Reduceより厳密には ↓もっと複雑らしいです 出力
    • Map•入力データを受け取り• 複数の Key/Value ペアを出力
    • Shuffle•Map による Key/Value を• Key ごとにまとめて出力
    • Reduce•Shuffle による中間データを• 集約して答えを出力
    • 複数の関数の入出力を経て最終的な答えを出力
    • 文章中の単語の数を数える例 (word count)
    • 入力•to be or not to be
    • Map •<"to", 1> •<"be", 1> •<"or", 1> •<"not", 1> •<"to", 1> •<"be", 1>
    • Shuffle •<"be", [1, 1]> •<"not", [1]> •<"or", [1]> •<"to", [1, 1]>
    • Reduce • <"be", 2> • <"not", 1> • <"or", 1> • <"to", 2>
    • MapReduce の利点•Map も Reduce も並列化すればスケールする•関数型っぽい考え方が活きる※ただし, Hadoop や MongoDB の MapReduce の Map と Reduce は 関数型言語のそれとはやや異なる (参照透過でなかったり)• パターンとして共有しやすい※手続き型のバッチ処理と比較して
    • MongoDB について•通常は MapReduce を並列に実行することができない• それでも MapReduce は便利•何故か?
    • スケーラビリティだけじゃない•プログラミングモデルとしての MapReduce にも価値がある• MongoDB で処理が完結•JS で関数ふたつ書くだけ
    • MySQL でもMapReduce したい!!!
    • というわけで作りました
    • MyMR https://github.com/yuya-takeyama/mymr•MySQL を入出力とする• PHP で Map/Reduce を書く• コマンドラインで実行
    • MyMR による処理の流れ•テーブルからレコードを読む•1 行 1 行に Map (PHP) を適用して 中間テーブルへ•MySQL による Shuffle•その結果に Reduce (PHP) を適用して 出力テーブルへ
    • に よ る yM RM 文章中の単語の数を数える例 (word count)
    • 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;
    • 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;
    • 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;
    • 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;
    • 入力•to be or not to be
    • Mapfunction ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) {        $emitter->emit($word, 1);    }}
    • Map レコードを 連想配列として受け取るfunction ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) {        $emitter->emit($word, 1);    }}
    • Mapfunction ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) {        $emitter->emit($word, 1);    }} text カラム内の 文字列をスペースで分割
    • Mapfunction ($record, $emitter) {    $words = preg_split(/s+/u, $record[text]);    foreach ($words as $word) {        $emitter->emit($word, 1);    }} Key/Value のペアとして 中間テーブルに INSERT
    • Reducefunction ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum);}
    • Reduce Key Value の配列function ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum);}
    • Reduce Value を全て足すfunction ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum);}
    • Reducefunction ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array(count => $sum);} 返り値の連想配列を レコードとして INSERT
    • +----+--------------------+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 | +----+---------+-------+
    • +----+--------------------+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 | +----+---------+-------+
    • +----+---------+-------+ | 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 | +---------+--------+
    • +---------+--------+ | 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 | +----+---------+-------+
    • +---------+--------+ | 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 | +----+---------+-------+
    • モチベーション•プログラミングモデルとしてのMapReduce を使いたい• MySQL を入出力にしたい•LL でサクッとやりたい
    • モチベーション•プログラミングモデルとしてのMapReduce を使いたい• MySQL を入出力にしたい•LL でサクッとやりたい PHP である必要はあまり無い
    • 今後の目標•非同期 INSERT による並列化• Hadoop へのシームレスな移行方法の提供
    • まとめ•ビッグデータは無くともMapReduce は有効• MySQL でできたら便利なはず•PHP で書けたら楽しいはず
    • リンク• 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
    • ご清聴 ありがとうございました