SlideShare ist ein Scribd-Unternehmen logo
1 von 52
Downloaden Sie, um offline zu lesen
PHP と MySQL で
    1-Click
  MapReduce
(@ニコニコ超会議)

  @yuya_takeyama
はじめに
1-Click
無理でした!!!
PHP と MySQL で
       1-Click
1カチャカチャカチャ...ッターン!
      MapReduce
    (@ニコニコ超会議)

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

•   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
MapReduce とは
(word count による例)
MapReduce とは

データ処理のための
プログラミングモデル
入力
処理の流れ      ↓
         Map
           ↓
        Shuffle
           ↓
        Reduce
           ↓
          出力
Map


•入力データを受け取り
• 複数の Key/Value ペアを出力
•to be or not to be
•<"to", 1>
•<"be", 1>
•<"or", 1>
•<"not", 1>
•<"to", 1>
•<"be", 1>
Shuffle


•Map による Key/Value を
• Key ごとにまとめて出力
•<"to", 1>
•<"be", 1>
•<"or", 1>
•<"not", 1>
•<"to", 1>
•<"be", 1>
•<"be", [1, 1]>
•<"not", [1]>
•<"or", [1]>
•<"to", [1, 1]>
Reduce


•Shuffle による中間データを
• 集約して答えを出力
•<"be", [1, 1]>
•<"not", [1]>
•<"or", [1]>
•<"to", [1, 1]>
•<"be", 2>
•<"not", 1>
•<"or", 1>
•<"to", 2>
複数の関数の
入出力を経て
最終的な答えを出力
ところで
MySQL で
MapReduce
  したい!!!
それ
  MySQL で
  も1
     カチ
        ャカ
MapReduce  チャ
              ...っ
                   ター
                     ン!
                        で

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

•   GROUP BY では難しい集計

•MySQL を入出力にしたい
• LL でサクッとやりたい
モチベーション
•
プログラミングモデルとしての
MapReduce を使いたい

•   GROUP BY では難しい集計

•MySQL を入出力にしたい
            PHP である必要はあまり無い


• LL でサクッとやりたい
モチベーション
 •
もち プログラミングモデルとしての
  ろん
     1カ
  MapReduce を使いたい
        チャ
           カチ
              ャ...
 • GROUP BY では難しい集計ッタ
                      ーン
                          !で
 • MySQL を入出力にしたい
              PHP である必要はあまり無い


 • LL でサクッとやりたい
というわけで作りました
MyMR
   https://github.com/yuya-takeyama/mymr


•MySQL を入出力とする

• PHP で Map/Reduce を書く

• カチャカチャ...ッターン!で実行
実行までの流れ

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

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

•入出力に使う MySQL テーブルの用意
•PHP で Map 関数を書く
•PHP で Reduce 関数を書く
•mymr コマンドを実行する
            この辺が...ッターン!
に よ る
 yM R
M
    文章中の
単語の数を数える例
 (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
Map

function ($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);
    }
}
Map

function ($record, $emitter) {
    $words = preg_split('/s+/u',
                        $record['text']);
    foreach ($words as $word) {
        $emitter->emit($word, 1);
    }
}                         text カラム内の
                       文字列をスペースで分割
Map

function ($record, $emitter) {
    $words = preg_split('/s+/u',
                        $record['text']);
    foreach ($words as $word) {
        $emitter->emit($word, 1);
    }
}
                    Key/Value のペアとして
                    中間テーブルに 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    |
                              +---------+--------+
Reduce
function ($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);
}
Reduce
function ($key, $values) {
    $sum = 0;
    foreach ($values as $count) {
        $sum += $count;
    }
    return array('count' => $sum);
}
                     返り値の連想配列を
                    レコードとして INSERT
+---------+--------+
            | 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 |
                +----+---------+-------+
今後の目標


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

•V8 エンジンとかで

•ストレージエンジン API を
• カジュアルに叩いて

•MapReduce したい
今後の野望
もち
 • ろん エンジンとかで
   V8 1
        カチ
          ャカ
 •          チャ
   ストレージエンジン API を
               ...ッ
                    ター
 • カジュアルに叩いて          ン!
                         で
 •MapReduce したい
ご清聴
 ありがとう
ございました

Weitere ähnliche Inhalte

Mehr von Yuya Takeyama

5分でわかる? 関数型 PHP の潮流
5分でわかる? 関数型 PHP の潮流5分でわかる? 関数型 PHP の潮流
5分でわかる? 関数型 PHP の潮流Yuya Takeyama
 
Good Parts of PHP and the UNIX Philosophy
Good Parts of PHP and the UNIX PhilosophyGood Parts of PHP and the UNIX Philosophy
Good Parts of PHP and the UNIX PhilosophyYuya Takeyama
 
