223 Software

主に勉強したことなどを記録するログです。 最近はRuby, Railsなどが多め。

MongoDB - 223 Software

第3回 MongoDB JP 勉強会 in Tokyo に参加しました

第2回(第2回 MongoDB JP 勉強会 in Tokyoに参加してきた)に引き続き、第3回 MongoDB JP 勉強会 in Tokyoに参加してきました。

心に残ったところをまたメモ程度にまとめます。

MongoDB 全機能チュートリアル & v1.8-1.9 新機能チュートリアル

@doryokujinさん
資料:http://www.slideshare.net/doryokujin/mongodb1

MongoDBの機能から、大まかに以下の項目を除いた全機能を網羅する大作でした。

  • Shading
  • MapReduce
  • GridFS
  • 地理情報index

あまりに大作なのでメモが追いつきませんでした。
特に注意しておこうと思った項目だけ並べますが、詳しくは資料を要参照。

また、資料中にはそれぞれドキュメントの該当箇所へとリンクを入れてくださっています。

mongodについて
  • ひとつのmongodに対してはシングルスレッドしか使えず、また多くのオペレーションに対してロックがかかる。
  • このロックはDB全体に対してかかるもので、Collection単位のロックは未実装。
    (おそらく、JavaScriptへの依存が問題であり、v2.0〜2.2で改善予定とのこと。)

ただしトランザクションがあるわけではないので、例えば1万ドキュメントをinsertする処理を走らせている最中に全く他のこと(書き込み系の処理)ができないわけではなく、insertの間に処理が割り込むために「ロック」をRDBMSほど気にしなくても大丈夫。

mongosについて
  • Sharding環境におけるルーティングサーバー
  • 自身はデータをストレージしない
databaseについて
  • 64bitを推奨
  • 32bitモードでは全てのdatabaseで2GBに容量が制限されてしまうため非現実的
BSONについて
  • 3種類の整数表現を持っている(int32, int64, double)故の曖昧さ
  • オブジェクト要素の出現順序に依存
    {'a': 1, 'b': 2} != {'b': 2, 'a': 1}(この特徴が後述のDot Notationの推奨にもつながる)
  • ただし上記の曖昧さ、順序問題は各種言語ドライバが吸収してくれている
Capped Collection
  • サイズが固定で、古いドキュメントから順に削除される
  • 書き込みのパフォーマンスが高い(ファイル書き込みレベル)
  • Capped Collection内のデータを削除することはできず、削除するならCollection自体を削除
  • デフォルトでは_idにもindexが作成されない
  • Readも挿入順 .sort({$natural: 1})で行うのが高速
  • Sharding不可能

上記のように尖った機能です。要はログファイルに最適とのこと。
MongoDBってアプリケーションのDBというよりはログ解析に本当に向いているなぁ、という印象がこのへんでさらに強くなります。

Buk Insert
  • 複数のドキュメントを配列としてinsertの引数として渡すと、高速にinsertしてくれる
  • ただし、最適な配列内のデータ数はデータに依存し、多く渡し過ぎるとエラーも
insertの注意
  • デフォルトは "Fire & Forget" なので、insertが成功している保証はない
  • しかし、ドライバ側が "safe write" などの名称で実装済み
  • 複数のコマンドに対するtransactionは無いので注意が必要
getLastError()

オペレーションの最後に起こったエラーを返すコマンド。(重要)

> db.getLastErrorObj() // 全てのエラーのオブジェクトを返す
> db.getLastErrorObj().ok // true or falseを返す
fsync
  • メモリ上の全てのデータをディスクにフラッシュ
  • デフォルトでは60秒毎にfsyncコマンドが実行されている
  • コマンドラインオプション --syncdelay で変更可能だが、変更は推奨されていない
  • ロックをかけるために使うこともある
Journalファイル
  • 自動的にローテーションされる
  • クリーンシャットダウン時には削除されるが、ダウン時には残る
  • journalファイルがある状態でサーバーが起動された場合、未実装の処理が自動的に行われる
  • journalファイルへの書き込みは100ms毎
Query
  • db.users.find().snapshot();
    同じデータを重複して取ってきてしまうことがあるため、それがまずい場合はshapshot()を使う。
    (updateがかかってドキュメントの容量が大きくなり、移動が起こったケース)
  • db.users.distinct('column')はインデックスがないと重いかも。
Dot NotationとSub Object
  • [Dot Notation] > db.blog.findOne({'author.name': 'Jane'})
  • [Sub Object] > db.blog.findOne({'author': {'name': 'Jane', 'id': 1}})

