第5回 MongoDB JP 勉強会に行ってきました

第5回 MongoDB JP 勉強会に行ってきました。仕事でも関わっているMongoDBですが、勉強会には初参加でした。
参加者の数がすごく多くて驚きました。すごい盛り上がりようです。ただやっぱりWebサービス系の会社の方が多いという印象かな。自分のような業務系がメインの人は少なそうな感じでした。
セッションの数も6つと盛り沢山でした。ちょっと量が多いので自分の印象に強く残ったことを中心にまとめます。

Play with Mongoid! by @yuki24さん

実は仕事でもお世話になっている、RubyのMongo向けmapperライブラリ、Mongoidについての解説でした。
前段で少し雑談として話していましたが、Ruby界隈ではMongoDBが妙に盛り上がっているとのこと。確かに自分もそう感じます。何ででしょうね?

  • RubyのMongo向けObject Document Mapper (ODM) 。ORMじゃないよ。
  • MongoidとMongoMapperの違いは?
    • Mongoidは大きなデータを扱いやすい。ドキュメントとか豊富。Ruby1.9.2、Rails3にも素早く対応してくれた。*1
    • MongoMapperは小さいデータに向いている。大きなデータは不向き。プラグイン機構を備えているのがよい。先行していたのでコミュニティは大きい。
  • ActiveRecordライクに使えるようにしているのが特徴。モデルに対してフィールド定義、型定義を行う。デフォルト値指定とかも出来る。動的にフィールドを追加するDynamic Fieldという機能もある。
  • クエリにはCriteriaとActiveRecordライクなFindersがある。
    • Criteriaはチェーン可能で遅延評価
    • Findersはチェーン不可能で即時にDBに触る (パフォーマンスに注意)
  • AssociaitonについてはMongoのembeddedドキュメントを扱うことが出来るAPIがある。
  • Paranoiaといういわゆる論理削除を扱える機能がある。(deleted_atフィールドを埋め込む)
  • Versioningというモデルのバージョン管理を行うことが出来る機能がある!
    • バージョンが異なると違うドキュメントになる (どんどんサイズが増えるので注意)
    • 特定のバージョンを指定してとってこれる
    • バージョニングを飛ばして更新も可能

解説の後にライブコーディングに入り、そこではFacebookAPIにアクセス、Mongoに永続化するアプリを作っていました。RSpecでまずテストを作成してから実装、実行時に問題があったらまたテスト作成、と割と自分が普段見慣れた光景が展開されていました。(^^)
バージョニング機能が面白いですね。例えば複数画面遷移するWebアプリケーションで、バックボタン対応するために画面情報の履歴を保持するのに (いわゆる対話スコープとして) 使えそう、とか思ったりしました。

YiiフレームワークとMongoDBを使ったFacebookアプリ開発 by @aoyagikouheiさん

最近PHPの世界で注目度が上がっているらしい (?) Yiiフレームワークと、そのフレームワークのMongoDBサポート機能などについて解説して頂きました。

  • YiiフレームワークとMongoDBの組み合わせで、いいねの前後で画像を切り替えるFacebookアプリ作りました。
  • PHPのMongoDB対応状況
    • ネイティブドライバがあるが、これは低レベル。
    • 有名どころのフレームワークが次々とサポートしてきている。
  • Yiiフレームワークとは
    • YiiはYes, it is! の略。ただいま注目度No.1?パフォーマンスが売り。ドキュメントも豊富とのこと。
    • フレームワークの構造としては割と一般的なWeb MVCアーキテクチャという印象。ビューとフォーム定義を分離しているのが特徴的。モデルに対して表示名定義があるのがユニーク。ActiveRecordもある。
  • YiiMongoDbSuite
    • ActiveRecordベース。CRUDの自動生成もある。
    • GridFSにも対応している。
  • どんなことにMongoDBを使ったか?
    • 画像のストレージとして。キャッシュ、認証、ログ、セッションストレージにも使った。
    • ログについてはmongoblogrouteというものを作った。MongoDBだとPostgreSQLに比べて高スループットだった。
    • セッション管理についてはMongoをストレージにする拡張を作った。
  • 質疑応答で出た話
    • セッション管理について、MongoDBは書き込みが非同期で、getLastError でチェックする必要があるのでは?
      • →してなかった。オプションでやるようにします。
        • getLastError でのチェックはやり過ぎると遅くなるというジレンマも...。

実はこれまでPHPの世界と関わったことがないので、詳しい事情はよく分からないのですが、PHPの世界でもMongoDBが結構盛り上がっていることを知りました。参加者のPHP率も結構高い感じでした。
まだ知名度がさほど高くないフレームワークだったので、フレームワークの説明にかなり時間を割く結果になっていたのがちょっと残念でした。

ココロもつながるオンラインゲーム – アットゲームズ – のMongoDB導入事例 by @nsegaさん

