Ruby Freaks Lounge
第31回 RubyistのためのMongoDB入門(1)
はじめに
ここ最近,NoSQLというキーワードが注目を集めています。
リレーショナルデータベースは,一般的にスケールアウト(サーバの台数を増やして性能向上を図る手法)が難しく,特に大規模サービスにおいてパフォーマンス上のボトルネックとなりえます。また,タグやグラフ構造のようなデータは関係モデルに馴染みにくいため,それらを扱う際にはアプリケーションコードもぎこちないものになりがちです。
これらの問題を背景に,何にでもリレーショナルデータベースを使うのではなく,用途に応じてKVSなど他のデータストアを選択する流れが広まりつつあります。このムーブメントがNoSQL(Not Only SQL)と呼ばれているものです。
今回は,NoSQLなデータベースの1つであるMongoDBをご紹介します。
MongoDBとは
MongoDBは高いパフォーマンスとスケーラビリティを特徴とするドキュメント指向型データベースです。GNU AGPLv3を採用したオープンソースソフトウェアで,開発母体である10gen, Inc.によって商用サポートが提供されています。
MongoDBの代表的な機能は以下のとおりです。
- JSONをベースとしたスキーマレスなデータモデル
- B-treeインデックスをサポートする高速なクエリ
- Master-Slave Replicationに加え,Replica Pairsによるフェイルオーバー構成を選択可能
- 分散データベースを実現するSharding
- 分散処理機構MapReduce
- バイナリデータを効率的に扱う仮想ファイルシステムGridFS
- ストリーミングやロギングに適したCapped Collections
- 各種言語用のドライバが提供されている(もちろんRubyも)
MongoDBは,いわゆるNoSQLデータベースの中でも機能が豊富な部類に入ります。リレーショナルデータベースの機能性とKVSの速度を合わせ持つことを狙いとして開発されています。
図1 MongoDBの位置付け

しかし,MongoDBは設計上の判断によりトランザクションやJOINをサポートしていません。Atomic Operationsやスキーマ設計の工夫によりある程度解決することはできますが,本質的にリレーショナルデータベースの機能が必要となる場面では力不足です。
それでは,MongoDBに適した分野は何でしょうか。いくつか事例を見てみましょう。
- The Business Insider
The Business Insiderは,一日に60万以上のPVがあるサイトのバックエンドとしてMongoDBを採用しました。理由として「スケーラブル」「動的言語との相性の良さ」「スキーマ構成の柔軟さ」などが挙げられています。1つのMongoDBサーバでCPU利用率は5%程度に収まっているとのことです。
- BoxedIce
BoxedIceは,サーバ監視システムで使用するデータベースをMySQLからMongoDBに移行しました。主な理由として管理面の問題が挙げられています。MySQLのレプリケーションは特に初回の同期が遅く,将来的なスケーリングにも不安があったため,NoSQLデータベースを比較検討した結果MongoDBを採用した顛末が綴られています。
また,同社のサービスはアカウントの管理や請求処理などには引き続きMySQLを使用しているそうです。
- その他の事例
他にもSourceforgeやGitHub,New York TimesなどのサービスでMongoDBが採用されています。
これらの事例から,MongoDBは性能を要求される大規模なサービスでの使用に向いていると言えそうです。
基本的な使い方
MongoDBのインストールはとても簡単です。ダウンロードページからお使いの環境に合うものをダウンロード・展開してください。今回は記事執筆時点での最新安定版であるバージョン1.2.2を使います。
% wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-1.2.2.tgz % tar xf mongodb-linux-x86_64-1.2.2.tgz
※アーカイブ名・ディレクトリ名は,環境に合わせて適宜読み替えてください。
アーカイブを展開した中のbinディレクトリに各種実行ファイルが収められています。まずはサーバ本体のmongodを起動しましょう。--dbpathオプションに適当なディレクトリを指定してください。そこにデータベースが作られます。
% cd mongodb-linux-x86_64-1.2.2/bin % mkdir -p ~/tmp/mongodb % ./mongod --dbpath ~/tmp/mongodb Mon Feb 8 07:09:16 Mongo DB : starting : pid = 24059 port = 27017 dbpath = /home/ursm/tmp/mongodb master = 0 slave = 0 64-bit Mon Feb 8 07:09:16 db version v1.2.2, pdfile version 4.5 Mon Feb 8 07:09:16 git version: 8a4fb8b1c7cb78648c55368d806ba35054f6be54 Mon Feb 8 07:09:16 sys info: Linux domU-12-31-39-06-79-A1 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_41 Mon Feb 8 07:09:16 waiting for connections on port 27017
別のターミナルで対話型シェルのmongoを起動します。オプションを指定しない場合はlocalhostのデフォルトポート(27017)に接続します。
% ./mongo MongoDB shell version: 1.2.2 url: test connecting to: test type "help" for help >
このシェルは実のところSpiderMonkeyをエンジンとしたJavaScriptコンソールです。計算からメソッド呼び出しまで一通りのことができてしまいます。
> a = 1 + 1 2 > 'hello'.toUpperCase() + a HELLO2


