はじめてのmongodb

72
はじめての @doryokujin 日本UNIXユーザ会 勉強会 2011/09/15

Upload: takahiro-inoue

Post on 15-Jan-2015

19.769 views

Category:

Technology


2 download

DESCRIPTION

 MongoDBの初心者向け資料です。SQLとの比較からMongoDBを理解する章を中心に展開していきます。また、Replication・Shardingに関しては別章で詳しく紹介します。  この資料をきっかけに多くの方がMongoDBを知り、触れるきっかけになればと思います。

TRANSCRIPT

Page 1: はじめてのMongoDB

はじめての

@doryokujin日本UNIXユーザ会 勉強会 2011/09/15

Page 2: はじめてのMongoDB

・井上 敬浩(26歳)

・twitter: doryokujin

・データマイニングエンジニア

・MongoDB JP 代表

・NoSQLやHadoopに興味

・マラソン2時間33分

自己紹介

Page 3: はじめてのMongoDB

1. イントロダクション

2. SQL との比較で見るMongoDBの基礎

3. Replication

4. Sharding

5. その他の主要な機能

アジェンダ

Page 4: はじめてのMongoDB

1. イントロダクション

Page 5: はじめてのMongoDB

・[ニュース] InfoWorldが2011年のベストオープンソース賞「Bossies」を発表、MongoDB、Hadoop、LibreOfficeなどが受賞

・[コミュニティ] 9月24日(土) に「第6回MongoDB勉強会 in Tokyo」を開催予定

・[コミュニティ] 11月のMongoDB勉強会に ServerDensity の @davidmytton が来日・講演予定

・[コミュニティ] 1月に10genのエンジニアを招待して「MongoDB Conference in Japan#2」を開催予定!

最近のニュース

Page 6: はじめてのMongoDB

[開発元] 10gen http://www.10gen.com/

[実装] C++

[OS] Linux, Mac, Windows, Solaris

[由来] “Humongous”(ばかでかい)amounts of data

[ライセンス]

・Database: GNU AGPL v3.0 License

・Drivers: Apache License v2.0

イントロダクション

Page 7: はじめてのMongoDB

[ドキュメント指向DB] JSON(内部ではBSONで保持)

[完全なインデックスサポート] あらゆる属性でインデックス作成

[Replication] 自動フェイルオーバー・高可用性

[Sharding] 自動シャーディング

[Map/Reduce] フレキシブルな記述が可能

[クエリ] あらゆる条件で条件指定可能

[高速 In-Place Update] 高速なAtomic Modifiers

[GridFS] 巨大なファイルも保存可能http://www.mongodb.org/

MongoDB の特徴

Page 8: はじめてのMongoDB

Production Deployments

Page 9: はじめてのMongoDB

・NoSQL

・ドキュメントデータベース:データをJSON(内部ではBSON)で保持

・スキーマフリー

[CAP]

・RDBMS:一貫性(Consistency)+可用性(Availability)

・MongoDB:Cと分断耐性(Partition-tolerance)

・代わりにトランザクション・JOINを持たない

MongoDB の立ち位置

Page 11: はじめてのMongoDB

・ドキュメントデータモデル(JSON):関連のあるデータを1つのドキュメントにまとめる事によるパフォーマンス・マネジメント・コーディングを容易に

MongoDB の哲学

・トランザクションを廃止し、パフォーマンスとスケーラビリティを

・スキーマレスによる柔軟性を重視

・純粋なkey/valueストアよりも機能性と柔軟性を

http://www.mongodb.org/pages/viewpage.action?pageId=20743144

Page 12: はじめてのMongoDB

2. SQLとの比較で見る

MongoDB の基礎

Page 13: はじめてのMongoDB

MySQL Oracle MongoDB

mysql oracle mongod

mysqld sqlplus mongo

MySQL <--> MongoDB(実行コマンド編)

Page 14: はじめてのMongoDB

MySQL MongoDBdatabase databasetable collectionindex indexrow BSON Document

column BSON Fieldjoin embedding and inking

primary key _id field

MySQL <--> MongoDB(概念編)

Page 15: はじめてのMongoDB

MongoDB(Single Server)mongod

DatabaseA