Shellからの比較はBSONにおける比較なので、出現順序と要素数がともに一致しないといけない。
そのため、Dot Notationが推奨される。

JavaScript表現

以下の4つは同じクエリ

> db.myCollection.find( { a: {$gt: 3} });
> db.myCollection.find( { $where: "this.a > 3"} )
> db.myColleciton.find("this.a > 3");
> f = function() { return this.a > 3; } db.myCollection.find(f);
削除系
> use myDB
> db.dropDatabase();

> db.mycoll.remove({}); // 全削除
> db.mycoll.remove({n: 1});
> db.videos.remove({rating: {$lt: 3.0}, $atomic: true});
  // ドキュメントの削除の途中に他の処理が割り込んでしまうのを$atomicでブロック
> db.mycoll.drop(); // 非常に高速な全削除
update

シングルdocumentに対してatomicな操作をするmodifierが用意されている
$set, $unset, $inc, $push, $pushAll, $pull, $pullAllなど

オブジェクトサイズが増えない場合はin-place updateという高速な処理が行われる

1回のupdateで複数のdocumentを同時に更新するときに他の書き込みをブロックするための$atomicが用意されている

> db.students.update({score: {$gt: 60}, $atomic: true}, {$set: {pass: true}});
index

バックグラウンドでのindexの生成が可能で、基本的にはバックグラウンドでやると良い

> db.things.ensureIndex({x: 1}, {background: true});

埋め込みdocumentに対してはDot NotationでのensureIndexが良い

> db.factories.ensureIndex({'metro.city': 1});

複合インデックス

> db.mycoll.ensureIndex({'a': 1, 'b': 1, 'c': 1});

Sparseインデックス
sparseインデックスで登録されたキーを持っていないドキュメントは対象外
現在はsparse indexは1つのフィールドに対してのみ

Unique index
_idはunique index

> db.things.ensureIndex({firstname: 1, lastname: 1}, {unique: true});

indexが効いているかどうかはexplain()を使う。

> db.comments.find({tags: 'mongodb'}).sort({created_at: -1}).explain();

Sharding環境ではunique indexの一意性が保証されない。

Replication

MongoDBのレプリケーションは2種類ある。

  1. Master-Slave
    マスタースレーブ
  2. Replica Sets
    自動フェイルオーバー・自動リカバリ機能あり
    primary - secondary間は非同期通信

local データベースにレプリケーション関連の情報が入っている。また、oplogというCapped Collectionにdbに対して実行されたオペレーションが記録される。

Replica Setsを構成するには最低でも3台のサーバーが必要。これは障害時に次のprimaryを選出する『投票』という機能があるが、2台では投票によって全体の過半数の票を獲得できないため。 ノードタイプには以下の3種類があるため、最低3台の条件をクリアするためにArbiterタイプを使うのも有効。

  • Standard
    普通のノード
  • Passive
    primaryにならない
  • Arbiter 次のprimaryを決める際にだけ使われるノード

Shardingとの連携で大規模データの運用もできるが、必要なサーバー数も跳ね上がる。
それぞれのshardに対してReplica Setを構成する。さらにmongosやconfigサーバーも必要。

フェイルオーバーには最低30秒〜数分かかる。

バックアップ

ロックする方法

  1. fsyncコマンドでdbをロック
  2. バックアップを行う(ディレクトリコピー、cloneコマンドなど)
  3. アンロック

ロックしない方法

  • mongoexport(json, csvでエクスポート) - mongoimport
  • mongodump(bsonでエクスポート) - mongorestore
  • wordnik-oss

「ソーシャルアプリのプロトタイプ制作にMongoDBを活用」

@bibrostさん
資料:http://www.slideshare.net/fungoing/mongodb-7948933

ソーシャルアプリのプロトタイプにMongoDBを使っているというお話でした。

毎週毎週動作するアプリケーションをリリースするアジャイルな開発を行うにあたって、プロトタイプにMongoDBを使う方法で進めているそうです。

大きなポイントは2つかと思います。

  1. PHPからはSleepy.Mongooseを使って構築されたRESTのインターフェイスに対し、json_encode/decode + php_curlでアクセスしている。
  2. 最終的(ある程度固まってきた時点)にはMySQLに全面移行する。

1に関しては、アプリケーションサーバーに余計なモジュールを入れたくないことと、ソーシャルアプリという特性からjson_encode/decode + php_curlは入っているために手間がかからないことが理由とのことです。

