51
PHP と MySQL で カジュアルに MapReduce する (Short Version) @yuya_takeyama

PHP と MySQL でカジュアルに MapReduce する (Short Version)

Embed Size (px)

DESCRIPTION

以下のスライドを再編集・一部加筆した Short Version ですhttp://www.slideshare.net/taketyan/php-mysql-mapreduce

Citation preview

Page 1: PHP と MySQL でカジュアルに MapReduce する (Short Version)

PHP と MySQL でカジュアルに

MapReduce する(Short Version)

@yuya_takeyama

Page 2: PHP と MySQL でカジュアルに MapReduce する (Short Version)

ショートバージョンでお送りします

• MyMR on GitHubhttps://github.com/yuya-takeyama/mymr

• PHP と MySQL でカジュアルに MapReduce するhttp://blog.yuyat.jp/archives/1706

• もっとカジュアルに PHP と MySQL で MapReduce するhttp://blog.yuyat.jp/archives/1853

• PHP と MySQL でカジュアルに MapReduce する(スライド・Long Version)http://www.slideshare.net/taketyan/php-mysql-mapreduce

Page 3: PHP と MySQL でカジュアルに MapReduce する (Short Version)

お断り

ビッグデータの話はありません

Page 4: PHP と MySQL でカジュアルに MapReduce する (Short Version)

問い

MongoDB にあってMySQL にないもの

なーんだ?

Page 5: PHP と MySQL でカジュアルに MapReduce する (Short Version)

構造化データ?自動シャーディング?自動フェイルオーバ?

Page 6: PHP と MySQL でカジュアルに MapReduce する (Short Version)

MapReduce!

Page 7: PHP と MySQL でカジュアルに MapReduce する (Short Version)

MapReduce!それもカジュアルな!!

Page 8: PHP と MySQL でカジュアルに MapReduce する (Short Version)

MongoDB はJavaScript で

カジュアルにMapReduce できる

Page 9: PHP と MySQL でカジュアルに MapReduce する (Short Version)

MySQL でもMapReduce

したい!!!

Page 10: PHP と MySQL でカジュアルに MapReduce する (Short Version)

MySQL でもMapReduce

したい!!!

それもカジュアルに!!

Page 11: PHP と MySQL でカジュアルに MapReduce する (Short Version)

モチベーション•プログラミングモデルとしてのMapReduce を使いたい

•GROUP BY では難しい集計•MySQL を入出力にしたい

•LL でサクッとやりたい

Page 12: PHP と MySQL でカジュアルに MapReduce する (Short Version)

モチベーション•プログラミングモデルとしてのMapReduce を使いたい

•GROUP BY では難しい集計•MySQL を入出力にしたい

•LL でサクッとやりたいPHP である必要はあまり無い

Page 13: PHP と MySQL でカジュアルに MapReduce する (Short Version)

MapReduce とは(word count による例)

Page 14: PHP と MySQL でカジュアルに MapReduce する (Short Version)

MapReduce とは

データ処理のためのプログラミングモデル

Page 15: PHP と MySQL でカジュアルに MapReduce する (Short Version)

処理の流れ入力↓

Map↓

Shuffle↓

Reduce↓出力

Page 16: PHP と MySQL でカジュアルに MapReduce する (Short Version)

Map

•入力データを受け取り•複数の Key/Value ペアを出力

Page 17: PHP と MySQL でカジュアルに MapReduce する (Short Version)

•to be or not to be

Page 18: PHP と MySQL でカジュアルに MapReduce する (Short Version)

•<"to", 1>

•<"be", 1>

•<"or", 1>

•<"not", 1>

•<"to", 1>

•<"be", 1>

Page 19: PHP と MySQL でカジュアルに MapReduce する (Short Version)

Shuffle

•Map による Key/Value を

•Key ごとにまとめて出力

Page 20: PHP と MySQL でカジュアルに MapReduce する (Short Version)

•<"to", 1>

•<"be", 1>

•<"or", 1>

•<"not", 1>

•<"to", 1>

•<"be", 1>

Page 21: PHP と MySQL でカジュアルに MapReduce する (Short Version)

•<"be", [1, 1]>

•<"not", [1]>

•<"or", [1]>

•<"to", [1, 1]>

Page 22: PHP と MySQL でカジュアルに MapReduce する (Short Version)

Reduce

•Shuffle による中間データを•集約して答えを出力

Page 23: PHP と MySQL でカジュアルに MapReduce する (Short Version)

•<"be", [1, 1]>

•<"not", [1]>

•<"or", [1]>

•<"to", [1, 1]>

Page 24: PHP と MySQL でカジュアルに MapReduce する (Short Version)

•<"be", 2>

•<"not", 1>

•<"or", 1>

•<"to", 2>

Page 25: PHP と MySQL でカジュアルに MapReduce する (Short Version)

複数の関数の入出力を経て最終的な答えを出力

Page 26: PHP と MySQL でカジュアルに MapReduce する (Short Version)

MySQL でもMapReduce したい!!! (再)

Page 27: PHP と MySQL でカジュアルに MapReduce する (Short Version)

というわけで作りました

Page 28: PHP と MySQL でカジュアルに MapReduce する (Short Version)

MyMR

•MySQL を入出力とする

•PHP で Map/Reduce を書く

•コマンドラインで実行

https://github.com/yuya-takeyama/mymr

Page 29: PHP と MySQL でカジュアルに MapReduce する (Short Version)

