SlideShare une entreprise Scribd logo
1  sur  51
Télécharger pour lire hors ligne
PHP と MySQL で
  カジュアルに
MapReduce する
  (Short Version)
   @yuya_takeyama
ショートバージョンで
         お送りします
•   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
お断り

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

MongoDB にあって
MySQL にないもの
   なーんだ?
構造化データ?
自動シャーディング?
自動フェイルオーバ?
MapReduce!
それ
   もカ
MapReduce!
      ジュ
      !!
         アル
            な
MongoDB は
   JavaScript で
      カジュアルに
MapReduce できる
MySQL でも
MapReduce
  したい!!!
MySQL でも
 それ
    もカ
MapReduce
       ジュ
          アル
             に!!


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

•   GROUP BY では難しい集計

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

•   GROUP BY では難しい集計

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


• LL でサクッとやりたい
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
したい!!! (再)
というわけで作りました
MyMR
   https://github.com/yuya-takeyama/mymr


•MySQL を入出力とする

• PHP で Map/Reduce を書く

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

•MySQL による Shuffle
•その結果に Reduce (PHP) を適用して
  出力テーブルへ
に よ る
 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 したい
ご清聴
 ありがとう
ございました

Contenu connexe

Plus de 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
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために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
 

Plus de Yuya Takeyama (10)

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
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
 
Making DSL with []
Making DSL with []Making DSL with []
Making DSL with []
 
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)
 

Dernier

LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルCRI Japan, Inc.
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video UnderstandingToru Tamaki
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイスCRI Japan, Inc.
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsWSO2
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Gamesatsushi061452
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...Toru Tamaki
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptxsn679259
 

Dernier (10)

LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 

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

  • 1. PHP と MySQL で カジュアルに MapReduce する (Short Version) @yuya_takeyama
  • 2. ショートバージョンで お送りします • 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
  • 7. それ もカ MapReduce! ジュ !! アル な
  • 8. MongoDB は JavaScript で カジュアルに MapReduce できる
  • 9. MySQL でも MapReduce したい!!!
  • 10. MySQL でも それ もカ MapReduce ジュ アル に!! したい!!!
  • 11. モチベーション • プログラミングモデルとしての MapReduce を使いたい • GROUP BY では難しい集計 •MySQL を入出力にしたい • LL でサクッとやりたい
  • 12. モチベーション • プログラミングモデルとしての MapReduce を使いたい • GROUP BY では難しい集計 •MySQL を入出力にしたい PHP である必要はあまり無い • LL でサクッとやりたい
  • 15. 入力 処理の流れ ↓ Map ↓ Shuffle ↓ Reduce ↓ 出力
  • 17. •to be or not to be
  • 18. •<"to", 1> •<"be", 1> •<"or", 1> •<"not", 1> •<"to", 1> •<"be", 1>
  • 19. Shuffle •Map による Key/Value を • Key ごとにまとめて出力
  • 20. •<"to", 1> •<"be", 1> •<"or", 1> •<"not", 1> •<"to", 1> •<"be", 1>
  • 21. •<"be", [1, 1]> •<"not", [1]> •<"or", [1]> •<"to", [1, 1]>
  • 23. •<"be", [1, 1]> •<"not", [1]> •<"or", [1]> •<"to", [1, 1]>
  • 28. MyMR https://github.com/yuya-takeyama/mymr •MySQL を入出力とする • PHP で Map/Reduce を書く • コマンドラインで実行
  • 29. MyMR による処理の流れ •テーブルからレコードを読む •1 行 1 行に Map (PHP) を適用して 中間テーブルへ •MySQL による Shuffle •その結果に Reduce (PHP) を適用して 出力テーブルへ
  • 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 したい