2に関しては質問、懇親会でも盛り上がりました。以下のような内容で参加者間でもやりとりがされていました。

  • どの時点をもってMySQLへ移行するか。
  • 何をもって完成形のスキーマとみなすか。
  • MySQLへの移行は具体的にどのように行うか。(現在のDBアクセスライブラリで抽象化して吸収?ある程度書きなおし?)
  • そもそも本当に全部MySQLに移行できるのか。

MongoDBであることを意識させずに、RESTのインターフェイスを構築しそれに対してcurlでアクセス、という作りは疎結合で魅力があるな、と感じました。また、MySQLへの移行に関しては最終的にどうなったのか、今後続報が知りたいところです。
(MongoDBをメンテナンスできるエンジニアが少ない、とのことでオトナの事情もあり頑張ってMySQLに置き換える、に一票。)

また、資料のP.47のUse caseの表が適切である、と当日も評判でした。

MongoDBチューニング

@matsuou1さん
資料: http://www.slideshare.net/matsuou1/20110514-mongo-db

以下の4つを目標として話してくださいました。

  1. オプティマイザの概要を理解する。
  2. 実行計画を取得し、読めるようになる。
  3. 遅いクエリを特定できる。
  4. 簡単なクエリのチューニングが出来る。

MongoDBではRDBMSのオプティマイザとは全く違う方法で実行計画を選択するそうです。

資料にはslowクエリの記録の方法やexplain()の結果の読み方も掲載されています。

NoSQLとは言え、チューニングの方法は意外とRDBMSと似たところがあるんだな、と個人的には感じました。

MongoDBを使用したモバイルゲーム開発について

@ygenkiさん
資料: http://www.slideshare.net/ygenki/mongodb-7962043

MongoDB + Javaで開発した東京ガールズスナップというアプリの開発事例をご紹介してくださいました。

まずMongoDB採用の理由として以下の3点を挙げられていました。 1. ドキュメントの階層構造 2. Replica Set & Sharding 3. MySQL + memcachedからの移行

今回のアプリの構成上、ユーザーの作成した写真をユーザデータの配列に$push, $pullする設計にしたそうです。

また、アプリの特性上(小さめの)バイナリデータを頻繁に出し入れすることになりますが、画像データのキャッシュストアとしてもMongoDBを使っているそうです。

当初はShardingを行うことも視野に入れていましたが、Sharding無しでも十分にパフォーマンスが出たこと、データ量が少ないこと、Shardingを行うと必要なサーバ台数が増加することから、現状では行っていないそうです。

スキーマレスゆえに仕様変更や機能追加が行いやすいことからモバイルゲームとの相性が良く、例えShardingを行わないとしても十分にメリットは多いとのことでした。

感想

懇親会などで色々な方に話を聞くと、アプリケーションのDBとしてMongoDBを採用したという例は少なく社内の管理アプリやログ解析に使われている、という方が多いようでした。(それ以上に、使ってみたいけど会社ではそこまで勇気を持って踏み出せない、という方が多いみたい。)

今回の勉強会の内容からも、どうもMongoDBはそういった裏側のシステムに特性があるのかなぁ、という感想です。

例えばRailsでアプリを開発することを考えたとき、スキーマの変更や開発者間でのスキーマの同期などはmigrationの仕組みでカバーされています。(もちろん本番環境でのスキーマ変更に当たっては停止時間など考慮に入れる必要がありますが)

すると、MongoDBを使うことによるメリット・デメリットはどのへんにあるのかなぁ、とちょっと疑問に思ってしまいました。
データの階層構造もActiveRecordで表現できますし・・・。

要は使いどころなんだと思います。なんでもかんでもMongoDBとかMySQLという風に思考停止するのではなく、要件に合わせて適切なミドルウェアを選択できるよう、しっかり勉強したいと思いました。

CloudFoundryでNode+MongoDBを動かした

先週末の開発コンテスト24の合間にチャレンジしていたのですがうまく動かず、さきほどようやく動かせました。

コツは3つ。

  1. npm bundleで必要なライブラリをインストールする
  2. 環境変数からMongoDBへの接続情報をとり出す
  3. vmc envでNODE_ENVを設定する

npm bundleで必要なライブラリをインストールする

今回動かしてみたのはexpressのアプリです。(NodeでMongoDBをいじってみた参照)
ちなみに"$ express -s -c sass"のコマンドで生成しています。

Nodeアプリを動かすには動作に必要なライブラリも一緒にCloudfoundryにアップする必要があり、その方法がnpm bundleです。
ちょっと手間がかかるのですが、まずはpackage.jsonというファイルを用意します。