MyMR による処理の流れ•テーブルからレコードを読む•1 行 1 行に Map (PHP) を適用して中間テーブルへ

•MySQL による Shuffle

•その結果に Reduce (PHP) を適用して出力テーブルへ

Page 30: PHP と MySQL でカジュアルに MapReduce する (Short Version)

文章中の単語の数を数える例(word count)

MyMR による

Page 31: PHP と MySQL でカジュアルに MapReduce する (Short Version)

use \MyMR\Builder;

$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;

Map/Reduce の定義

Page 32: PHP と MySQL でカジュアルに MapReduce する (Short Version)

use \MyMR\Builder;

$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;

Map/Reduce の定義

入出力テーブルの指定

Page 33: PHP と MySQL でカジュアルに MapReduce する (Short Version)

use \MyMR\Builder;

$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;

Map/Reduce の定義

この辺が Map

Page 34: PHP と MySQL でカジュアルに MapReduce する (Short Version)

use \MyMR\Builder;

$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;

Map/Reduce の定義

この辺が Reduce

Page 35: PHP と MySQL でカジュアルに MapReduce する (Short Version)

入力

•to be or not to be

Page 36: PHP と MySQL でカジュアルに MapReduce する (Short Version)

function ($record, $emitter) {    $words = preg_split('/\s+/u', $record['text']);    foreach ($words as $word) {        $emitter->emit($word, 1);    }}

Map

Page 37: PHP と MySQL でカジュアルに MapReduce する (Short Version)

function ($record, $emitter) {    $words = preg_split('/\s+/u', $record['text']);    foreach ($words as $word) {        $emitter->emit($word, 1);    }}

レコードを連想配列として受け取る

Map

Page 38: PHP と MySQL でカジュアルに MapReduce する (Short Version)

function ($record, $emitter) {    $words = preg_split('/\s+/u', $record['text']);    foreach ($words as $word) {        $emitter->emit($word, 1);    }} text カラム内の

文字列をスペースで分割

Map

Page 39: PHP と MySQL でカジュアルに MapReduce する (Short Version)

function ($record, $emitter) {    $words = preg_split('/\s+/u', $record['text']);    foreach ($words as $word) {        $emitter->emit($word, 1);    }}

Key/Value のペアとして中間テーブルに INSERT

Map

Page 40: PHP と MySQL でカジュアルに MapReduce する (Short Version)

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 | +----+---------+-------+

Page 41: PHP と MySQL でカジュアルに MapReduce する (Short Version)

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 | +----+---------+-------+

value には JSON で入れるので構造化データも使用可能

Page 42: PHP と MySQL でカジュアルに MapReduce する (Short Version)

Shuffle

↓ キーで GROUP BY して ↓↓ 値は GROUP_CONCAT ↓

+---------+--------+| key | values |+---------+--------+| be | 1,1 || not | 1 || or | 1 || to | 1,1 |+---------+--------+

+----+---------+-------+ | id | key | value | +----+---------+-------+ | 1 | to | 1 | | 2 | be | 1 | | 3 | or | 1 | | 4 | not | 1 | | 5 | to | 1 | | 6 | be | 1 | +----+---------+-------+

SELECT `key`, GROUP_CONCAT(`value`)FROM `中間テーブル`

GROUP BY `key`

Page 43: PHP と MySQL でカジュアルに MapReduce する (Short Version)

function ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array('count' => $sum);}

Reduce

Page 44: PHP と MySQL でカジュアルに MapReduce する (Short Version)

function ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array('count' => $sum);}

ReduceKey Value の配列

Page 45: PHP と MySQL でカジュアルに MapReduce する (Short Version)

function ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array('count' => $sum);}

ReduceValue を全て足す

Page 46: PHP と MySQL でカジュアルに MapReduce する (Short Version)

function ($key, $values) {    $sum = 0;    foreach ($values as $count) {        $sum += $count;    }    return array('count' => $sum);}

Reduce

返り値の連想配列をレコードとして INSERT

Page 47: PHP と MySQL でカジュアルに MapReduce する (Short Version)

Reduce

↓ キーと値の配列を Reduce へ ↓

+---------+--------+| key | values |+---------+--------+| be | 1,1 || not | 1 || or | 1 || to | 1,1 |+---------+--------+

+----+---------+-------+| id | key | count |+----+---------+-------+| 1 | be | 2 || 2 | not | 1 || 3 | or | 1 || 4 | to | 2 |+----+---------+-------+

Page 48: PHP と MySQL でカジュアルに MapReduce する (Short Version)

Reduce

↓ キーと値の配列を Reduce へ ↓

+---------+--------+| key | values |+---------+--------+| be | 1,1 || not | 1 || or | 1 || to | 1,1 |+---------+--------+

+----+---------+-------+| id | key | count |+----+---------+-------+| 1 | be | 2 || 2 | not | 1 || 3 | or | 1 || 4 | to | 2 |+----+---------+-------+

実際にはデリミタとして改行を使用改行区切りの JSON になる

Page 49: PHP と MySQL でカジュアルに MapReduce する (Short Version)

今後の目標

•非同期 INSERT による並列化•Hadoop へのシームレスな移行方法の提供

Page 50: PHP と MySQL でカジュアルに MapReduce する (Short Version)

今後の野望

•V8 エンジンとかで•ストレージエンジン API を•カジュアルに叩いて•MapReduce したい

Page 51: PHP と MySQL でカジュアルに MapReduce する (Short Version)

ご清聴ありがとうございました