MongoDB Conference in Japan(通称 mongotokyo)に行ってきた

最近、少しつめこみすぎかなと思いつつ、Early Birdでお金払っちゃってるし、子供を保育園に預けておいて、家でうだうだしたり遊びに行ったりするのは倫理に反するので行ってきた。

ということで、全セッション分というわけではないけど、メモ。
英語聞きながら、メモってのはかなり難しい。。。日本語だとメモしながらでも内容が耳に入ってくるけど、英語だと意識を集中して聞かないと音が遮断されてしまうww。

追記:
@doryokujinさんの技評上でのレポート。動画あり。
http://gihyo.jp/news/report/2011/03/2301

Welcome to Mongo Tokyo @rogerb

資料はまだアップされてなさげ。

    • What is MongoDB?
      • 120000ダウンロード per month
      • アメリカ、ヨーロッパ、日本、中国の順に利用数が多い。
      • 1000以上の採用実績。
      • 昔はRDMSがデータを格納するための選択肢。
      • なぜNoSQLが人気になってきたか? -> 大量のデータ、コネクション数の増加。
      • RDMSでもできるけど、相当詳しくないと無理。
    • RDMSの特徴
      • 完全なTransactionのサポート

    • NoSQLの特徴
      • 緩いTransaction管理
      • holizontalなスケール
    • MongoDBの特徴
      • MongoDBはmemcachedとRDMSのあいのこ。
      • C++で実装されている。
      • driverは色々とある。Rubyが一番人気
      • No joins and no complex transactions
      • これによってスケーラビリティを確保する。
    • RDBMSとの用語比較
      • Table -> Collection
      • Row -> json document
      • index -> index
      • Join -> Embedding and linking
      • もうちょっとあったけど、資料にて
    • MongoDBの機能
      • 複雑なデータ構造の表現
      • Secondary index
      • 多様なquery
      • $exists, 正規表現
    • スケーラービリティに関して
      • Read scalability -> replicationを増やすことで実現可。
      • Write scalability -> Shardingによる複数のreplica setを生成することで、実現されている。