Reactor Pattern and React
Reactor Pattern and ReactReactor Pattern and React
Reactor Pattern and ReactYuya Takeyama
 
PHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めようPHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めようYuya Takeyama
 
HashTable と HashDos
HashTable と HashDosHashTable と HashDos
HashTable と HashDosYuya Takeyama
 
Proposal for xSpep BDD Framework for PHP
Proposal for xSpep BDD Framework for PHPProposal for xSpep BDD Framework for PHP
Proposal for xSpep BDD Framework for PHPYuya Takeyama
 
Building Development Environment with php-build and phpenv
Building Development Environment with php-build and phpenvBuilding Development Environment with php-build and phpenv
Building Development Environment with php-build and phpenvYuya Takeyama
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにYuya Takeyama
 
LIMIT 付きで UPDATE を行うと何故怒られるか
LIMIT 付きで UPDATE を行うと何故怒られるかLIMIT 付きで UPDATE を行うと何故怒られるか
LIMIT 付きで UPDATE を行うと何故怒られるかYuya Takeyama
 
Ruby 同好会宣言
Ruby 同好会宣言Ruby 同好会宣言
Ruby 同好会宣言Yuya Takeyama
 
第一回 社内勉強会 PHP Application Security Checklist に学ぶ PHP セキュリティ (Excerpt)
第一回 社内勉強会 PHP Application Security Checklist に学ぶ PHP セキュリティ (Excerpt)第一回 社内勉強会 PHP Application Security Checklist に学ぶ PHP セキュリティ (Excerpt)
第一回 社内勉強会 PHP Application Security Checklist に学ぶ PHP セキュリティ (Excerpt)Yuya Takeyama
 

Mehr von Yuya Takeyama (13)

5分でわかる? 関数型 PHP の潮流
5分でわかる? 関数型 PHP の潮流5分でわかる? 関数型 PHP の潮流
5分でわかる? 関数型 PHP の潮流
 
Good Parts of PHP and the UNIX Philosophy
Good Parts of PHP and the UNIX PhilosophyGood Parts of PHP and the UNIX Philosophy
Good Parts of PHP and the UNIX Philosophy
 
Reactor Pattern and React
Reactor Pattern and ReactReactor Pattern and React
Reactor Pattern and React
 
PHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めようPHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めよう
 
HashTable と HashDos
HashTable と HashDosHashTable と HashDos
HashTable と HashDos
 
Proposal for xSpep BDD Framework for PHP
Proposal for xSpep BDD Framework for PHPProposal for xSpep BDD Framework for PHP
Proposal for xSpep BDD Framework for PHP
 
Building Development Environment with php-build and phpenv
Building Development Environment with php-build and phpenvBuilding Development Environment with php-build and phpenv
Building Development Environment with php-build and phpenv
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
 
Making DSL with []
Making DSL with []Making DSL with []
Making DSL with []
 
LIMIT 付きで UPDATE を行うと何故怒られるか
LIMIT 付きで UPDATE を行うと何故怒られるかLIMIT 付きで UPDATE を行うと何故怒られるか
LIMIT 付きで UPDATE を行うと何故怒られるか
 
GOOS #1
GOOS #1GOOS #1
GOOS #1
 
Ruby 同好会宣言
Ruby 同好会宣言Ruby 同好会宣言
Ruby 同好会宣言
 
第一回 社内勉強会 PHP Application Security Checklist に学ぶ PHP セキュリティ (Excerpt)
第一回 社内勉強会 PHP Application Security Checklist に学ぶ PHP セキュリティ (Excerpt)第一回 社内勉強会 PHP Application Security Checklist に学ぶ PHP セキュリティ (Excerpt)
第一回 社内勉強会 PHP Application Security Checklist に学ぶ PHP セキュリティ (Excerpt)
 

Kürzlich hochgeladen

論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 

Kürzlich hochgeladen (9)

