狠狠撸

狠狠撸Share a Scribd company logo
ソーシャルゲームにおける
 MongoDB適用事例


       Masakazu Matsushita
           Cyberagent, Inc.
About Me
? 松下 雅和 / Masakazu Matsushita
? @matsukaz
? Cyberagent, Inc. - SocialApps Division
  - Ameba Pico (2011/01~)
    ? 海外向けピグ
  - Animal Land (2011/03~)
? DevLOVE Sta?
Agenda
? サービス概要
? システム构成
? MongoDB採用のポイント
? MongoDB利用時に考慮した点
? 発生した障害
? 今后の课题
? etc
サービス概要
Demo
開発期間
? 2011/03から開発スタート
? 初ミーティングが 3.11
? 本格的な開発は2011/05から
? 2011/12/09 リリース
開発メンバー
? Producer 2
? Designer 1
? Flash Developer   3
? Engineer 4
  +α
システム构成
利用サービス
? Amazon Web Services
  - EC2 (Instance Store + EBS)
  - S3
  - CloudFront
  - Route53
  - Elastic Load Balancing
? Google Apps
? Kontagent
システム間のつながり

iframe    各種API呼び出し
                              課金コールバック




                                            Web
          HTML
                                            サーバ
                      JSON


          Flash
                                          Command
                      AMF                  サーバ

                             AMF : Actionscript Message Format
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
ミドルウェア
? nginx 1.0.x
? Tomcat 7.0.x
? MongoDB 2.0.1
? MySQL 5.5.x
? memcached 1.4.x
フレームワーク/ライブラリ
? Spring Framework、Spring MVC
? BlazeDS、Spring Flex
? Spring Data - MongoDB 1.0.0 M4
? mongo-java-driver 2.6.5
? Ehcache
? spymemcached
? RestFB
? MyBatis
MongoDB
採用のポイント
? Ameba Picoでの利用実績




        http://apps.facebook.com/amebapico/
? MongoDBの良さ
  - ReplicaSetによる耐障害性
  - Auto-Shardingによるスケールしやすさ
  - 複雑なデータ構造を扱える
  - Index、Advanced Queries
  - 開発チームがアクティブ
  - 敷居が低い
? Animal Landの要件に合う
  - 複雑なデータ構造 (街のグリッド情報、
 ユーザ/建築物のパラメータ、etc)
- シーケンシャル処理中心で、同時更新が
 少ない
- メンテナンスレス
  ? データ構造の動的変更
  ? 耐障害性
  ? スケールアウト
? 苦手な部分は他の方法で解決
  - 特性に合わないデータは他のDBで
    ? 信頼性が必要な課金関連はMySQL
    ? 一時的なデータはmemcached
  - トランザクションは利用しない
MongoDB
利用時に考慮した点
アプリケーション開発時
? トランザクションがいらないデータ構造に
  - ユーザ情報などは、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 , ... } ],
  ...
}
アプリケーション開発時
? データ量を可能な限り削減
  - 街のグリッド情報を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...
アプリケーション開発時
? フィールド数は多すぎないように
  - 2万以上のフィールド (144x144の街の
  グリッド情報 )を持つと、?nd()にっかる
  時間は5秒以上に???
 - データ量だけでなく、BSONのパースに
  かかる時間も考慮する
アプリケーション開発時
? Shard Keyは以下の方針で決定
  - カーディナリティが低い値は使わない
  - よく使われるデータがメモリ上に乗る
  - 使われないデータはメモリ上に乗らない
  - 参照や更新が多いデータはバランスよく
 各Shardに分散
- Targetedオペレーション
 での利用を意識 (後述)

             おすすめ書籍 →
アプリケーション開発時
? Targetedオペレーションを中心に
  - Shard Keyでデータを操作
  - Shard Key以外の操作はIndexを利用
                  Operation                      Type
db.foo.?nd({ShardKey : 1})                    Targeted
db.foo.?nd({ShardKey : 1, NonShardKey : 1})   Targeted
db.foo.?nd({NonShardKey : 1})                 Global
db.foo.?nd()                                  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})
アプリケーション開発時
? 更新頻度をなるべく減らす
  - マスタ情報はサーバ上でキャッシュ
  - ユーザ操作はまとめて処理 (5秒に1度)
  ? Flash側でキューの仕組みを用意
  ? サーバ側はキューから取り出してシーケ
  ンシャルに処理
                                 シーケンシャル処理
   ユーザ操作
                     キューで保持
               キュー
                                  Command
       Flash
                                   サーバ
                       まとめて送信
アプリケーション開発時
? O/Rマッパーで開発を効率化
  - Spring Data - MongoDBとラッパーク
  ラスを用意して効率よく開発
   @Autowired
   protected MongoTemplate mongoTemplate;

   public void insert(T entity) {
         mongoTemplate.save(entity);
   }

 - オブジェクトをそのまま利用できるの
  で、RDBのO/Rマッパーより扱いやすい
 - Javaでも言うほど大変じゃない
