MongoDBでゆるふわDB体験

第2回 MongoDB 2.2の新機能

この記事を読むのに必要な時間:およそ 3 分

Readノードの選択

システムで保証する一貫性のレベルに応じて,Replica Setsのノード群の中でどのノードからReadするかを選択可能となりました。一貫性レベルが強い順に以下の5段階が設定できます。システムにデータの強い一貫性が求められる場合はPRIMARYに,結果整合性※1でも十分な場合にはそれ以外に設定してReadの性能と可用性を向上させることが可能となりました。

設定名 意味
PRIMARY PRIMARYノードのみからReadする
PRIMARY PREFERRED 可能であればPRIMARYノードからReadする
SECONDARY SECONDARYノードのみからReadする
SECONDARY PREFERRED 可能であればSECONDARYノードからReadする
NEAREST レイテンシの小さいノードからReadする※
※1 結果整合性
書き込みが行われたPRIMARYノードからReadを保証せず,状況や設定によってSECONDARYノードからREADする。最新の状態が反映されているかどうかは保証されないが,可用性と性能は向上する(例:DNS⁠⁠。

NEARESTに設定すると,以下のアルゴリズムでReadするノードを決定します。

「ドライバからReplica Setsにpingをし,15ms以内で返ってきたノード群から1台選択」

設定はアプリケーションのコード中で行います。

Rubyでの設定例

@collection.find({:doc => 'foo'}, :read => :primary)    #primaryノードからReadする
@collection.find({:doc => 'foo'}, :read => :secondary)  #secondaryノード群からReadする

Tagを利用したSharding

Shardingに参加しているノードにTagを追加しTagRangeを設定することで,指定したレンジのデータを任意のノードに格納することが可能になりました。この機能により,uid=1~100のデータは東京データセンターのノード,uid=101~200のデータはNew Yorkデータセンターのノード,というDR(ディザスタリカバリ)を考慮したデータ配置が可能となります。2.2の目玉機能のひとつで,前述のReadノードの設定と合わせて"Data Center Awareness"※2と表現されています。

設定例

> sh.addShardTag("shard0000", "TokyoDC");
> sh.addTagRange("appdb.users", { "uid" : 1  }, { "uid" : 100  }, "TokyoDC");

図4 大陸間をまたがったHA構成の例

図4 大陸間をまたがったHA構成の例

※2 Awareness(アウェアネス)
ある問題に対する人々の知識の程度,危機・問題意識の高さ,といった意味

TTL(Time To Live) Collections

一定時間が経過した後,データが削除されるTTL Collectionsが定義可能になりました。

起点とするフィールドに{"expireAfterSeconds":数値}というハッシュを第二引数に入れてensureIndex()でインデックスを作成することで,起点に入力されたdate-type型から計測して,先ほどexpireAfterSecondsのvalueとして入れた数値秒後にドキュメントデータが削除されます。

制限として,データサイズ上限が決められるCapped Collectionsでは使用できません。

TTL Collectionsの例

// 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.2で追加/改善された主な機能を紹介しました。次回はMongoDBのクエリに関して説明します。

MongoDBと他のNoSQLを比較した場合の特徴のひとつとして,JOINを除くほぼすべてのSQLを再現できることが挙げられます。スムーズな理解につながるよう,SQLと比較しながらMongoDBのクエリを紹介していきます。

著者プロフィール

藤崎祥見(ふじさきしょうけん)

野村総合研究所 OpenStandia所属。オープンソースのR&Dとセミナー講師を担当。

Debian,Ubuntu,Liferayのコミュニティで活動した後,MongoDBの翻訳に関わり,丸の内MongoDB勉強会を始める。

実家がお寺で,住職の資格を所持する坊主系エンジニア。

Twitter:@syokenz