CollectionA

Doc Doc DocDoc Doc DocDoc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

CollectionB CollectionC CollectionD

DatabaseB

Doc Doc DocDoc Doc DocDoc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc DocDoc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc DocDoc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Page 16: はじめてのMongoDB

{

"_id" : ObjectId("4dcd3ebc9278000000005158"),

"timestamp" : ISODate("2011-05-13T14:22:46.777Z"),

"binary" : BinData(0,""),

"string" : "abc",

"number" : 3,

"subobj" : {"subA": 1, "subB": 2 },

"array" : [1, 2, 3],

"dbref" : [_id1, _id2, _id3]

}

Document

Page 17: はじめてのMongoDB

{

"_id" : ObjectId("4dcd3ebc9278000000005158"),

"timestamp" : ISODate("2011-05-13T14:22:46.777Z"),

"binary" : BinData(0,""),

"string" : "abc",

"number" : 3,

"subobj" : {"subA": 1, "subB": 2 },

"array" : [1, 2, 3],

"dbref" : [_id1, _id2, _id3]

}

Document_id が常に primary key としての役割

row は BSON Field

column は BSO

N Docum

ent

他のドキュメントの _id への参照

Page 18: はじめてのMongoDB

MySQL MongoDBCREATE TABLE USERS (a Number, b

Number)自動生成 または

db.createCollection("collname")

ALTER TABLE users ADD ... 自動生成

INSERT INTO USERS VALUES(3,5) db.users.insert({ a:3, b:5 })

UPDATE users SET a=1 WHERE b='q' db.users.update({ b: 'q' }, { $set: { a: 1 }}, false, true)

UPDATE users SET a=a+2 WHERE b='q' db.users.update({ b: 'q' }, { $inc: { a: 2 }}, false, true)

MySQL <--> MongoDB(Insert/Update編)

Page 19: はじめてのMongoDB

operator 意味{ $inc : { field : value } } field へ value だけインクリメント

{ $set : { field : value } } field へ value をセット。全ての型をサポート

{ $push : { field : value } } array型のfieldに対して要素valueを追加

{ $pushAll : { field : value_array } } array型のfieldに対して配列value_arrayの要素を全て追加

{ $addToSet : { field : value } } field が空配列か存在しない場合に新たにvalueを持つ配列をセット

{ $addToSet : { a : { $each : [ 3 , 5 , 6 ] } } }

複数の値もセット可能

{ $rename : { old_field_name : new_field_name } }

field 名の変更

MySQL <--> MongoDB(Insert/Update編)

Page 20: はじめてのMongoDB

{

"_id" : ObjectId("4dcd3ebc9278000000005158"),

"timestamp" : ISODate("2011-05-13T14:22:46.777Z"),

"binary" : BinData(0,""),

"string" : "abc",

"number" : 3,

"subobj" : {"subA": 1, "subB": 2 },

"array" : [1, 2, 3],

}

padding

Document(Insert)

Page 21: はじめてのMongoDB

{

"_id" : ObjectId("4dcd3ebc9278000000005158"),

"timestamp" : ISODate("2011-05-13T14:22:46.777Z"),

"binary" : BinData(0,""),

"string" : "def",

"number" : 4,

"subobj" : {"subA": 1, "subB": 2 },

"array" : [1, 2, 3, 4, 5, 6],

"newkey" : "In-place"

}

{ $inc : {"number": 1} }

{ $set : {"string": "def"} }

{ $pull : {"subobj": {"subB": 2 } } }

{ $addToSet : { "array" : { $each : [ 4 , 5 , 6 ] } } }

{ $set : {"newkey": "In-place"} }

Document(Update)

Page 22: はじめてのMongoDB

MySQL MongoDB

SELECT a,b FROM users db.users.find( {}, { a: 1, b: 1 })

SELECT * FROM users db.users.find()

SELECT * FROM users WHERE age=33 db.users.find({ age: 33 })

SELECT a,b FROM users WHERE age=33 db.users.find({ age: 33 }, { a: 1, b: 1 })

SELECT * FROM users WHERE age=33 ORDER BY name db.users.find({ age: 33 }).sort({name:1})

MySQL <--> MongoDB(Query編)