アプリケーション開発時
? ロールバック出来ない前提で実装
  - ある程度のデータ不整合は諦める
  - 必ずユーザが不利益を被らないようにす
 る
インフラ構築時
? 従来のDBと同様に見積もり
  - データ量/1ユーザ (50 KB)
  - 想定ユーザ数 (DAU 70万)
  - データの更新頻度
  - 各サーバの最大同時接続数
  - 各サーバの台数、スペック、コスト
  - 想定ユーザ数を超えた場合のスケールの
 ポイント整理
インフラ構築時
? 性能検証
  - 帯域幅を確認 (350Mbps程度)
  - MongoDBを検証 (MongoDB 2.0.1、
  ReplicaSetのShardを2つ、ジャーナリ
  ング有効)
  ? 参照/更新の処理性能
  ? マイグレーション時の性能比較
  ? Javaドライバー経由の性能比較
 - アプリケーションを通した性能を確認
インフラ構築時
? 障害を想定した動作検証
  - mongodが落ちた場合
    ? PRIMARYへ昇格するか
    ? 起動したらデータが同期されるか
    ? SECONDARYが落ちても問題ないか
  - mongocが落ちた場合
    ? 全体の動作に影響がないか
  - バックアップから戻せるか
                → 全て問題ナシ
インフラ構築時
? ReplicaSet、Shardの構成と配置を決定
  - メモリサイズを大きめ
  - ディスクI/Oが高速
  - mongocはmongodと別サーバに
  - 信頼性を高めるためにEBS利用 (負荷軽
  減のためSECONDARY専用に)
? ジャーナリングを有効に
? oplogsizeを10GBに (デフォルトの全体の
 5%が多すぎるため)
インフラ構築時
? 必要なIndexはあらかじめ作成しておく
  - 通常のIndex作成中は、全てのオペレー
  ションがブロックされてしまうため
 - 20万件のデータ (それぞれ50KB程度)
  にIndexを貼ると、2分程度かかる
 - あとから追加する場合は、メンテ中に作
  成するか、バックグラウンドで作成
インフラ構築時
? コネクションプールをチューニング
 ※ mongosに対するコネクションプール
           項目              意味          値
 connectionsPerHost   コネクション数          100
 threadsAllowedToBlockFor 1コネクション辺りの
                                       4
 ConnectionMultiplier     接続待ち数

- nginxのworker数、TomcatのThread数
 とのバランスを考慮して設定
- プールが足りなくなったときのエラー
 (Out of Semaphores) に注意
 上記例では、100 + (100 * 4) = 500
運用時
? db.printShardingStatus()でShard間の
 chunkの偏りを定期的にチェック
 - 必要があれば手動でchunk移動

? 新しいCollectionの追加は慎重に
  - 最初はPrimary Shardにデータが偏り、
   急激な負荷がかかる可能性があるため
発生した障害
mongodとmongocダウン
? mongoc1台 & mongod1台
 (SECONDARY) が落ちた
? 原因はEC2インスタンスの仮想サーバホス
 トの障害、MongoDBは悪くない
? サービスへの影響はゼロ!
? プロセスを起動するだけで復旧!!
今后の课题
オンライン?バックアップ
? やはり難しい
? 当面はメンテを入れてバックアップ
? 以下のSECONDARYバックアップも検討
中
1. balancerをオフに
2. SECONDARYでwrite lockをかけて
    ディレクトリ毎バックアップ
3. SECONDARYのロックを解除
Upgrade
? サービスを運用しているとUpgradeのタイ
 ミングが難しい
? 以下のアップグレードの手順が必要
 1. Arbiterを停止、Upgrade、起動
 2. SECONDARYを停止、Upgrade、起動
 3. PRIMARYを停止、Upgrade、起動
Shardの追加
? Shard追加は可能だが、追加時のバランシ
ングがパフォーマンスに与える影響が読め
ない
- Picoではパフォーマンスの影響が問題と
 なったため、メンテ中に対応している
最適なchunksize
? ユーザ情報のデータサイズが大きかったた
 め、デフォルトの64MBだとマイグレー
 ションが多発
? データサイズに合わせて調整する必要があ
 る


Collectionごとにchunksizeが設定出来るよ
うになって欲しいです???
データの分析
? ユーザ情報を1つにまとめたため、データ
 の分析がやりづらい
? 必要に応じてIndexを貼って対応中
  - MapReduceも試したが、検証時にパ
  フォーマンスに影響が出たので利用して
  いない
ご清聴
ありがとうございました

More Related Content

ソーシャルゲームにおけるMongoDB適用事例 - Animal Land