Más contenido relacionado La actualidad más candente (20) Similar a ソーシャルゲームにおけるMongoDB適用事例 - Animal Land (20) Más de Masakazu Matsushita (20) ソーシャルゲームにおけるMongoDB適用事例 - Animal Land2. About Me
• 松下 雅和 / Masakazu Matsushita
• @matsukaz
• Cyberagent, Inc. - SocialApps Division
- Ameba Pico (2011/01∼)
• 海外向けピグ
- Animal Land (2011/03∼)
• DevLOVE Staff
9. 利用サービス
• Amazon Web Services
- EC2 (Instance Store + EBS)
- S3
- CloudFront
- Route53
- Elastic Load Balancing
• Google Apps
• Kontagent
10. システム間のつながり
iframe 各種API呼び出し
課金コールバック
Web
HTML
サーバ
JSON
Flash
Command
AMF サーバ
AMF : Actionscript Message Format
11. L m1.large
サーバ構成 XX
EBS
m2.2xlarge
EBS
ELB ELB
S3
Web L 3 Command L 4 CloudFront
nginx nginx Route 53
Tomcat Tomcat
バッチ L
mongos mongos
バッチ
MySQL
Shard 5 MySQL L memcached L 2
monitor L
MongoDB XX MySQL memcached
EBS munin
mongod
MySQL L nagios
MongoDB XX
MySQL admin L ビルド L
mongod EBS
nginx redmine
MongoDB XX MongoDB XX 3 Tomcat jenkins
mongod mongoc
EBS EBS mongos Maven SVN
EBS
Secondary
16. • MongoDBの良さ
- ReplicaSetによる耐障害性
- Auto-Shardingによるスケールしやすさ
- 複雑なデータ構造を扱える
- Index、Advanced Queries
- 開発チームがアクティブ
- 敷居が低い
17. • Animal Landの要件に合う
- 複雑なデータ構造 (街のグリッド情報、
ユーザ/建築物のパラメータ、etc)
- シーケンシャル処理中心で、同時更新が
少ない
- メンテナンスレス
• データ構造の動的変更
• 耐障害性
• スケールアウト
18. • 苦手な部分は他の方法で解決
- 特性に合わないデータは他のDBで
• 信頼性が必要な課金関連はMySQL
• 一時的なデータはmemcached
- トランザクションは利用しない
20. アプリケーション開発時
• トランザクションがいらないデータ構造に
- ユーザ情報などは、1ドキュメントで保
持して一括更新
ユーザ情報
{ facebookId : xxx,
イメージ
status : { lv : 10, coin : 9999, ... },
layerInfo : 1¦1¦0¦1¦2¦1¦1¦3¦1¦1¦4¦0... ,
structure : {
1¦1 : { id : xxxx, depth : 3, width : 3, aspect : 1, ... }, ...
},
inventory : [ { id : xxx, size : xxx, ... }, ... ],
neighbor : [ { id : xxx, newFlg : false, ... }, ... ],
animal : [ { id : xxx, color : 0, pos : 20¦20 , ... } ],
...
}
21. アプリケーション開発時
• データ量を可能な限り削減
- 街のグリッド情報を1つのデータで保持
するなど (プログラム側で展開)
- 設計時の構造(500 KB)
layerInfo : {
1¦1 : 0,
1¦2 : 1,
....
}
- 現在の構造(50 KB)
layerInfo : 1¦1¦0¦1¦2¦1¦1¦3¦1¦1¦4¦0...
23. アプリケーション開発時
• Shard Keyは以下の方針で決定
- カーディナリティが低い値は使わない
- よく使われるデータがメモリ上に乗る
- 使われないデータはメモリ上に乗らない
- 参照や更新が多いデータはバランスよく
各Shardに分散
- Targetedオペレーション
での利用を意識 (後述)
おすすめ書籍 →
24. アプリケーション開発時
• Targetedオペレーションを中心に
- Shard Keyでデータを操作
- Shard Key以外の操作はIndexを利用
Operation Type
db.foo.find({ShardKey : 1}) Targeted
db.foo.find({ShardKey : 1, NonShardKey : 1}) Targeted
db.foo.find({NonShardKey : 1}) Global
db.foo.find() Global
db.foo.insert(<object>) Targeted
db.foo.update({ShardKey : 1}, <object>) Targeted
db.foo.remove({ShardKey : 1})
db.foo.update({NonShardKey : 1}, <object>) Global
db.foo.remove({NonShardKey : 1})
25. アプリケーション開発時
• 更新頻度をなるべく減らす
- マスタ情報はサーバ上でキャッシュ
- ユーザ操作はまとめて処理 (5秒に1度)
• Flash側でキューの仕組みを用意
• サーバ側はキューから取り出してシーケ
ンシャルに処理
シーケンシャル処理
ユーザ操作
キューで保持
キュー
Command
Flash
サーバ
まとめて送信
26. アプリケーション開発時
• O/Rマッパーで開発を効率化
- Spring Data - MongoDBとラッパーク
ラスを用意して効率よく開発
@Autowired
protected MongoTemplate mongoTemplate;
public void insert(T entity) {
mongoTemplate.save(entity);
}
- オブジェクトをそのまま利用できるの
で、RDBのO/Rマッパーより扱いやすい
- Javaでも言うほど大変じゃない
28. インフラ構築時
• 従来のDBと同様に見積もり
- データ量/1ユーザ (50 KB)
- 想定ユーザ数 (DAU 70万)
- データの更新頻度
- 各サーバの最大同時接続数
- 各サーバの台数、スペック、コスト
- 想定ユーザ数を超えた場合のスケールの
ポイント整理
29. インフラ構築時
• 性能検証
- 帯域幅を確認 (350Mbps程度)
- MongoDBを検証 (MongoDB 2.0.1、
ReplicaSetのShardを2つ、ジャーナリ
ング有効)
• 参照/更新の処理性能
• マイグレーション時の性能比較
• Javaドライバー経由の性能比較
- アプリケーションを通した性能を確認
30. インフラ構築時
• 障害を想定した動作検証
- mongodが落ちた場合
• PRIMARYへ昇格するか
• 起動したらデータが同期されるか
• SECONDARYが落ちても問題ないか
- mongocが落ちた場合
• 全体の動作に影響がないか
- バックアップから戻せるか
→ 全て問題ナシ
31. インフラ構築時
• ReplicaSet、Shardの構成と配置を決定
- メモリサイズを大きめ
- ディスクI/Oが高速
- mongocはmongodと別サーバに
- 信頼性を高めるためにEBS利用 (負荷軽
減のためSECONDARY専用に)
• ジャーナリングを有効に
• oplogsizeを10GBに (デフォルトの全体の
5%が多すぎるため)
32. インフラ構築時
• 必要なIndexはあらかじめ作成しておく
- 通常のIndex作成中は、全てのオペレー
ションがブロックされてしまうため
- 20万件のデータ (それぞれ50KB程度)
にIndexを貼ると、2分程度かかる
- あとから追加する場合は、メンテ中に作
成するか、バックグラウンドで作成
33. インフラ構築時
• コネクションプールをチューニング
※ mongosに対するコネクションプール
項目 意味 値
connectionsPerHost コネクション数 100
threadsAllowedToBlockFor 1コネクション辺りの
4
ConnectionMultiplier 接続待ち数
- nginxのworker数、TomcatのThread数
とのバランスを考慮して設定
- プールが足りなくなったときのエラー
(Out of Semaphores) に注意
上記例では、100 + (100 * 4) = 500