ページの先頭です
2012年8月21日
NoSQLのオープンソースプロジェクトの中でも人気の高いMongoDB最新機能についてご紹介します。最新の安定版である2.2*系で最も注目すべき機能は、Aggregation Frameworkです。なお、2.0系より前のバージョンでは使えない機能なのでご注意ください。
* MongoDB 2.2.0-rc0(2012年8月9日執筆時点)
NoSQLの登場により「ハイパフォーマンス」や「スケーラビリティ」を手に入れた一方で、失った物がいくつかあります。そのうちの1つが「データの操作性」です。特に「データの集計」について、多くの開発者は、MapReduceを利用することでしのいでいると思います。
MongoDBでMapReduceを行う場合は、JavaScriptでコードを書くことになります。これにより、JavaScript故のパフォーマンス問題に直面することが容易に想像されます。
MongoDB 2.2で登場した新機能が、これまでMapReduceで補完していたデータの操作性を向上させられるAggregation Frameworkです。この新機能の登場でJavaScriptは不要となり、MongoDBに対するコマンドの一部として実行できるようになりました。中でも、SQLでGROUP BY句に相当する$groupについては、非常に分かりやすいのでこれを取り上げてみます。
IIJの様々なサービスの中で我々が日々直面しているタスクの1つである「膨大なログデータの集計」が、Aggregation Frameworkを使うことで、どのようなことが可能になるかをご覧ください。対象となるログデータはapache combined形式で、複数のサーバからfluentdなどを使うことで常にMongoDBに更新され続けているという状況を想定し、以下の結果を得ることを目的とします。
条件:7月10日、昼のピーク時である10時から14時までの間の転送量をFQDN単位で出す。ただし、対象は正常な応答のみとする。
> db.access_log.aggregate(
{ $match :
{ time :
{ "$gte" :ISODate("2012-07-10T10:00:00Z"),
"$lte" : ISODate("2012-07-10T14:00:00Z")}}},
{ $match : { system_status : 200 }},
{ $group : { _id : "$domains",
TotalBytes : { $sum : "$transfers" } }}
)
...
{
"result" : [
{
"_id" : "iijgio_is_awesome.jp",
"TotalBytes" : 3048576090
}
],
"ok" : 1
}
Aggregation Frameworkが追加される前であれば、MapReduceを用いた処理を1時間おきに呼び出し、最後に日次集計を実行という処理をされていたと思います。しかし、2.2以降であれば、コマンド1つで集計が可能になりました。今回は、$matchと$groupを組み合わせましたが、これに限らず非常に強力なオペレータが用意されていますので、是非ともお試しください。
なお、誤解を与えないように補足をしますが、Aggregation Frameworkが登場したことでMapReduceがもはや不要となったという短絡的な結論ではありません。「様々な条件、状況によって取り得る最適な手段の1つとして、Aggregation Frameworkという選択肢が増えた」と私たちは捉えています。
Aggregation Frameworkにも課題はあります。現在の2.2.0では、explain()が取得できません。これはMongoDB開発元の10genでも早急に対処すべく、2.3系で実装する予定だということです。となると、安定版へのマージは2.4が最短となるでしょう。
2.2における新機能は、他にもあります。
最後に、非公開の情報ではありますが、2.4ではMongoDBを使う大多数の技術者が期待しているShardingの新機能も実装することになっているようです。引き続きMongoDBの動向に目が離せないでしょう。
執筆者プロフィール
福田 信一(ふくだ しんいち)
IIJ プロダクト本部 基盤プロダクト開発部 配信技術課
2001年7月IIJ入社。髭が生えていますが、伸ばしたいわけではなくカミソリ負けするのが嫌なだけ。FC Barcelonaを心から愛しているため、白いチームを応援する人とは仲良くなれません。
ページの終わりです