{
  "name": "instanode",
  "version": "0.0.1",
  "dependencies": {
    "express":"",
    "jade":"",
    "less":"",
    "mongodb":"",
    "socket.io":"",
    "instagram":""
  }
}

dependenciesの中に必要なライブラリを列挙しました。バージョンの指定などもできますが、今回はしていません。 このファイルをapp.jsと同じディレクトリに置いて、$ npm bundle と打てば、node_modules/内にライブラリがインストールされます。

これが終わると以下のような構成になります。

$ tree
.
├── app.js
├── logs
├── node_modules
│   ├── connect -> ./connect@1.3.0
│   ├── connect@1.3.0 -> ./.npm/connect/1.3.0/package
│   ├── express -> ./express@2.2.2
│   ├── express@2.2.2 -> ./.npm/express/2.2.2/package
│   ├── instagram -> ./instagram@0.0.4
│   ├── instagram@0.0.4 -> ./.npm/instagram/0.0.4/package
│   ├── jade -> ./jade@0.10.4
│   ├── jade@0.10.4 -> ./.npm/jade/0.10.4/package
│   ├── less -> ./less@1.0.41
│   ├── less@1.0.41 -> ./.npm/less/1.0.41/package
│   ├── mime -> ./mime@1.2.1
│   ├── mime@1.2.1 -> ./.npm/mime/1.2.1/package
│   ├── mongodb -> ./mongodb@0.9.3
│   ├── mongodb@0.9.3 -> ./.npm/mongodb/0.9.3/package
│   ├── qs -> ./qs@0.1.0
│   ├── qs@0.1.0 -> ./.npm/qs/0.1.0/package
│   ├── socket.io -> ./socket.io@0.6.17
│   └── socket.io@0.6.17 -> ./.npm/socket.io/0.6.17/package
├── package.json
├── pids
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       ├── style.css
│       └── style.sass
├── test
│   └── app.test.js
└── views
    ├── index.jade
    └── layout.jade

27 directories, 7 files

あとはapp.jsに以下を書き足して、requireできるようにします。

require.paths.unshift('./node_modules');

環境変数からMongoDBへの接続情報をとり出す

vmc pushとか、MongoDBを有効にする方法とか、そのへんは他にも書いてある記事がありますし指示に従えばできるので省略しちゃいます。

MongoDBへの接続情報は環境変数で渡されます。 以下のようなコードでその値を取り出してMongoDBに接続します。

app.configure('production', function(){
  app.use(express.errorHandler()); 
  var env = JSON.parse(process.env.VCAP_SERVICES);
  var mongo = env['mongodb-1.8'][0]['credentials'];
  client = new Db('db', new Server(mongo.hostname, mongo.port, {}));
  client.open(function(err, p_client){
    client.authenticate(mongo.username, mongo.password, function(){});
  });
});

vmc envでNODE_ENVを設定する

先ほど挙げたコードを見ると、sinatraに慣れた人なら'production'の指定に気づくと思います。

これがまたちょっと曲者で、自分でNODE_ENVを設定しておかないと'production'の方のコードが実行されませんでした。

$ vmc env-add instanode env-add NODE_ENV=production

heroku configと似ていますね。これでOK。

app.jsの全体

最後にapp.jsの全体を載せます。ご参考になれば幸いです。

require.paths.unshift('./node_modules');

/**
 * Module dependencies.
 */

var express = require('express'),
    instagram = require('instagram').createClient(
      'YOUR_CLIENT_ID', 'YOUR_CLIENT_SECRET'),
    io = require('socket.io'),
    json = JSON.stringify,
    Db = require('mongodb').Db,
    Server = require('mongodb').Server;

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser());
  app.use(express.session({ secret: 'YOUR_SECRET' }));
  app.use(express.compiler({ src: __dirname + '/public', enable: ['sass'] }));
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

var client = {};
app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
  client = new Db('instanode', new Server('127.0.0.1', 27017, {}));
  client.open(function(err, p_client){});
});

app.configure('production', function(){
  app.use(express.errorHandler()); 
  var env = JSON.parse(process.env.VCAP_SERVICES);
  var mongo = env['mongodb-1.8'][0]['credentials'];
  client = new Db('db', new Server(mongo.hostname, mongo.port, {}));
  client.open(function(err, p_client){
    client.authenticate(mongo.username, mongo.password, function(){});
  });
});

// Routes