Page 23: はじめてのMongoDB

MySQL MongoDB

SELECT * FROM users WHERE age>33 db.users.find({ age: { $gt: 33 }})

SELECT * FROM users WHERE age!=33 db.users.find({ age: { $ne: 33 }})

SELECT * FROM users WHERE name LIKE "%Joe%" db.users.find({ name: /Joe/ })

SELECT * FROM users WHERE name LIKE "Joe%" db.users.find({ name: /^Joe/ })

SELECT * FROM users WHERE age>33 AND age<=40

db.users.find({ 'age': { $gt: 33, $lte: 40 }})

MySQL <--> MongoDB(Query編)

Page 24: はじめてのMongoDB

MySQL MongoDBSELECT * FROM users ORDER BY name

DESC db.users.find().sort({ name: -1 })

SELECT * FROM users WHERE a=1 and b='q' db.users.find({ a: 1, b: 'q' })

SELECT * FROM users LIMIT 10 SKIP 20 db.users.find().limit(10).skip(20)

SELECT * FROM users WHERE a=1 or b=2

db.users.find( { $or : [ { a: 1 } , { b: 2 } ] } )

SELECT * FROM users LIMIT 1 db.users.findOne()

MySQL <--> MongoDB(Query編)

Page 25: はじめてのMongoDB

{

"_id" : ObjectId("4dcd3ebc9278000000005158"),

"timestamp" : ISODate("2011-05-13T14:22:46.777Z"),

"binary" : BinData(0,""),

"string" : "abc",

"number" : 3,

"subobj" : {"subA": 1, "subB": 2 },

"array" : [1, 2, 3],

}

db.coll.find({"number": 3})

db.coll.find({"number": {$gt: 1}})

db.coll.find({"subobj.subA": 1})

db.coll.find({"subobj.subB": {$exists: true} })

db.coll.find({"string": "abc"})

db.coll.find({ "string" : /^a.*$/i })

db.coll.find({"array": {$all:[1, 2]} });

db.coll.find({"array": {$in:[2, 4, 6]} });

Document(Query)

Page 26: はじめてのMongoDB

MySQL MongoDB

SELECT COUNT(*y) FROM users db.users.count()

SELECT COUNT(*y) FROM users where AGE > 30 db.users.find({ age: { $gt: 30 }}).count()

SELECT COUNT(AGE) from users db.users.find({ age: { $exists: true }}).count()

SELECT DISTINCT last_name FROM users db.users.distinct( 'last_name' )

MySQL <--> MongoDB(Aggregation編)

Page 27: はじめてのMongoDB

MySQL MongoDB

CREATE INDEX myindexname ON users(name) db.users.ensureIndex({ name: 1 })

CREATE INDEX myindexname ON users(name,ts DESC) db.users.ensureIndex({name:1, ts:-1})

EXPLAIN SELECT * FROM users WHERE z=3 db.users.find({ z: 3 }).explain()

DELETE FROM users WHERE z="abc" db.users.remove({ z: 'abc' })

MySQL <--> MongoDB(Other編)

Page 28: はじめてのMongoDB

・MongoDBのコマンドはJavaScriptベース

・JavaScriptのコマンドが利用可能

・SQLの持つほぼ全て(JOIN除く)コマンドを再現できる

・MongoDBのあらゆるフィールドにインデックスを作成することができる

・かつあらゆるフィールドの検索が可能

→ 他のNoSQLよりもデータ検索性が非常に優れている

特徴1

Page 29: はじめてのMongoDB

・MongoDBの多くの更新はアトミック

・MongoDBはドキュメント1つ1つにpaddingを持つ

・これによってドキュメントの更新が高速(In-place)

・padding はコレクションごとにオブジェクトの増加量から統計的に最適なサイズが設定される

・In-place Updateが常に行えるようなスキーマデザインを。これは embedded にするか dbref かの問題に関連

特徴2

Page 30: はじめてのMongoDB

・ディスクとメモリを大量に消費する

・例えばAmazonのsmallインスタンスでは使用困難

・64bit OS 向けに考えられたシステム

・インデックスがメモリに乗らなくなった時点でパフォーマンスが低下

