Born Too Late

Yuya's old tech blog.

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

2012-03-25 21:00:13

以前紹介した MapReduce フレームワーク MyMR の開発を少し進めました.
パッケージとしてのリリースはまだですが.

この記事では変更点等について紹介します.

MyMR の仕組みなどについては前回の記事を参照してください.

ビルダーによる Mapper/Reducer の定義

元々はクラスにメソッドを定義する形で行っていた Mapper/Reducer の定義を, ビルダーを使って定義できるようにしました.

この方法を使った場合, Mapper も Reducer も無名関数だけで定義できるようになったので, よりカジュアルになったと言えるでしょう.

また, クラスベースの定義では, 入出力のテーブルをコマンドラインオプションで指定していましたが, こちらではビルダーで指定できるようになりました.
なので設定ファイルの別出しすることもできるようになっています.

また, コマンドラインで指定した場合はそちらが優先されるので, テスト時はテスト用のデータベースを使う, ということもできます.

無名関数以外でも, call_user_func_array() で実行できるもの (PHP 5.4 で言うところの callable) であれば何でもいいので, インスタンスメソッドなどを Mapper として定義することもできます.

簡単なものは無名関数でサクッと定義してい, 複雑なものはユニットテストされたクラスのメソッドで定義する, といった使い分けができるようになっています.

クラスベースの定義も一応残していますが, ビルダーの方が圧倒的に使いやすいように思えるので, そのうち消すかもしれません.

コマンド名の変更

以前は mymr execute コマンドでクラスベースの MapReduce 定義を実行していましたが, ビルダーによる定義の追加に伴い mymr class コマンドに変更しました.

Emitter の切り出し

Mapper はもともと \MyMR \Base クラスの emit メソッドを $this->emit($key, $value) として読んでいましたが, 無名関数で同様のことをやるには PHP 5.4 以降の Closure::bindTo() を使用する必要が出てきてしまうため, Emitter クラスを別に作り, Mapper に引数として渡すようにしました.

これにより, Mapper のテスト時には Emitter をモックオブジェクトや Test Spy オブジェクトに差し替えてテストする, ということもできるようになりました.

進捗の表示

元々は実行しても無言で終了していましたが, Map と Reduce それぞれで進捗を表示するようにしました.

[caption id="attachment_1859" align="aligncenter" width="249" caption="進捗の表示"]進捗の表示[/caption]

今回 \MyMR \Progress という形で実装しましたが, これ自体の MyMR との結合は緩く, Symfony の Console コンポーネントの OutputInterface にしか依存していないので, 別で公開できればと思っています.

まとめ

遊びで作り始めたものですが, 少しずつ様になって来ました.
まだまだ開発が安定しないので, インターフェイス等は大幅に変わる可能性があると思いますが, 引き続き開発を続けて行きたいと思います.

MyMR については, 3/27 の第58回PHP勉強会@東京で発表する予定なので, 後日スライドを公開する予定です. (今からつくる)

あと, MySQL Casual Talks Vol. 3 の LT 枠でも喋りたいと思っているんですけど, これってもう募集していないんでしょうか...