app.get('/', function(req, res){
  client.collection('images', function(err, collection){
    collection.find({}, {limit: 10}).toArray(function(err, images){
      res.render('index', {
        title: 'index',
        images: images
      });
    });
  });
});

app.get('/popular', function(req, res){
  instagram.media.popular(function(images, error) {
    client.collection('images', function(err, collection){
      collection.remove();
      for (var i=0, l=images.length; i < l; i++) {
        collection.insert(images[i]);
      }
      res.redirect('/');
    });
  });
});

// Only listen on $ node app.js

if (!module.parent) {
  app.listen(process.env.VMC_APP_PORT || 3000);
}

http://instanode.cloudfoundry.com/popularにアクセスすると、

  1. instagramからpopularの写真を取ってきて
  2. MongoDBにそのまま格納し
  3. http://instanode.cloudfoundry.com/にリダイレクトし、
  4. MongoDBから写真のデータを取り出し
  5. 画面に表示します。

次はSocket.ioを試そうと思います。(ライブラリはインストールしていますが、上記コードではまだ使っていません。)

第2回 MongoDB JP 勉強会 in Tokyoに参加してきた

MongoDB JP 勉強会 in Tokyoに参加してきました。 簡単に感想程度書いてみようと思います。

発表の感想

Sharding詳解

@doryokujinさん

Shardingについての前提知識がほとんど内容な状態で聞いてきましたが、その概要から問題点までよくわかりました。

大事なこととして挙げられたことは以下の2つ。

  1. Shard Keyの設定は非常に重要、慎重に
    一度設定すると基本的には変更できない。
    もし偏りが出たときにはMongoDBが自動的に是正するようにMigrationを行なってくれるが、
    処理が遅かったり、問題があるためになるべくならMigrationが起こらないようにすることが大事。
    (Migrationしないように設定することもできるそうですが、その場合偏りが起きたら手動でChunkを移動しないとならない。)
  2. Sharding環境におけるクエリは振る舞いがあやしい部分があるので要注意
    Migration中のcountが正しい値を返さなかったり、uniqueであるべき値が重複してしまう可能性があったり。

あと、ほとんど前提知識がない状態の僕が学べたことを箇条書きでつらつらと。

  • Sharding環境のMongoDBは3種類のサーバーで実現されている
    mongos, config, mongod
    mongosが仲介役をしてくれるので、アプリケーションからは普通にmongodにアクセスするのと同じ感覚でmongosにアクセスすればOK。
  • Chunkとは特定のCollectionの連続した範囲のデータ集合であり、データがどのChunkに属するかはShard Keyによって変わる
  • Chunkはデフォルトで200MBであり、それを超えると等分割される
  • Shard Keyの値は型がバラバラでもOK。MongoDBではすべての型を通して順番が決まっている
  • 特定のShardにChunkが集中してしまうと、Migrationが起こる
    MongoDBが自動的にバックグラウンドでやってくれるものではあるが、処理にかかる時間が非常に遅い
    また、Migration中はクエリの結果が怪しいことがある
  • Migrationの問題点
    • configサーバーへの負担
    • ネットワーク帯域の圧迫
    • メモリ領域の圧迫
    • パフォーマンスの低下
    • Migration中、クエリの結果を正しく返さない可能性がある
    • 低速
  • Shard Keyは「ゆるやかに増加するキー」+「検索でよく使われるキー」の複合が良い
    • アクセス解析の例だったら、monthとuserのような。
  • Sharding環境でのクエリには2種類がある
    • Targeted
      Shard Keyが指定されることによって、必要なデータがあるShardのみにアクセスするクエリ
    • Global
      システム内のほぼすべてのShardにアクセスするクエリ
      (でもindexが効いていればそれほど速度低下するわけではない。)
    • どのようなクエリがTargetedになるのか、はShardingの紹介 - Docs-Japanese - 10gen Confluenceの「オペレーションタイプ」の表を参照
  • サーバーの構成はShardingの紹介 - Docs-Japanese - 10gen Confluenceの「サーバーレイアウト」の項目を参照

今日の話の多くはScaling MongoDBという本に書かれている内容らしく、さらに詳しい内容を知りたい方はこちらを読むことをおすすめされていました。

Type-safe MongoDB in Scala

@bibrostさん

Scala + Lift + Rogueでサービスを作られたそうで、MongoDBと組み合わせたときの利点をトイレの実装の例などを通して、笑いを交えながら説明してくださいました。

