今回は、
新機能ダイジェスト
- 1.並列処理の強化
(Concurrency Improvements) - ロックの粒度がGlobalロックからDBロックになりました。
- PageFaultアーキテクチャが改善されロック時間が減りました。
- 2.Aggregation Framework
- 集計処理がコマンドで可能になりました。
- 3.Replica SetsのReadノード選択
- 一貫性レベルに応じて、
どのノードからデータをReadするかを選択可能になりました。 - 4.Tagを使用したSharding
(Improved Data Center Awareness) - データ保存先のShardをTagで指定可能になりました。
- 5.TTL
(Time To Live) Collections - 一定時間で削除されるCollectionを定義可能になりました。
- 6.その他の変更点
- 今回は省略します。第3回丸の内勉強会の資料を参照ください。
並列処理の強化(Concurrency Improvements)
並列処理の強化のために2つの大きな改善が入りました。ロックレベルに関するものとPage Faultに関するものです。どちらも利用者が意識することなく利用できる機能です。
ロックレベル
ロックの粒度がv2.
次のステップであるCollectionレベルロックでは多くのユーザに恩恵があると思われますが、
Page Faultアーキテクチャ
MongoDBはメモリキャッシュ機能を持っています。高速なReadを実現するためにpageと言う単位でデータをメモリに保持しています。メモリ内に無いデータはディスクからロードすることになりますが、
v2.
Aggregation Framework
Aggregation Frameworkは、
たとえば、
SELECT name as '_id', AVG(score) as 'average' FROM scores
WHERE year = 'junior'
GROUP BY = name
db.scores.aggregate(
{ $match : { "year" : "junior" } },
{ $project : { "name" : 1, "score" : 1 } },
{ $group : { "_id" : "$name",
"average" : { "$avg" : "$score" } } }
);
パイプラインに組み合わせることができるオペレータは以下のものがあります。
| オペレータ名 | 処理 |
|---|---|
| $match | 条件で絞り込みを実施 |
| $project | 集計処理を行うフィールドの選択/除外、 |
| $unwind | 指定された配列の展開を実施 |
| $group | $sum, $avgなどを使い集計処理を実施 |
| $sort | 指定されたsortキーによるソートを実施 |
| $skip | 指定された数字分スキップして次の処理へ渡す |
| $limit | 指定された数字分の結果を次の処理へ渡す |
Readノードの選択
システムで保証する一貫性のレベルに応じて、
| 設定名 | 意味 |
|---|---|
| PRIMARY | PRIMARYノードのみからReadする |
| PRIMARY PREFERRED | 可能であればPRIMARYノードからReadする |
| SECONDARY | SECONDARYノードのみからReadする |
| SECONDARY PREFERRED | 可能であればSECONDARYノードからReadする |
| NEAREST | レイテンシの小さいノードからReadする※ |
Tagを利用したSharding
Shardingに参加しているノードにTagを追加しTagRangeを設定することで、
> sh.addShardTag("shard0000", "TokyoDC");
> sh.addTagRange("appdb.users", { "uid" : 1 }, { "uid" : 100 }, "TokyoDC");
TTL(Time To Live) Collections
一定時間が経過した後、
起点とするフィールドに{"expireAfterSeconds":数値}というハッシュを第二引数に入れてensureIndex()でインデックスを作成することで、
制限として、
// eventsコレクションのデータを、created_atフィールドを起点に30秒後に
// 削除されるように設定
> db.events.ensureIndex( { “created_at”: 1 }, { expireAfterSeconds: 30 } )
// statusにはdate-type型を入れる。new Date()でOK
// statusがdata-type型以外、またはcreated_atが無いデータは消えない
> db.events.insert( { "myid" : 1, "created_at" : new Date() } );
> db.events.insert( { "myid" : 2, "created_at" : "String" } );
> db.events.insert( { "myid" : 3, "time_field" : new Date() } );
> db.events.count();
// => 3
//30秒後
> db.events.count();
// => 2
> db.events.find({},{"_id":0})
{ "myid" : 2, "created_at" : "String" }
{ "myid" : 3, "time_field" : ISODate("2012-11-28T16:04:19.781Z") }
// "myid" : 1 のデータが消えている
次回のテーマ
今回はv2.
MongoDBと他のNoSQLを比較した場合の特徴のひとつとして、
