php と mysql で 1 カチャカチャカチャ...ッターン! mapreduce (@ニコニコ超会議)

52
PHP と MySQL で 1-Click MapReduce (@ニコニコ超会議) @yuya_takeyama

Upload: yuya-takeyama

Post on 13-Jan-2015

1.393 views

Category:

Technology


2 download

DESCRIPTION

 

TRANSCRIPT

Page 1: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

PHP と MySQL で1-Click

MapReduce(@ニコニコ超会議)

@yuya_takeyama

Page 2: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

はじめに

Page 3: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

1-Click無理でした!!!

Page 4: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

PHP と MySQL で1-Click

1カチャカチャカチャ...ッターン!MapReduce(@ニコニコ超会議)

@yuya_takeyama

Page 5: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

N番煎じでお送りします• 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

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

Page 6: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

MapReduce とは(word count による例)

Page 7: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

MapReduce とは

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

Page 8: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

処理の流れ入力↓Map↓

Shuffle↓

Reduce↓出力

Page 9: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

Map

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

Page 10: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

•to be or not to be

Page 11: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

•<"to", 1>

•<"be", 1>

•<"or", 1>

•<"not", 1>

•<"to", 1>

•<"be", 1>

Page 12: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

Shuffle

•Map による Key/Value を•Key ごとにまとめて出力

Page 13: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

•<"to", 1>

•<"be", 1>

•<"or", 1>

•<"not", 1>

•<"to", 1>

•<"be", 1>

Page 14: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

•<"not", [1]>

•<"or", [1]>

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

Page 15: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

Reduce

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

Page 16: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

•<"not", [1]>

•<"or", [1]>

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

Page 17: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

•<"be", 2>

•<"not", 1>

•<"or", 1>

•<"to", 2>

Page 18: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

Page 19: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

ところで

Page 20: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

MySQL でMapReduce したい!!!

Page 21: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

MySQL でMapReduce したい!!!

それも1カチャカチャ...っターン!で

Page 22: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

•GROUP BY では難しい集計•MySQL を入出力にしたい•LL でサクッとやりたい

Page 23: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

•GROUP BY では難しい集計•MySQL を入出力にしたい•LL でサクッとやりたい

PHP である必要はあまり無い

Page 24: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

•GROUP BY では難しい集計•MySQL を入出力にしたい•LL でサクッとやりたい

PHP である必要はあまり無い

もちろん1カチャカチャ...ッターン!で

Page 25: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

というわけで作りました

Page 26: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

MyMR

•MySQL を入出力とする•PHP で Map/Reduce を書く•カチャカチャ...ッターン!で実行

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

Page 27: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

実行までの流れ

•入出力に使う MySQL テーブルの用意•PHP で Map 関数を書く•PHP で Reduce 関数を書く•mymr コマンドを実行する

Page 28: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

実行までの流れ

•入出力に使う MySQL テーブルの用意•PHP で Map 関数を書く•PHP で Reduce 関数を書く•mymr コマンドを実行するこの辺がカチャカチャカチャ...

Page 29: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

実行までの流れ

•入出力に使う MySQL テーブルの用意•PHP で Map 関数を書く•PHP で Reduce 関数を書く•mymr コマンドを実行する

この辺が...ッターン!

Page 30: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

MyMR による

Page 31: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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 で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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 で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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 で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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 で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

入力

•to be or not to be

Page 36: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

Map

Page 37: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

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

Map

Page 38: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

文字列をスペースで分割

Map

Page 39: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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 で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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 で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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 で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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 で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

Reduce

Page 44: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

ReduceKey Value の配列

Page 45: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

ReduceValue を全て足す

Page 46: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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

Reduce

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

Page 47: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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 で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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 で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

今後の目標

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

Page 50: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

今後の野望

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

Page 51: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

今後の野望

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

もちろん1カチャカチャ...ッターン!で

Page 52: PHP と MySQL で 1 カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議)

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