この組み合わせで開発するメリットとしては以下の4つを挙げていらっしゃいました。

  1. コンパイル時に型チェックされる
  2. アプリ側だけに定義を書けばいい
  3. クエリを使って検索ができる(しかも型安全に)
  4. プロパティを増やすときのコストが少ない

コードも多かったので、詳しい内容は直接資料をご覧になった方がいいと思います。

例えばRails + Mongoidでも「コンパイル時に型チェック・・・」以外は同じメリットを享受できると思いますので、
動的言語と比べたときの一番の利点は型チェックされることなんだと思います。

あと、実際に稼動しているシステムのCollection構成を教えていただいたのですが、どこまで正規化し、何をembedするか、という設計はやっぱり悩ましいところらしいです。

アクセスログをできるだけいろいろ見る時のmapreduce + ニフティクラウドでの構築とパフォーマンスを初心者からわかりやすく

@muddydixonさん

そもそもmapReduceを使っていないので、情けないことに正直あまりついていけなかったのですが、
重要そうなポイントだけメモ。

  • よくわからないデータをとりあえず突っ込んでおくのにはMongoDBは最適
    サービスを横断するログなどは必ずしも形式が一緒じゃないが、重要なところだけをある程度合わせて
    とりあえずインポートしておくことで、あとは必要になったときにはクエリでなんとかできる
  • MongoDBにおけるmapReduceはドキュメントに対して縦横無尽に検索をかけられるという特性を活かして、
    keyをきちんと考えるほうが良い。valueは数え上げに徹する方がいいかも。(実際、valueは1にすることが多い)
  • mapReduceを使うならShardingを使うとパフォーマンスがよくなる
    Shard毎に処理した結果をさらにまとめているから。
    その関係上、平均・最大・最小などを求めるときにはFinalizeを使わないと正しい値にならないが。
地理空間インデックスを利用したWebアプリケーション

@yamaneko1212さん

地理空間インデックスはかなり興味のあるところでした。(最近は位置情報を使ったアプリも多いですし。)

ある座標の「近く」を検索できるだけではなく、矩形内にあるかどうかを簡単に検索できるのもMongoDBのいいところですね。 注意点として、球体モデルを利用したい場合には座標を保存する際に緯度・経度の順番を間違えないように、ということをご指摘されていました。

{loc: [経度, 緯度]}

この辺の情報は公式のマニュアルも詳しいですね。 地理空間のインデックス - Docs-Japanese - 10gen Confluence

Tachy with MongoDB

@joe_hrmnさん

サイバーエージェントさんで開発しているTachyというアプリのお話でした。

MongoDBを使った理由を以下のように挙げていらっしゃいました。

  • 使ってみたかった
  • データ分散の処理は大変
  • データアクセスが高速(と聞いて)
  • 自動でfailover
  • ドキュメント形式の柔軟性

そして、使ってみて良かったことを以下のように述べていらっしゃいました。

  • Index重要
  • mongostatが役に立った
    Sar, vmstat, iostat
  • RDBのノウハウの流用が可能
    explain(MongoDBにもあるんですね)

こうして実戦投入して、その中で出会った問題点やその解決方法などを聞くことができるのは非常に有意義です。
まだまだMongoDBではこうした実例が少ないので、とても貴重な発表を聞くことができて嬉しかったです。

懇親会

お話をさせて頂いた方のほとんどがソーシャル系のお仕事をされていて、ソーシャルの勢いを感じました。
実際にMongoDBを実際のシステムに投入した方はまだ少ないようで、まずはログ解析などの社内で使う仕組みから・・・と考えている方が多いようでした。

僕の仕事はいわゆるBtoBのシステムなので、よっぽどRDBMSで難しい案件でも来ない限り仕事で使うことは無いと思います。
・・・何年先でしょう。

会場について

大崎にあるフューチャーアーキテクトさんのセミナールームを貸していただきました。
会場に着いたときに思わずツイートしてしまいましたが、受付がまるで観光地のホテルのような感じで、さらに内部にはバーがあったり、と軽くカルチャーショックを受けるようなすごいオフィスでした。

最後に

大変ためになる勉強会でした。実際に会社の仕事で使うのはまだ難しそうですが、個人的には次のアプリではぜひMongoDBを使って勉強してみたいな、と感じました。

スタッフの方々、発表者の方々、そして会場を貸してくださったフューチャーアーキテクトの方々、どうもありがとうございました。

つらつらと書いてみましたが、まだまだ僕自身MongoDBは勉強不足なので色々怪しいところがあるかもしれません。
間違って解釈しているところはぜひ教えてください!