導入事例のお話しです。最後のほうで発表の内容 (構成的にまずい所があった) について、参加者が様々な意見を寄せる場面があり、皆で支え合いながらMongoDBを広めていこうという雰囲気が感じられてとても良かったです。

  • アットゲームズとは
  • Mongo導入の経緯
    • SNSのリニューアルであしあと、ゲストブックの統合を決めたことがきっかけ。
    • あしあと、ゲストブックデータが1億件。MySQLで管理してたがレスポンスが悪化していた。これらのデータは更新頻度高いが、整合性は厳密さを求められない。
    • 問題をスケールアウトで解決したかった。
    • ツール、ドキュメント充実、コミュニティも活発という理由でMongoDBを選択した。
  • システム構成
    • LAMPのシステムにMongoDBが加わるような形。
    • WebサーバーはWeb15台、モバイル3台でここにmongosを。
    • MongoDBは3台のシャーディング構成。レプリカは2台構成。
      • レプリカについて、@doryokujinさんらからこれはまずいとの指摘あり。2台構成だとプライマリが死んだ場合にセカンダリが1つになって過半数が得られなくなるため。よって最低3台にする必要がある。
  • 工夫したこと
    • 自動シャーディングはオフにして、手動シャーディング。ユーザIDを100で割った余りをシャードキーにした。
    • アクセスクラスは自作。DAOを作った。親クラスにアクセス処理を実装しておき、継承して利用するパターン。
    • 重いクエリのチューニングはMongoに備わっている explain を活用。実行計画の cursor 属性を見て、適宜インデックスを作るやり方で対応。
      • この辺りRDBMSのやり方に感覚が近いのがいい、とのことでした。
  • ハマりどころ
    • 明示的な型指定。Mongoでは型指定が重要だが、PHPは暗黙的に型変換しちゃうのでそこでハマりやすい。
    • 更新はデフォで非同期。ドライバのパラメータで更新確認の指定をした。
  • 発生した問題
    • mongodプロセスの異常終了
      • アクセス過多による out of memory が発生。作りの問題だったので修正。
    • 自動フェイルオーバーが起動しない
      • 構成の説明のところで上がった指摘 (セカンダリが足りない) が原因。
      • 発表資料ではpriorityパラメータを設定していなかったことが原因では?とあったのですが、これはデフォルトで 1 であるため (絶対にプライマリにしたくないサーバーに対して0を指定する)、これが原因ではありませんでした。
    • スロークエリー設定
      • ログに長時間掛かるクエリを出してくれる機能で、これには随分助けられた。
    • シャーディングの偏り
      • そんなに偏ってはいない
      • 2ヶ月に1回位は moveChunk で偏りを直したほうが良さそう
  • その他色々出たおはなし (周りからの指摘など)
    • レプリケーションする場合、セカンダリは別サーバーもしくは別ハードディスクにした方がよい。これはケチらない方がいい!
    • コア数の多いサーバー使っているけど、Mongoだとコアを使い切れないのでは?という指摘あり。
      • MapReduceは次バージョンからマルチスレッドになるそうです。
    • スロークエリーの監視について、何か良いツールある?
    • インデックスの課題はRDBMSと同じ。(今回は更新がなく、追加削除のみ)

やっていることをありのままにさらけ出したら、みんなが親切なアドバイスを次々に出してくれるので驚きました。上にも書きましたが、特に普及途上の技術については互いに支えあってやっていこうという雰囲気のコミュニティが存在することはすごくいいことだと思います。
しかし安全に運用しようとしたらやっぱり6台くらい必要なのか...。

Not Only NoSQL! RDBの逆襲 – PostgreSQL編 by @choplinさん

MongoDBの特徴的な機能に対して、「それPostgreSQLでも出来るよ」的な解説をして頂きました。その上で、ではどんな場面でNoSQLを選択すべきなのか、というお話をされました。

  • 何故MongoDBなのか?
    • ドキュメント指向。アプリのデータとマップしやすい。埋め込みやすい。スキーマレス。ジョインを減らせる。
    • 高性能。ジョインがない。何でもインデックスOK。非同期書き込み。
    • ブログデータを例に
      • データ構造の埋め込みが出来るのが利点。タグとか。
      • 埋め込むとジョインが不要になる。(マテビューみたいな感じ)
      • ジョインが無いので実行計画が単純になる。
  • 注意すること
    • 1ドキュメント16MBまで。
    • スキーマ設計結構重要。オフィシャルにもスキーマ設計に関するドキュメントがある。
      • 今後勉強会するかも。
      • MongoDB Document Designが出る予定!
  • でもPostgreSQLでも結構できるよ
    • 配列のカラムが持てる。
      • 実はSQL標準。
      • ただし、Mongoでは型が自由だけど、PostgreSQLでは型限定される
    • MongoだとSpiderMonkeyが動いているのでJS関数でいろんなことが出来る。
      • PostgreSQLでも関数豊富。配列を行にする事もできる!
    • インデックスについて。
    • ドキュメントにさらにオブジェクトを埋め込むような半構造 (Semi Structured) については...。
      • PostgreSQLにはhstoreが。
      • XML型というものもある。XMLに対してインデックス貼るのもOK。
      • 9.2はJSON型が入るかも?入れるかどうか結構揉めているとのこと。
  • ではどういうところでMongoDBを?MongoDBだと何が嬉しいか?