・key/value や column データベースに比べて特に書き込みパフォーマンスは良くない

・その他たくさん

MongoDBの欠点

Page 31: はじめてのMongoDB

3. Replication

Page 32: はじめてのMongoDB

MongoDB(Single Server)mongod

DatabaseA

CollectionA

Doc Doc DocDoc Doc DocDoc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

CollectionB CollectionC CollectionD

DatabaseB

Doc Doc DocDoc Doc DocDoc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc DocDoc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc DocDoc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Page 33: はじめてのMongoDB

MongoDB(Replica Set)

SyncSync

Sync

PrimarySecondary Secondary

Page 34: はじめてのMongoDB

・MongoDB の Replication は2種類:

- Master/Slave: 典型的な 1 master - N slave 構成

- Replica Sets: 自動フェイルオーバー機能

・primary(master) - secondary(slave) 間は非同期通信

・Replication の設定・管理は非常に簡単

・Replication メンバーの追加・削除も非常に簡単

・slave からのデータ読み取り可能(書き込み不可)

Replication

Page 35: はじめてのMongoDB

[1] insert, update, delete などデータ変更オペレーションが行われる

[2] oplog collection にオペレーションが書き込まれる

[3] オペレーションが実際に primary データベースに反映

[4] secondary 達は常に primary の oplog を定期的に取得しにいく

[5] secondary は実際に自身の oplog のオペレーションを実行する

同期の方法

Page 36: はじめてのMongoDB

・1 master と 1 slave の最低2サーバーから構成可能

・slave は後から追加・撤退が容易に行える

・slave からの読み込みをサポート => Read Scaling

[コマンド]

Master Slave

$ mongod --master --dbpath /data/masterdb/ --rest

$ mongod --slave --source <masterhostname>[:<port>]

--dbpath /data/slavedb/ --rest

Page 37: はじめてのMongoDB

・最低3台のサーバーから構成可能

・secondary からの読み込みをサポート

・Sharding との連携で大規模データの運用も可能

・primary優先度など、メンバー毎に細かな設定が可能

[自動フェイルオーバー]

・現 primary サーバーのダウン時に、適切な secondary サーバーを新 primary に自動切り替える機能

Replica Set

Page 38: はじめてのMongoDB

・3台のサーバーでの最小構成例

Replica Set

$ mongod --replSet setname --rest

> config = {_id: 'mySet', members: [

{_id: 0, host: 'host1:27017', priority: 1.0},

{_id: 1, host: 'host2:27018’, priority: 0.5},

{_id: 2, host: 'host3:27019', priority: 0.0} ] }

> rs.initiate(config)

> rs.status() // 確認

Page 39: はじめてのMongoDB

[primaryダウン時の動作]

[1] 各メンバーは heartbeat で互いに通信しあい、通信できるメンバーを確認

[2] 現 primary ノードが通信不可能であることを確認

[3] arbiterでないメンバー間でネゴシエーション

[4] 時期primary選出のための票の投げ合いを行う。最終同期時間が最新でpriority値の高いメンバーに票が集まる仕組み

[5] あるメンバーの持つ票が過半数に達した時点で primary が決まる

Replica Set

Page 40: はじめてのMongoDB

[自動フェイルオーバー]

Member1Primary

Member2Secondary

Member4Secondary

Sync

SyncSync

Member3Secondary

1. Current Primary

Replica Set

Page 41: はじめてのMongoDB

[自動フェイルオーバー]

Member1Primary

Member2Secondary

Member4Secondary

Member3Secondary

2. Primary Down

Replica Set

Page 42: はじめてのMongoDB

[自動フェイルオーバー]

Member1Primary

Member2Secondary

Member4Secondary

Member3Secondary

3. Election Time

Negotiate Negotiate

Negotiate

Replica Set

Page 43: はじめてのMongoDB

[自動フェイルオーバー]

Member2Primary

Member4Secondary

Member3Secondary

4. New Primary

SyncSync

primary 選出基準1. priority 値が最大2. primary との最終同期が最新3. votes 値が高い

Replica Set

Page 44: はじめてのMongoDB

4. Sharding

Page 45: はじめてのMongoDB

MongoDB(Sharding)

mongod 1

DatabaseA DatabaseB

CollectionA Coll CollDoc Doc DocDoc Doc DocDoc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

Doc Doc DocDoc Doc Doc

DocDocDocDoc

Doc

Doc Doc DocDoc Doc Doc

DatabaseACollectionADoc Doc DocDoc Doc DocDoc Doc Doc

mongod 2

DatabaseACollectionADoc Doc DocDoc Doc DocDoc Doc Doc

mongod 3

mongod 1

DatabaseA DatabaseB

CollectionA Coll CollDoc Doc DocDoc Doc Doc

DocDocDocDoc

Doc

分割

Shard1

Shard2 Shard3

Page 46: はじめてのMongoDB

・クライアントの接続を mongos サーバーが仲介することによってクラスタ全体の情報を意識せず扱える

・クライアントは Sharding していない状況と同じようにクエリを発行し、結果を得ることができる

・Shardの 追加・撤退が容易にできる

・自動 Sharding 機能 が指定した Shard Key でデータ振り分けルールを自動決定・随時更新

・自動 Balancing 機能 が Chunk の移動を行い、Shard 間でデータの均質性を保つ

Sharding

Page 47: はじめてのMongoDB

Sharding のサーバー構成

config Servers (Shard Configration)

mongos Servers (Routers)

Shard Servers (Data)

[ a, f )

[ f, k )

[ k, n)

[ n, o )

[ o, t )

[ t, } )

