phpとmongodbで学ぶ次世代データストア

68
LOCAL PHP 提

Upload: takuya-sato

Post on 27-May-2015

8.661 views

Category:

Technology


0 download

DESCRIPTION

ドキュメント指向データベースのMongoDBをPHPで扱う方法を説明しながら、RDBやKVSとの違いやメリットを紹介します。 at LOCAL DEVELOPER DAY '10 /Winter http://labs.nazone.info/

TRANSCRIPT

Page 1: PHPとMongoDBで学ぶ次世代データストア

提 供

LOCAL PHP部

Page 2: PHPとMongoDBで学ぶ次世代データストア

PHP と MongoDB で学ぶ次世代データストア

佐藤琢哉LOCAL PHP 部

Page 3: PHPとMongoDBで学ぶ次世代データストア

自己紹介• 佐藤琢哉 aka nazo• 旭川出身 東京在住• 株式会社 RYUS 所属 (http://ryus.co.jp)– 3月末まで

• LOCAL PHP 部• Hatena : nazone• twitter : nazo

Page 4: PHPとMongoDBで学ぶ次世代データストア

突然ですが

Page 5: PHPとMongoDBで学ぶ次世代データストア

4月から札幌市民に

なります!!!!!

Page 6: PHPとMongoDBで学ぶ次世代データストア

友達が少ないので皆さん

遊んでやってください

Page 7: PHPとMongoDBで学ぶ次世代データストア

アジェンダ• MongoDB って何?• 使い方• 他の DBMS との比較• MapReduce• まとめ

Page 8: PHPとMongoDBで学ぶ次世代データストア

そもそも何の話?

Page 9: PHPとMongoDBで学ぶ次世代データストア

MongoDB すごいよ!

Page 10: PHPとMongoDBで学ぶ次世代データストア

MongoDB って何?

Page 11: PHPとMongoDBで学ぶ次世代データストア

http://www.mongodb.org/

Page 12: PHPとMongoDBで学ぶ次世代データストア

MongoDB (from "humongous") is a scalable, high-performance, open source, schema-free,

document-oriented database.

Page 13: PHPとMongoDBで学ぶ次世代データストア

ドキュメント指向データベース• スキーマがない• データ定義自体が各ドキュメントに入っ

ている

Page 14: PHPとMongoDBで学ぶ次世代データストア

RDBMSID 名前 年齢 性別 住所

行と列にデータを

当てはめていくのがRDBMS

Page 15: PHPとMongoDBで学ぶ次世代データストア

ドキュメントの集合

ドキュメント指向

ID : 1名前: hokkai

性別:男

ID : 2名前: onodes

電話番号: xxx-xxx-xxxx

ID : 3名前: reath

ID : 4名前: riaf

ライブラリ: rhaco

※名前は実在の人物とは一切関係ありません

Page 16: PHPとMongoDBで学ぶ次世代データストア

AGPL ライセンス• Web からのみアクセスするものでもソー

スコードを公開しないといけない GPL• 普通の GPL は、 Web サイトとして使う

分にはプログラムを配布するわけじゃないからソースコード公開する必要がないが、それが気にくわないために作られたライセンス

Page 17: PHPとMongoDBで学ぶ次世代データストア

AGPL ライセンス• MongoDB 自体をカスタマイズするなら

例え Web サイト内部だけで使ってても公開要求に応じないと駄目よー

• 各言語からアクセスするドライバはApache License だから大丈夫よー

• 社内からしかアクセスできないような場所で使う分には平気よー

Page 18: PHPとMongoDBで学ぶ次世代データストア

特長

Page 19: PHPとMongoDBで学ぶ次世代データストア

データを BSON で保存• BSON is a binary-encoded serialization

of JSON-like documents• { hoge: "fuga", foo: [bar, baz] }• 構造が自由• XML データベースが JSON になったような

感じ• JSON なので操作も簡単• ちょっとした構造で JOIN とかする必要がな

Page 20: PHPとMongoDBで学ぶ次世代データストア

JavaScript 処理系内蔵• MongoDB 単体で JavaScript でデータを

操作することが可能• JSON で記録されたデータをそのまま処理

できる• ストアドプロシージャ的な使い方• MapReduce

Page 21: PHPとMongoDBで学ぶ次世代データストア

スケーラブル• MapReduce 搭載• Master-Slave 構成• ペア DB• Master-Master 構成(制限あり)• Sharding

Page 22: PHPとMongoDBで学ぶ次世代データストア

なんで MongoDB なの?

Page 23: PHPとMongoDBで学ぶ次世代データストア

日本だと CouchDB のほうが情報が圧倒的に

多いのになんでMongoDB とかマイ

ナーそうなのを…

Page 24: PHPとMongoDBで学ぶ次世代データストア

提 供

LOCAL PHP 部

Page 25: PHPとMongoDBで学ぶ次世代データストア

http://php.net/mongo

Page 26: PHPとMongoDBで学ぶ次世代データストア

そりゃ MongoDB しかない!

Page 27: PHPとMongoDBで学ぶ次世代データストア

ちなみに世界的には

青: CouchDB赤: MongoDB

Page 28: PHPとMongoDBで学ぶ次世代データストア

使い方[ インストール ]

Page 29: PHPとMongoDBで学ぶ次世代データストア

インストール• いろんなプラットフォームのバイナリが

配布されているので好きなのを入れる。

Page 30: PHPとMongoDBで学ぶ次世代データストア

インストール• データフォルダをデフォルトで /data/db

に作るので、面倒であればフォルダを作っておく

• 起動時の設定でもちろん変更可能

Page 31: PHPとMongoDBで学ぶ次世代データストア

インストール• mongod を実行するだけで起動• 面倒な人は init スクリプト– init.d for MongoDB– http://gist.github.com/232227

Page 32: PHPとMongoDBで学ぶ次世代データストア

インストール• pecl install mongo• あと php.ini に extension=mongo.so

と書くだけ– PHPer 歓喜

Page 33: PHPとMongoDBで学ぶ次世代データストア

使い方[PHP コード ]

Page 34: PHPとMongoDBで学ぶ次世代データストア

接続• $mongo = new Mongo();• $mongo = new

Mongo("example.com:65432");

Page 35: PHPとMongoDBで学ぶ次世代データストア

データベースとコレクションの取得

• $db = $mongo->selectDB( "dbname" );

• $col = $db->selectCollection( "collectionname" );

Page 36: PHPとMongoDBで学ぶ次世代データストア

データベースとコレクション

RDBMS MongoDB

データベース データベース

テーブル コレクション

行(レコード) ドキュメント

Page 37: PHPとMongoDBで学ぶ次世代データストア

INSERT

$doc = array( "name" => "MongoDB", "type" => "database", "count" => 1, "info" => (object)array( "x" => 203, "y" => 102), "versions" => array("0.9.7", "0.9.8",

"0.9.9"));$col->insert( $doc );

Page 38: PHPとMongoDBで学ぶ次世代データストア

INSERT

• PHP の配列がそのままデータとして入る• 複雑な階層でももちろんそのまま入る• 1コレクション内の構造が統一されてい

なくてもいい(ただしインデックスを張る場合はその項目は必須)

Page 39: PHPとMongoDBで学ぶ次世代データストア

INSERT

$doc = array( "name" => "Apple", "color" => "Red",);$col->insert( $doc );$doc = array( "name" => "Beer", "price" => 300,);$col->insert( $doc );

Page 40: PHPとMongoDBで学ぶ次世代データストア

SELECT

• 1件取得$obj = $col->findOne();• 条件指定取得$obj = $col-

>findOne(array("name"=>"MongoDB"));

• 全件取得$cursor = $col->find();

Page 41: PHPとMongoDBで学ぶ次世代データストア

SELECT

• $cursor = $col->find(array('num' => array('$gt' => 1)));

• $cursor = $col->find(array('name' => new MongoRegex('/ba/i')));

• $cursor = $col->find(array('$where' => 'this.num > Math.abs(-1)'));

Page 42: PHPとMongoDBで学ぶ次世代データストア

Update

$obj = $col->findOne(array("name"=>"MongoDB"));

$obj["value"] = 2;$col->save($obj);

Page 43: PHPとMongoDBで学ぶ次世代データストア

Delete

$col->remove(array("name" => "MongoDB"));

$obj = $col->findOne();$col->remove($obj);

$col->drop();$db->drop();

Page 44: PHPとMongoDBで学ぶ次世代データストア

Count

$col->count();$col->count(array('x'=>1));

Page 45: PHPとMongoDBで学ぶ次世代データストア

Index 作成$col->ensureIndex( array( "name" => 1 ) );$col->ensureIndex( array( "name" => 1 ,

"count" => -1 ) );

• Index に対応するデータは一意であり、全てのドキュメントで必須である必要がある

Page 46: PHPとMongoDBで学ぶ次世代データストア

使い方[MapReduce]

Page 47: PHPとMongoDBで学ぶ次世代データストア

MapReduce とは?• 大量のサーバ上で分散処理をするために考案された手法

• Key-Value の組み合わせを単純な方法で分散して再計算することによって、複雑な計算に対応する

• Map フェーズと Reduce フェーズの処理を与えてあげるだけで、後の処理はシステムが自動的に分散して行ってくれる

Page 48: PHPとMongoDBで学ぶ次世代データストア

MapReduce とは?• Map– ある大量のデータを、一連の Key-Value の形

式にして、システムに渡す• システム–Map で渡されたデータを、同一の Key で束ねる

• Reduce– システムから渡ってきたデータを加工し、出力する

Page 49: PHPとMongoDBで学ぶ次世代データストア

例:ユーザーごとの買い物金額の合計

• MapReduce を使う必要があるかは謎• そもそも設計も怪しい

Page 50: PHPとMongoDBで学ぶ次世代データストア

データ例名前 品物 金額

hokkai apple 100

hokkai orange 100

onodes bread 100

onodes beef 200

reath book 300

reath pen 100

※名前は実在の人物とは一切関係ありません

Page 51: PHPとMongoDBで学ぶ次世代データストア

Map

Map関数 hokkai=100

hokkai=100

onodes=100

onodes=200

reath=300

reath=100

元データ

元データ

元データ

元データ

元データ

元データ

Page 52: PHPとMongoDBで学ぶ次世代データストア

Reduce

Reduce関数

hokkai=[100,100]

onodes=[100,200]

reath=[100, 300]

hokkai=200

onodes=300

reath=400

Page 53: PHPとMongoDBで学ぶ次世代データストア

MongoDB で MapReduce

• MapReduce に与える Map/Reduce関数を JavaScript で記述

• PHP で使う場合は MongoDB-MapReduce-PHP ライブラリを使うと少し楽– でも処理自体は結局 JavaScript で書かないと

いけない

Page 54: PHPとMongoDBで学ぶ次世代データストア

基本データ$col->insert( array("user" => "hokkai", "item" =>

"apple", "price" => 100 ) );$col->insert( array("user" => "hokkai", "item" =>

"orange", "price" => 100 ) );$col->insert( array("user" => "onodes", "item" =>

"bread", "price" => 100 ) );$col->insert( array("user" => "onodes", "item" =>

"beef", "price" => 200 ) );$col->insert( array("user" => "reath", "item" =>

"book", "price" => 300 ) );$col->insert( array("user" => "reath", "item" =>

"pen", "price" => 100 ) );

Page 55: PHPとMongoDBで学ぶ次世代データストア

Map

$map = <<<MAPfunction() { emit(this.user, this.price);}MAP;

Page 56: PHPとMongoDBで学ぶ次世代データストア

Reduce

$reduce = <<<REDUCEfunction(key, values) { var total = 0; for(var i in values) total +=

values[i]; return total;}REDUCE;

Page 57: PHPとMongoDBで学ぶ次世代データストア

PHP側( insert済みな前提)<?php

require_once('./MongoDB-MapReduce-PHP/lib/MongoMapReduce.php');require_once('./MongoDB-MapReduce-PHP/lib/MongoMapReduceResponse.php');

$mongo = new Mongo();$db = $mongo->selectDB( 'mydb' );$col = $db->selectCollection( 'shop' );// $mapと$reduceは省略$map_reduce = new MongoMapReduce($map, $reduce);$response = $map_reduce->invoke($db, "shop");if ($response->valid()) { foreach($response->getResultSet() as $result) { echo "name: ", $result["_id"] , " / price: ", $result["value"], PHP_ EOL; }}

Page 58: PHPとMongoDBで学ぶ次世代データストア

結果name: hokkai / price: 200name: onodes / price: 300name: reath / price: 400

Page 59: PHPとMongoDBで学ぶ次世代データストア

ほかのデータストアと比較

Page 60: PHPとMongoDBで学ぶ次世代データストア

RDBMS との違い• 分散が楽!– 様々な分散方法を標準搭載– MapReduce

• テーブル定義不要– 動的に構造を付け足したりできる– プログラミング言語の構造に密着

• JOIN はできない– MapReduce でカバー

• トランザクションはない– 銀行のシステムとか作りたいなら RDBMS でいいんじゃね?

Page 61: PHPとMongoDBで学ぶ次世代データストア

KVS との違い• KVS=Key-Value Store–Memcached 、 Tokyo

Cabinet/Tyrant 、 Flared 、 ROMA 、 BigTable、 etc…

• KVS よりは分散は大変– KVS は置くだけで分散できるものが多い

• KVS よりはデータ構造が存在する– KVS は単純に Key-Value の構造しかない(キー

での検索しかできない)–MongoDB は大体 RDBMS に近い設計手法で操

作ができる

Page 62: PHPとMongoDBで学ぶ次世代データストア

CouchDB との違い• 基本的には同じ• まだ比較できるほどの事例が存在しない• PHP で使うなら MongoDB のほうが楽• 若干用語とかが違う

Page 63: PHPとMongoDBで学ぶ次世代データストア

KVS

MongoDB

RDBMS

高速

高機能

Page 64: PHPとMongoDBで学ぶ次世代データストア

まとめ

Page 65: PHPとMongoDBで学ぶ次世代データストア

実用的に MongoDB を PHP で使うなら

• Lithium ( http://li3.rad-dev.org/ )– PHP5.3専用フレームワーク–MongoDB推奨で設計されている–チュートリアルももちろん MongoDB

• CakePHP用 DataSource– http://d.hatena.ne.jp/cakephper/

20100122/1264140610

• 単体ライブラリ–Mongodloid 、 Morph

Page 66: PHPとMongoDBで学ぶ次世代データストア

実際使えるのか?• もちろんレンタルサーバの類では不可• RDBMS より圧倒的に高速なので、高負荷

に耐えれるサービスを作るなら重要• トランザクションが重要になるサービス

では使えない• テーブル定義とか書かなくていいので、立

ち上げ時とか試行錯誤する時とかはものすごく簡単に書ける

Page 67: PHPとMongoDBで学ぶ次世代データストア

日本語の情報が少なくて…• 概念とかは CouchDB関係で調べれば近

いものが出てくる• 情報がないなら自分たちで発信しよう!– CakePHP用 datastore の作者は日本人だし

日本語の情報しか存在しないが、公式に掲載された

• 翻訳も積極的に!

Page 68: PHPとMongoDBで学ぶ次世代データストア

おわり