oreilly本(http://oreilly.com/catalog/0636920001096)の最初のほうを要約してくれた感じ。
ちなみにアプリもある(http://iphone.appinfo.jp/apps/395324056/MongoDB%3A%20The%20Definitive%20Guide)ので、自分はこれをepubにしてiPadに入れています。当時は600円。今は800円。
あと、RDBMSとの比較の所では、デブサミの時にDeNAの奥さんが2者の違いはパッケージングの違いにすぎないというようなことを仰っていたのを思い出しました(http://d.hatena.ne.jp/seikoudoku2000/20110217)。主にconsitencyの取り扱いの所に2者の差があるように思いますが、そう捉えるとより理解し易い気がしました。

Schema design @rogerb

資料はまだアップされてなさげ

    • History of data modeling
      • ISAM
      • Network
      • Hierarchical
      • Relational. 1970年頃から現れた。そこまで古いものでもない。
    • Modeling goals
      • Avoid anomalies(奇形とか変則性という意味)
      • Minimize redisgn. RDMSではこれがかなりネック。三ヶ月かかるとか?
      • Make the model informative
      • Avoid bias towards a particular style of query
    • Advanced scema design
      • Single table inheritance
      • One to many , many to many
      • Trees
      • Queues
    • Hierarchical
      • Shapeテーブル
      • typeというフィールドを作り、circle, square, rect という種類を持たせる。共通するフィールドと、typeにより異なるフィールドがShapeテーブルには混合して存在。circleだとradius(半径)というフィールドがあったり。
      • circleだけにあるradiusを条件にfindクエリを投げることで、該当のレコードを抽出できる。squareやrectは自動的に無視できる。
    • One to many
      • Embed arrays
      • Blog エントリーの中に、コメントの配列を持たせて、さらにそのコメント毎にreplyの配列を持たせる。
      • Simple、まとめて持てる
      • ただし、ドキュメントをまたがって最新のコメントを探すのは難しい
      • Blog とcommentテーブルに分ける。
      • Flexible, more queries
    • many to many
      • Product とcategory
      • よくあるパターンとしては結合用のテーブルを作ること
      • Productの中にcategory idの配列、Categoryの中にproduct idの配列というデータの持ち方。
      • 関連データの検索が容易
      • ただし、一回の更新毎に二回のupdateが必要。
      • Categoryにproductを持たせるのはやめる
      • それでも容易に検索はできる。
    • Trees
      • full tree in document
      • Single document, peformance intuitive
      • 検索が難しい。一つのドキュメントは4MBまでという制限
      • Parent links
      • Trees as a path
      • ディレクトリ構造をdocumentで表すことも可。
      • 前方一致の正規表現で引っ掛ける。
    • Queue
      • Inprogress というフラグとpriorityを表すフィールド
      • findandModify() という関数を使ってデータを取り出すことで、フラグをデータを取り出すと同時にフラグをオンにすれば、Queue的なことが実現できる。
    • その他
      • Capped collections 上限を決めて古いデータから勝手に消えていく

どうしてもRDBMSちっくな考え方から中々抜けることができないというのはあるので、まずはこういったパターンを覚えてしまって、そこに今あるデータをあてはめることはできないかというアプローチはありだなと思いました。
実稼働しているシステム上での具体的なスキーマ構成というのはさすがに中々出てこない & そもそもそこまで突き詰めて構成している人は少ない気がするので、この辺は試行錯誤しながら身につけていく部分になるのかな〜と思います。

Replication and Sharding 10genのエンジニアの人

http://bit.ly/f5UsfF
かなり断片的なメモ。資料見るべし。

    • shardingに関して
      • addshard コマンド
      • 境界値はシステムが自動的に調整してくれる。
      • Timestampをshardのkey に足すといい?
      • More key values to enable split shards
      • ShardのkeyをQueryのkeyと合わせるとseekもスムーズ

    • replication
      • ノードが落ちた時のコネクションのハリ直しはdriverがやってくれる。
      • ノード復旧時には自動でリカバリ
    • slaveOK (ドライバからのアクセスで使えるコマンド)
      • writeはprimary, readはsecondaryという振り分けを行ってくれる
      • Secondaryからの読み込み時は必ずしもconsitentなデータが読めるとは限らない。

    • QA
      • Shardを追加する時、Shard間のノード数は合わせないといけない。
      • Shardingはcollenction単位。shardingのkey指定しないといけないから。DB単位でのshardingをサポートする予定はない。

      • Shardingすると、ユーザ認証が効かないが、サポート予定はあるか? -> 2.0以降でサポート予定。チケットもある。1.8が出たばかりなので、2.0がいつ出るかは未定。その他、shardingすることで欠落してしまう機能はいくつかある。


まだ、複数台構成で動かしたことがないのですが、shardingのところは結構はまりそうな予感がしました。特にsharding keyを自分で決めるという所で、考慮の足りない設計にしてしまうと、後で大けがをしそう(4sqの障害的な?)。
sharding keyに関しては、複数のフィールドを設定するとbetterという説明でしたが、どのようにデータが格納されていくのかイメージしきれず、今いちピンとこず。。
oreilly本に、"The Key to Sharding"という章があるので、そこを読み返す & とりあえず動かしてみるという感じでしょうか。。

Social data and log analyze 芸者東京 @doryokujin

    • ざっくりとした構成
      • Mysql, cassandra, access-logのサマリ等をまとめてmongoDBに入れている。
      • 中間データ(ほぼ生データ)とサマリーデータの両方をMongoDBに入れている。
      • サマリーにはMongoDBのmap reduceを利用。
      • 中間データ生成にHadoopを使っているが、mongoDBへの書き込みでボトルネックあり
      • MongoDB のmap-reduceはsharding毎に並列で行われる。
      • 1.8以降でreduceの機能が改善されるらしい。
    • REST部分
      • sleepy,mongoose
      • HTTPでダイレクトにmongo DBにアクセスして、jsonでデータを取得できる。
    • Rを使っての集計
      • 登録日と課金額の相関関係とかプレイ時間と課金額の相関関係とか。
      • RCurl、Rjsonというのを使って、同様にmongooseにアクセスしてデータを取得できる。
    • その他
      • Muninという監視ツールで稼動状況をチェック
      • Mongo flume plugin. accessデータを直でmongo dbに入れることができる。


先日のhadoop conference(http://d.hatena.ne.jp/seikoudoku2000/20110223)では、DeNA,Cyber Agent共に、access_logの中間データはHDFS上に格納してHiveやらpigやらで集計しているという話でしたが、adhocにクエリを投げたり、GUI化するところがちょっと大変そうだなと感じていたので、MongoDBにデータを突っ込んで、mongoose + javascriptという構成は手軽さという点でもカスタマイズ性という点でも魅力的だな〜と感じました。是非試してみたいです。

MongoDB as a Search Engine platform. @kzk_mover

    • sedue
      • エンタープライズ向けの分散検索エンジン。
      • 5000万件くらいのドキュメントの検索が行える。

    • Data model
      • RDBMSのようにスキーマを定義する必要がある。
      • ArticleID, Title, Content,,
      • カラムに対してindexの定義を行う。recommend用のindexも作れる。
      • XMLで記述。
    • Architectureの話。
      • たくさんのサーバが協調して動いている。
      • 図を見るべし。

    • 導入を進めたが、、、
      • Schemaが毎週のように変わる。
      • 使われていないカラムもある。
      • その割にシステムを止めることは許されない
    • storageの再検討
      • Storageはpluggableにできるように実装していた。
      • Tokyo Tyrantはreplication, sharding ができない。
      • Mysqlではshardingしてカラム足すのが大変。
      • NFSはセットアップにコストがかかる。
      • HDFSは安定性に課題が。
      • MongoDBに出会う。
      • API, Replication, online column add, sharding という必要要件をどれも満たしてくれていた。
      • GridFS. MongoDB as a Blob-storage
      • 16MB制限を超えて、大きなファイルを保存できる。
      • crawlerが集めてきた文章の保存、インデックスファイルの保存のところでMongoDBを使っている。後者はGridFSを使っている。
    • 開発にあたって
      • バグに対してpatchも送っている。
      • その取り込みも早いし、MLの対応も早い。
      • patchを送るとマグがもらえる!
      • 一週間で作っちゃってその後テスト的な。

    • 問題点
      • ディスクの使用量がでかい。富豪か!
      • Appendが多い。Vacume的なことをするとDBがとまってしまう。
      • 圧縮がサポートされていない。
      • Consistencyの取り扱いが難しい
      • デフォルトはWriteのリクエストを投げただけで、書き込みOKになる。 -> getLastError を取得すると確認できるがデフォルトではオフ。(MySQLとのパフォーマンス比較をこれなしでやっちゃダメでしょ的な。。)
      • レプリカセットを使うと、eventually consistencyになる。
      • Replicaの設定が深く追えていないので、master-masterにしている。
      • Shardingのパフォーマンスには厳しいものがあった。1.7前半。
      • 勝手にデータが行き来したりするので、何がおこってるんだ??ってなる。
    • QA
      • Mongo dump でバックアップをとっている
      • logの保存にCapped collectionsを使っているけど、リカバリーの時にこれが足りないと全部リカバリーできない。

検証しながらバグを見つけてパッチを送ってマグもらったとさらっと言っていましたが、それって半端ないなと、圧倒されてしまいました。それがほんとの意味でオープンソースを使うってことなんだろうな〜と。
リアルに100倍くらいの速さで製品を作っているんだろうなと感じます。(http://lab.jibun.atmarkit.co.jp/entries/805)
そして、それだけしっかりと検証をした上での、MongoDBのメリット、デメリットの説明だったので、凄く説得力もあり、勉強になりました。

node.js + mongoDB Cyber Agent @snamura


Ameba pico の中の人。facebook上で動いているやつ
EC2上で大規模に動かしている。

    • 作ろうとしているもの
      • PC向けのソーシャルゲーム

    • 使おうとしている技術
      • MongoDB 1.8
      • node.js 0.4
      • WebSocket. -> 現在はflash上で動く独自プロトコルを使っているが、将来的にflash、、、となった時に備えて
      • Flash player

    • node.jsにした理由
      • これまではjavaで開発していたが、javaの静的型付けとの相性が悪くて残念な感じになってしまう。
      • Python + twistedは同僚のエンジニアが拒否。
      • なんか流行ってる。
      • 言語使用がすでにシングルスレッド
    • 構成
      • MongoDBは3 * 3 のクラスタ構成
      • Replica setの最低構成数の推奨が三台。二台だと一台落ちた時に、決定権云々の話がある。特別なプロセスを立ち上げとく必要がある。
      • Ameba picoではこれで数万ユーザの同時接続を実現できている。
    • MongoDBとnode.js
      • 鼻血がでるほど相性がいい。
      • jsonがそのまま使える
      • プログラムがシームレスに統合される
      • No more OR mapper

    • node.js用のドライバ
      • node-mongodb
        • 公式のCドライバのラッパー
        • bulk insert非対応
      • node-mongodb-native
    • node.jsの特徴
      • 全て非同期
      • 何をするにもコールバック。DBアクセスも。
      • コールバック全てにエラーハンドリングが必要。
      • 階層がかなり深くなる。

    • 工夫したところ
      • メソッドチェーンで連続した処理を記述できるようにした。
      • Mongooseという選択肢もあったが自分で作ってみたかった。
    • 運用管理ツール
      • 管理ツールは開発が面倒?? -> ソーシャルゲームは運用が命。管理ツールの使いやすさはサービスの成功に関わる。
      • 社内ツールなので、最先端技術を導入しやすい。エンジニアの腕の見せ所。
      • 運用チームのテンションを上げてやるようなツールを作ることで、チームの士気が高まる。
      • リアルタイムレポート。 ##動画で画面を見せてくれましたが、凄かった!
      • データ定義をそのままフォーム仕様にしている。
      • 今はget,postではなく、websocktで通信している。
    • まだリリースしておらず、スケーラビリティ的な所は話せないので、また今度。

    • 結論
      • 仕様やデータ構成が複雑なソーシャルゲームとMongoDBの相性がいい。
      • node.jsとMongoDBは良い組み合わせ。
        • ただし、どちらも新しい技術なので何か起こる可能性はある。
      • テストコードが超大事。nodeunit。
        • スペルミスとかしてても容赦なく動くので、ほんと大事。
      • 厳格なシステムには向かない。
    • QA
      • Web socketで接続にくるので、ユーザ単位(プロセス単位?)で大きなドキュメントをプロセス上に保持しておいて、差分のみをMongoDBに反映する的なことをしている。
      • プロキシを挟んでプロセス間通信をして、近くのユーザーを認識させるような仕組みを作り中。
      • 実際の運用話は前回の勉強会の資料を見るべし!
      • shardingはたまに手でバランスを直してる。
        • 不思議とノード1にかたよる。。結構大変。

デブサミ、hadoop conf, MongoTokyoとそれぞれでCyber Agentの発表がありましたが、どれも内容が濃くて、ソーシャルゲームっていうただの流行りではなく、これまでの技術の積み重ねがあって花開いたんだなというのを改めて感じました。
と同時に、それまでの積み重ねた技術に縛られずに、node.js + MongoDB を使って作っちゃいましたってのは改めて凄いなと。
そういうのを使って作っちゃえるのも凄いし、完全にエンジニアにプロダクトの決定権を与えてそんな冒険をさせちゃう会社も凄いし、何よりまだリリースしてないサービスなのに、こんなに詳しく構成の話をしてしまって大丈夫なのか?と部外者なのに心配してしまいましたwww。
あとは運用ツールの話がグサグサきました。picoを作れって言われてもすぐにはできませんが、こういうツールは自分で作れそうなものなのに、ただやれてないだけなんだなと反省。まずはこういう思考の部分で追いついていく & それをコードに落とすということを意識し続けないといけないな〜。


前回の資料も共有されていたのでリンク。


主催者の方々、10genの方々、発表者の方々、どうもありがとうございました!!