shard1 shard2 shard3

Chunk

Cluster

Page 48: はじめてのMongoDB

サーバー間の関係

クライアントのアクセスは 必ず mongos に対して行う

該当データのある Shard にのみ クエリの送出・データの取得を行う

cinfig サーバーから Shard に関する情報を取得する

各Shardごとに書き込み先は1つ

( mongosがprimaryを自動選択 )

primary

Page 49: はじめてのMongoDB

自動 Sharding

DatabaseACollectionADoc Doc DocDoc Doc DocDoc Doc Doc

mongod 2

DatabaseACollectionADoc Doc DocDoc Doc DocDoc Doc Doc

mongod 3mongod 1

DatabaseA DatabaseB

CollectionA Coll CollDoc Doc DocDoc Doc Doc

DocDocDocDoc

Doc

mongosconfigshard 情報

ClientClient Client

データの自動振り分け

[自動 Sharding]

Shard1 Shard2 Shard3

DocDoc

Page 50: はじめてのMongoDB

DatabaseACollectionADoc Doc DocDoc Doc DocDoc Doc Doc

mongod 2

DatabaseACollectionADoc Doc DocDoc Doc DocDoc Doc Doc

mongod 3mongod 1

DatabaseA DatabaseB

CollectionA Coll CollDoc Doc DocDoc Doc Doc

DocDocDocDoc

Doc

mongosconfigshard 情報

ClientClient Client

Doc Doc DocDoc Doc DocDoc Doc DocDoc Doc Doc

shardの偏り!

[自動 Balancing 1]

自動 BalancingShard1 Shard2 Shard3

Page 51: はじめてのMongoDB

DatabaseACollectionADoc Doc DocDoc Doc DocDoc Doc Doc

mongod 2

DatabaseACollectionADoc Doc DocDoc Doc DocDoc Doc Doc

mongod 3mongod 1

DatabaseA DatabaseB

CollectionA Coll CollDoc Doc DocDoc Doc Doc

DocDocDocDoc

Doc

mongosconfigshard 情報

ClientClient Client

Doc Doc DocDoc Doc Doc Doc Doc Doc Doc Doc Doc

マイグレーション※マイグレーションは Chunk 単位

Shard1 Shard2 Shard3

[自動 Balancing 2]

自動 Balancing

Page 52: はじめてのMongoDB

Sharding チュートリアル

Client

mongosconfig

Shard01Shard00 Shard02

・最小限な構成例でセットアップ

・( Shard ) × 3 + config × 1 + mongos × 1

server1 server2 server3

Page 53: はじめてのMongoDB

[初期設定 from console]

・dbpath の作成。mongosは不要

・mongod、mongos サーバーの起動