論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 

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

  • 1. PHP と MySQL で 1-Click MapReduce (@ニコニコ超会議) @yuya_takeyama
  • 4. PHP と MySQL で 1-Click 1カチャカチャカチャ...ッターン! MapReduce (@ニコニコ超会議) @yuya_takeyama
  • 5. N番煎じでお送りします • 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 • 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
  • 8. 入力 処理の流れ ↓ Map ↓ Shuffle ↓ Reduce ↓ 出力
  • 10. •to be or not to be
  • 11. •<"to", 1> •<"be", 1> •<"or", 1> •<"not", 1> •<"to", 1> •<"be", 1>
  • 12. Shuffle •Map による Key/Value を • Key ごとにまとめて出力
  • 13. •<"to", 1> •<"be", 1> •<"or", 1> •<"not", 1> •<"to", 1> •<"be", 1>
  • 14. •<"be", [1, 1]> •<"not", [1]> •<"or", [1]> •<"to", [1, 1]>
  • 16. •<"be", [1, 1]> •<"not", [1]> •<"or", [1]> •<"to", [1, 1]>
  • 20. MySQL で MapReduce したい!!!
  • 21. それ MySQL で も1 カチ ャカ MapReduce チャ ...っ ター ン! で したい!!!
  • 22. モチベーション • プログラミングモデルとしての MapReduce を使いたい • GROUP BY では難しい集計 •MySQL を入出力にしたい • LL でサクッとやりたい
  • 23. モチベーション • プログラミングモデルとしての MapReduce を使いたい • GROUP BY では難しい集計 •MySQL を入出力にしたい PHP である必要はあまり無い • LL でサクッとやりたい
  • 24. モチベーション • もち プログラミングモデルとしての ろん 1カ MapReduce を使いたい チャ カチ ャ... • GROUP BY では難しい集計ッタ ーン !で • MySQL を入出力にしたい PHP である必要はあまり無い • LL でサクッとやりたい
  • 26. MyMR https://github.com/yuya-takeyama/mymr •MySQL を入出力とする • PHP で Map/Reduce を書く • カチャカチャ...ッターン!で実行
  • 27. 実行までの流れ •入出力に使う MySQL テーブルの用意 •PHP で Map 関数を書く •PHP で Reduce 関数を書く •mymr コマンドを実行する
  • 28. 実行までの流れ •入出力に使う MySQL テーブルの用意 •PHP で Map 関数を書く •PHP で Reduce 関数を書く •mymr コマンドを実行する この辺がカチャカチャカチャ...
  • 29. 実行までの流れ •入出力に使う MySQL テーブルの用意 •PHP で Map 関数を書く •PHP で Reduce 関数を書く •mymr コマンドを実行する この辺が...ッターン!
  • 30. に よ る yM R M 文章中の 単語の数を数える例 (word count)
  • 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); }); return $builder;
  • 32. 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;
  • 33. 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;
  • 34. 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;
  • 35. 入力 •to be or not to be
  • 36. Map function ($record, $emitter) {     $words = preg_split('/s+/u', $record['text']);     foreach ($words as $word) {         $emitter->emit($word, 1);     } }
  • 37. Map レコードを 連想配列として受け取る function ($record, $emitter) {     $words = preg_split('/s+/u', $record['text']);     foreach ($words as $word) {         $emitter->emit($word, 1);     } }
  • 38. Map function ($record, $emitter) {     $words = preg_split('/s+/u', $record['text']);     foreach ($words as $word) {         $emitter->emit($word, 1);     } } text カラム内の 文字列をスペースで分割
  • 39. Map function ($record, $emitter) {     $words = preg_split('/s+/u', $record['text']);     foreach ($words as $word) {         $emitter->emit($word, 1);     } } Key/Value のペアとして 中間テーブルに INSERT
  • 40. +----+--------------------+ 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 | +----+---------+-------+
  • 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 value には JSON で入れるので | 1 | | 5 | to 構造化データも使用可能 | 1 | | 6 | be | 1 | +----+---------+-------+
  • 42. +----+---------+-------+ | 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 | +---------+--------+
  • 43. Reduce function ($key, $values) {     $sum = 0;     foreach ($values as $count) {         $sum += $count;     }     return array('count' => $sum); }
  • 44. Reduce Key Value の配列 function ($key, $values) {     $sum = 0;     foreach ($values as $count) {         $sum += $count;     }     return array('count' => $sum); }
  • 45. Reduce Value を全て足す function ($key, $values) {     $sum = 0;     foreach ($values as $count) {         $sum += $count;     }     return array('count' => $sum); }
  • 46. Reduce function ($key, $values) {     $sum = 0;     foreach ($values as $count) {         $sum += $count;     }     return array('count' => $sum); } 返り値の連想配列を レコードとして INSERT
  • 47. +---------+--------+ | 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 | +----+---------+-------+
  • 48. +---------+--------+ | 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 | +----+---------+-------+
  • 49. 今後の目標 •非同期 INSERT による並列化 • Hadoop へのシームレスな 移行方法の提供
  • 50. 今後の野望 •V8 エンジンとかで •ストレージエンジン API を • カジュアルに叩いて •MapReduce したい
  • 51. 今後の野望 もち • ろん エンジンとかで V8 1 カチ ャカ • チャ ストレージエンジン API を ...ッ ター • カジュアルに叩いて ン! で •MapReduce したい