(2011/08/02修正。@choplinさんご本人からご指摘を頂きました。)

    • 機能性と速度の両立、RDBMSの良い所を残すという哲学。
      • ORM使うんだったらMongo使おうぜー! もしくはSQLをダイレクトで。

純粋にPostgreSQLの機能紹介がためになりました。PostgreSQLは昔から積極的に新しいことにチャレンジするDBMSという印象を持っていましたが、この発表を聞いていても強く感じました。
この次の発表でも同じような話があったのですが、ある技術の採用を考えるときには、その技術が何のために生み出されたのか、その背景をきちんと理解することが大事ですね。

ビジネス視点のMongoDB vs RDB by @bibrostさん

発表者ご自身がこれまで実際のビジネスでMongoDBを採用してきた経験から、ビジネス視点からみてMongoDBの導入戦略はどう考えるのか、といった内容についての発表でした。

  • 最初に...
    • RDBに死を!
      • 性能のために正規化を崩してジョインをなくすとか、参照整合性を消すとか...。
      • 本来RDBMSの用途をねじ曲げて無理やり使うのはおかしい。(それが偽RDB)
      • MongoDBはそういうところのためにある。
  • これまで作ったアプリ
  • 導入戦略
    • 短期と中長期の視点。
    • プロジェクトやチームの性質、ミッションから鑑みて判断。
      • バックグラウンドをブレークダウンしてチェック。
        • 新規 or 追加?受託? or 自社?とか。
        • 新規、自社がやはり向いている。
    • 課題に対して解決になる機能があるか?
      • プロダクトのビジョンや方向性を見極めること。
        • どんなプロダクトも解決したい課題があって、それに対する機能がある。
      • 基本の立ち位置は課題から。
    • 能動的にプロダクトへ貢献することが大事。
  • 自分が作ったサービスのときは... (勝間和代のサイトの時)
    • (自分にとって) 成長のあるプロダクト選択をしたかった。
      • だからScalaとか。
    • 学習コストは大きい会社だと大きい。
    • 認証と決済はRDB、他はMongoでやった。
      • こけると致命的なところはRDBにした。
  • まとめ
    • ビジネス視点では機能比較は意味がない。プロダクトが解決したい課題があって、それに対する機能があるのだから。
      • 解決したい課題の内容を考えたら自然と選択できるはず。
      • プロダクトのビジョンの方向に逆らった選択をするのは良くない。(なので偽RDBに死を!)

聞いていて、まーそりゃそうだよねー、と納得出来るようなお話でした。
あるプロダクトを選択する時は、そのプロダクトが何を解決しようとしていたのか、その背景思想を知ろうとすることは自分も普段から心掛けるようにしています。
あと、(1つ前の発表からは逆説的になりますが) 「それ◯◯でも出来るよ」とプロダクト本来の目的に逆らって無理なことをするのも良くないですね。これは自分も結構やりがちなので肝に命じないと...。

MongoDB GridFS by @camelmasaさん

MongoDBの分散ファイルシステム、GridFSについての説明でした。これについては余り良く知らなかったのですが、説明を聞いているとちょっとしたファイルストレージには結構いいかも、と思えてきました。

  • GridFSとは
    • 巨大ファイル格納のための仕様。大きいファイルを複数のドキュメントに透過的に分割する。
    • ドライバはPHPJavaPythonRubyなど。
  • 環境構築
    • 基本的に特別な設定が不要。configもmongosもレプリカセットもシャーディングも。
  • コマンド
    • monogofilesコマンドで操作する。
    • 同じファイル名で登録すると削除されるので注意!
    • ファイル名検索は部分一致。
  • つまづいたところ
    • レプリカセットの設定するとディスク容量すぐ食う。
    • 相当登録しないとシャーディングされない。
    • マスターに対して問い合わせないとmonogofilesコマンドで見つからない。
  • さらに
    • nginxの拡張モジュールがある。
    • それのrack版もある。もしかしたらnodeも?
  • まとめなど
    • 特別な設定が不要なので、気軽に分散ファイルシステムが出来る。
    • 1つの大きなファイルを分散保存出来るのは利点。

特別な設定なしに使えるというとっつきの良さは魅力ですね。MongoDB自体、他のNoSQLと比較してとっつきやすいという印象があります。

全体を通しての感想

参加者が多く、とにかく随分勢いが出てきているなーと感じました。ただ、やっぱりまだみんな手探り状態で使っているというところでしょうか。さすがにクリティカルな部分で使っている人はまだいなさそうですね。
登場したばかりで発展途上なプロダクトだけに、ユーザーが互いに助けあいながら盛り上げていこうという雰囲気があり、それはすごくいいと思いました。

*1:自分が関わっているプロジェクトで使っている理由もこれが大きいです