~ mongod --shardsvr --port 27017 --dbpath shard/shard00~ mongod --shardsvr --port 27018 --dbpath shard/shard01~ mongod --shardsvr --port 27019 --dbpath shard/shard02~ mongod --configsvr --port 27020 --dbpath shard/config~ mongos --configdb localhost:27020 --port 27021

~ mkdir -p shard/shard00~ mkdir -p shard/shard01~ mkdir -p shard/shard02~ mkdir -p shard/config

Sharding チュートリアル

Page 54: はじめてのMongoDB

[初期設定 from mongo shell]

・Shardの追加➜ ~ mongo localhost:27021 // mongosに接続

MongoDB shell version: 1.8.0

connecting to: localhost:27021/test

> show dbs

config 0.1875GB // shardingのメタ情報を格納するデータベース

> db.adminCommand( { addshard: "localhost:27017", name: "shard00" } )

{ "shardAdded" : "shard00", "ok" : 1 }

> db.adminCommand( { addshard: "localhost:27018", name: "shard01" } )

{ "shardAdded" : "shard01", "ok" : 1 }

> db.adminCommand( { addshard: "localhost:27019", name: "shard02" } )

{ "shardAdded" : "shard02", "ok" : 1 }

Sharding チュートリアル

Page 55: はじめてのMongoDB

[初期設定 from mongo shell]

・Shardの追加(Sharding + Replica Set の場合)

・addshard: ”<Replica Set Name>/<menber1>,<member2>,...”

> db.adminCommand( { addshard: "set00/delta1:27017,delta2:27017", name:

"shard00" } )

{ "shardAdded" : "shard00", "ok" : 1 }

> db.adminCommand( { addshard: "set01/delta3:27018,delta4:27018", name:

"shard01" } )

{ "shardAdded" : "shard01", "ok" : 1 }

> db.adminCommand( { addshard: "set02/delta5:27019,delta6:27019", name:

"shard02" } )

{ "shardAdded" : "shard02", "ok" : 1 }

Sharding チュートリアル

Page 56: はじめてのMongoDB

[初期設定 from mongo shell]

・データベース/コレクションのShard有効化

・myshardコレクションを “ShardKey: n” としてShard化

・後は mongos サーバーに接続してデータを挿入するだけ!

// 引き続きmongosより

> db.adminCommand( { enablesharding : "test" } )

{ "ok" : 1 }

> db.adminCommand( { shardcollection : "test.myshard", key : { n : 1 } } )

{ "collectionsharded" : "test.myshard", "ok" : 1 }

Sharding チュートリアル

Page 57: はじめてのMongoDB

[参考資料]

・機能・仕組みの詳細についてはこちらを参照してください

参考資料

http://www.slideshare.net/doryokujin/mongo-sharding

Page 58: はじめてのMongoDB

5.その他の主要な機能

Page 59: はじめてのMongoDB

・サイズ固定のコレクション。サイズ以上のデータ挿入時は古いデータから自動削除・インデックスを持たないためファイル書き込みに迫る高速な書き込みパフォーマンスを持つ(インデックス作成可能)・コレクション内のデータを削除できない。drop()のみ。・Sharding不可能[用途]・logging サーバー・セッション情報の保持

Capped Collection

Page 60: はじめてのMongoDB

・※ ver.2.0 から標準機能に・データ書き込み前にオペレーションを journal ログに保存(先行書き込みログWAL)することでデータの安全性を向上

・100ms毎(デフォルト)に journal ログに書き込みが行われる(ver2.0 からこの書き込みタイミングの変更が可能に)・予期せぬサーバーダウンからの復帰もjournaling機能によってデータがリカバリーされる

http://www.mongodb.org/display/DOCSJP/Journaling

Journaling

Page 61: はじめてのMongoDB

[ダウンからのデータリカバリプロセス]

[1] クリーンシャットダウン時に journal サブディレクトリは削除

[2] サーバーダウン時には journal サブディレクトリはそのまま残る

[3] mongod は起動時に journal サブディレクトリが無いかチェック

[4] あればそのディレクトリ内の journal ファイルからダウン時に未実行だったオペレーションを実行する

・journal ファイルへの書き込みは 100ms 毎 (v.2.0から変更可に)

・書き込みは Group Commits を行って一度に高速処理

Journaling

Page 62: はじめてのMongoDB

・MongoDBは位置をベースにしたクエリをサポート

・そのために二次元の地理空間のインデックスが存在

・「自分の場所に近いN個のデータを取得」といった検索が可能

・v1.8では球面を考慮した検索が可能になった

・v1.8ではSharding環境でも使用できるようになった

地理情報インデックス

Page 63: はじめてのMongoDB

[領域検索]:$within クエリ + $box、$center、$polygon

・指定した長方形・円・多角形内に入っているオブジェクトを検索

地理情報インデックス

// v1.9 でサポート> polygonA = [ [ 10, 20 ], [ 10, 40 ], [ 30, 40 ], [ 30, 20 ] ]> polygonB = { a : { x : 10, y : 20 }, b : { x : 15, y : 25 }, c : { x : 20, y : 20 } }> db.places.find({ "loc" : { "$within" : { "$polygon" : polygonA } } })> db.places.find({ "loc" : { "$within" : { "$polygon" : polygonB } } })

// 中心と半径を指定> center = [50, 50]> radius = 10> db.places.find({"loc" : {"$within" : {"$center" : [center, radius]}}})

// 左下と右上の座標を指定> box = [[40.73083, -73.99756], [40.741404, -73.988135]]> db.places.find({"loc" : {"$within" : {"$box" : box}}})

Page 64: はじめてのMongoDB

GridFS・MongoDBは1ドキュメント当たり16MB制限が

・GridFSはそれ以上の単一ファイルの保存を可能に

・ファイルを複数のドキュメントに透過的に分割してバイナリ保存している

・画像、音楽、動画ファイルも保存可能

・Sharding 可能(ただしfile単位で)

・S3やNFSの代替えとして考えられていた

Page 65: はじめてのMongoDB

GridFS➜ ~ mongofiles list connected to: 127.0.0.1

➜ ~ mongofiles put music1.mp3 connected to: 127.0.0.1added file: { _id: ObjectId('4df17f8d9d47ba5c0247e72e'), filename: "music1.mp3", chunkSize: 262144, uploadDate: new Date(1307672462538), md5: "9ee9472200a2e18bf376ce622c3b0055", length: 11183104 }done!

➜ ~ mongofiles list -v // -vオプションで詳細な出力Fri Jun 10 11:21:05 creating new connection to:127.0.0.1Fri Jun 10 11:21:05 BackgroundJob starting: connected to: 127.0.0.1music.mp3 11183104

Page 66: はじめてのMongoDB

GridFS➜ ~ mongofiles put music2.mp3connected to: 127.0.0.1added file: { _id: ObjectId('4df181fc5e354129e833193f'), filename: "music2.mp3", chunkSize: 262144, uploadDate: new Date(1307673086293), md5: "9d4f424fa1843711e196e502d8a00183", length: 12225353 }done!

➜ ~ mongofiles listconnected to: 127.0.0.1music1.mp3 11183104music2.mp3 12225353

➜ ~ mongofiles search .mp3connected to: 127.0.0.1music1.mp3 11183104music2.mp3 12225353

Page 67: はじめてのMongoDB

MapReduce・Sharding環境でMapReduceを実行する事で分散データ処理が可能

・Shuffle機能が無い等、Hadoop等に比べて簡易的実装

・JavaScriptエンジンの制約を受ける:1スレッド/Shard

・ある程度仕組みを知らないと正しい結果が得られない

・集約関数の拡張として捉えてもらった方が気軽に扱える

・v1.8でoutputオプションが充実して扱いやすくなった

Page 70: はじめてのMongoDB

まとめ

Page 71: はじめてのMongoDB

まとめ・MongoDB は RDB からの移行がスムーズに行える

・かつ大規模データに対するスケーラビリティを持つ

・そのための Replication, Sharding 機能を容易に扱える

・スキーマフリーがもたらすデザインの自由度

・JavaScript ベースで扱いやすく、node.js との親和性

・地理情報インデックスなどのwebに特化した機能

是非とも一度 MongoDB を触って見て下さい!

Page 72: はじめてのMongoDB

ありがとうございました