狠狠撸

狠狠撸Share a Scribd company logo
ソーシャルゲームにおける
AWS/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
? 惭辞苍驳辞顿叠概要
? Animal Land概要
? AWS利用時のポイント
? MongoDB利用時のポイント
? 発生した障害
? 课题
? まとめ
惭辞苍驳辞顿叠概要
Document-oriented
? スキーマレス
? BSON形式(Binary JSON)
> db.users.save( { name : "Alex", age : 20 } );
> db.users.save( { name : "Beth" } );
> db.users.?nd();
{ _id : ObjectId("..."), name : "Alex", age : 20 }
{ _id : ObjectId("..."), name : "Beth" }

> db.items.save( { id : "item01", name : "hoge", price : 1 } );
> db.items.?nd();
{ _id : ObjectId("..."), id : "item01", name : "hoge", price : 1 }
Full Index Support
? ドキュメント内のどの属性にもIndexを作
 成可能
? Unique Index、複合Indexにも対応
Replication
? ReplicaSetにより高可用性を実現
                   mongod
                 (PRIMARY)




      mongod                    mongod
   (SECONDARY)               (SECONDARY)
Replication
? ReplicaSetにより高可用性を実現
                mongod
                (DOWN)




      mongod                mongod
    (PRIMARY)            (SECONDARY)
Replication
? ReplicaSetにより高可用性を実現
                   mongod
                (RECOVERING)




      mongod                  mongod
    (PRIMARY)              (SECONDARY)
Replication
? ReplicaSetにより高可用性を実現
                   mongod
                (SECONDARY)




      mongod                 mongod
    (PRIMARY)             (SECONDARY)
Auto-Sharding
? 指定したShard Keyで水平分割
Shard 1
users (shardkey=name)
  Alex     Beth   Chris
  Daniel   Fred    George
  Maria    Nancy    Phil

items (shardkey=id)
  item01 item02 item03
Auto-Sharding
? 指定したShard Keyで水平分割
Shard 1                     Shard 2
users (shardkey=name)
  Alex     Beth   Chris
  Daniel   Fred    George
  Maria    Nancy    Phil

items (shardkey=id)
  item01 item02 item03
Auto-Sharding
? 指定したShard Keyで水平分割
Shard 1                      Shard 2
users (shardkey=name)        users (shardkey=name)
  Alex     Beth   Chris        Maria   Nancy    Phil
  Daniel   Fred    George
  Maria    Nancy    Phil

items (shardkey=id)         ?データ量の偏りを元に自動で
  item01 item02 item03       マイグレーション
                            ?マイグレーションはchunkと呼
                             ばれるShard Keyの特定範囲
                             (ここではMaria~Phil)
Auto-Sharding
? 指定したShard Keyで水平分割
Shard 1                     Shard 2
users (shardkey=name)       users (shardkey=name)
  Alex     Beth   Chris       Maria   Nancy    Phil
  Daniel    Fred   George
                                 mongosを介すことで、
                                 クライアントはShard構
items (shardkey=id)
                                 成を意識する必要なし
  item01 item02 item03
                                       Shard情報を保持
   client                                   mongoc
                       mongos               mongoc
                                             mongoc
   client                       Shard情報
Querying
? ?eld selection
 > db.items.?nd({id : "item01"}, {"name" : 1});


? sort
 > db.items.?nd({}).sort({"name" : 1});


? skip, limit
 > db.items.?nd({}).skip(20).limit(10);

? cursor
 > var cur = db.items.?nd({});
 > cur.forEach(function(data){ print(data.name) });
Animal Land
   概要
Demo


https://apps.facebook.com/animal-land/
開発期間
? 2011/03から開発スタート
? 初ミーティングが 3.11
? 本格的な開発は2011/05から
? 2011/12/09 リリース
開発メンバー
? Producer 2
? Designer 1
? Flash Developer   3
? Engineer 4
  +α
利用サービス
? Amazon Web Services
  - EC2 (Amazon Linux, Instance Store)
  - EBS
              m1.large    m2.2xlarge
  Memory      7.5 GB       34.2 GB
   ECU           4           13
  Storage     850 GB       850 GB
    I/O        高速            高速
利用サービス
? Amazon Web Services
  - S3
  - CloudFront
  - Route53
  - Elastic Load Balancing

? Google Apps
? Kontagent
システム間のつながり

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

                                     Web
          HTML
                                     サーバ
                   JSON


                                    Command
          Flash
                                     サーバ
                   AMF

                  AMF : Actionscript Message Format
AMF利用時の注意
? RemoteObjectを利用すると、HTTPセッ
 ションが使われてステートフルになってし
 まう
 - スケールアウトしづらい
? NetConnectionを直接利用することで、
 ステートレスにして解決
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
                           EBS                      admin           L       ビルド               L
        mongod
                                                        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.4
? 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
AWS
利用時のポイント
EC2
? 環境ごとに適切なリージョンを選択
  - 開発環境は効率を重視して東京
  - 本番環境はCalifornia(Virginiaは障害が
  多いと判断)


? 1年以上使うインスタンスはReservedに
 するとかなりお得
EC2
? AMIを作成しておくとサーバ追加が楽
  - image作成
ec2-bundle-vol -d [image出力先] --privatekey [EC2インスタン
ス作成時に利用した秘密鍵] --cert [アクセス証明書] --user
[AWSの口座番号]

  - S3へアップロード
ec2-upload-bundle --bucket [S3のバケット] --manifest [作成
したimageのマニフェストファイル] --access-key [アクセスキー]
--secret-key [シークレットキー]

  - 管理画面でimageを登録
EC2
? 必要に応じてEBSを利用
  - 別のインスタンスにマウントし直すこと
 が出来るので、いろんな用途で使える
- SNAPSHOTでバックアップ可能
EC2
? 注意点
  - 別インスタンスで利用されていたIPアド
 レスが再利用される
 ? 外部公開のサーバは、各種ログで異常
  を確認しておいた方が良い
EC2
? 注意点
  - 同じスペックでもI/O性能に差がある
    ? ストレージで利用するサーバは、ツー
         ルなどで検証しておいた方が良い
                        連続書き込み                              連続読み込み
   対象       Char単位      Block単位        Rewrite      Char単位      Block単位
          K/sec CPU     K/sec   CPU   K/sec CPU K/sec CPU       K/sec    CPU
m2.2xlarge 55484   68   71216    12   61546       7 86701   99 3034488    99
m2.2xlarge 81659   99 245211     47 133788       17 87943   99 3154005    99
ebsマウント 81476      98 186995     34 129284       16 83300   99 3090866    99
                                                     bonnie++の分析結果の一部
EC2
? 注意点
  - サーバ再起動がスケジューリングされる
 ことがある
 ? 大抵は1W~2W程度の猶予があり、期
  間内に自分で再起動すれば良い
- 稀にサーバ停止もスケジューリングされ
 る???
 ? 代替サーバを立てて移行が必要
Elastic Load Balancing
? 同じEC2インスタンスは複数のELBにはつ
なげられない
? EC2インスタンスを全て切り離すと、次回
つなげた際にELBの起動時間がかかる
- メンテ時はSorryサーバをつなぐ運用
 運用中                  メンテ中
        ELB                  ELB



  Web   Web   Sorry    Web   Web   Sorry
S3 + CloudFront
? CloudFrontのキャッシュクリアは難しい
? キャッシュクリアをしない運用
  - S3のパスにバージョン番号を入れる
  ?[S3バケット]/swf/1.0.3/main.swf
  ?[S3バケット]/image/1.0.8/icon/xxx.png


 - バージョン毎に全ファイルをUploadす
  るため、並列Uploadで効率化
  https://github.com/pcorliss/s3cmd-modi?cation
MongoDB
利用時のポイント
MongoDB採用の理由
? Ameba Picoでの利用実績
? Animal Landの要件に合う
  - 複雑なデータ構造 (街のグリッド情報、
 ユーザ/建築物のパラメータ、etc)
- 順次処理中心で、同時更新が少ない
- メンテナンスレス
  ? データ構造の動的変更
  ? 耐障害性、スケールアウト
MongoDB採用の理由
? MongoDBが苦手な部分は他の方法で解決
  - 特性に合わないデータは他のDBで
    ? 信頼性が必要な課金関連はMySQL
    ? 一時的なデータはmemcached
  - トランザクションは利用しない
アプリケーション開発時
? トランザクションがいらないデータ構造
  - ユーザ情報などは、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" : xxx, "depth" : 3, "width" : 3, ... }, ...
  },
  "inventory" : [ { "id" : xxx, "size" : xxx, ... }, ... ],
  "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オペレーション
 での利用を意識 (後述)

             おすすめ書籍 →
アプリケーション開発時
? Globalは極力避けて、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/D(?)マッパーで開発を効率化
  - 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にデータが偏り、
   急激な負荷がかかる可能性があるため


? それ以外は監視任せでOK
発生した障害
MongoDBがダウン
? mongoc x 1 & mongod x 1
 (SECONDARY) が落ちた
? 原因はEC2インスタンスの仮想サーバホス
 トの障害
? プロセスを起動するだけで復旧
? サービスへの影響なし
Shard情報の不整合
? mongos上でmoveChunkしたら、他の
 mongosからはデータが見えなくなった
 - Shard情報がうまく伝わらないことがあ
  るらしい
 - 普段のマイグレーションでは問題ないの
  で、手動で行ったときはmongos再起動
数値の型変換エラー
? アプリから数値を入れると32-bit integer
 だが、コンソールから数値を入れると
 doubleとして扱われ、型変換に失敗
 - 入れる場合はNumberIntを利用
??※ まだドキュメントには書いてない
  > db.foo.save( { val : 1 } );
  > db.foo.save( { val : NumberInt(2) } );    1 : double
                                              16 : int
  > db.foo.?nd( { val : { $type : 16 } } );
  { _id : ObjectId("..."), val : 2 }
mongoimportの不具合
? mongoimportを実行したら、データ件数
 が1件減った
? ヘッダ行を無視する --headerline オプ
 ションが誤動作している模様
 - 再現性が不明(一部環境でのみ発生)
 - mongodumpを利用&件数を常に確認
データロストしかけた
? movePrimaryを実行したら、Shard情報
 が更新されないままデータが別Shardに移
 動してしまい、データが見えない状態に
 - 数万件のデータがロストしかけた
 - この問題は、当時ドキュメントに書いて
  なかった(今はこの問題が警告されてい
  る)
AWSネットワーク障害
? 数分間のネットワーク障害
? サーバへのPINGも通らない状態
? AWS Service Health Dashboardを見て
 復旧を祈る???
 http://status.aws.amazon.com/
课题
オンライン?バックアップ
? MongoDBはやはり難しい
? 当面はメンテを入れてバックアップ
? 以下のSECONDARYバックアップも検討
中
1. balancerをオフに
2. SECONDARYでwrite lockをかけて
    ディレクトリ毎バックアップ
3. SECONDARYのロックを解除
MongoDBアップグレード
? バージョンがどんどん上がるので、サービ
スを運用しているとアップグレードのタイ
ミングが難しい
- 基本的には、Release Noteで問題のあ
 るバグがFixされてたら対応
Shardの追加
? Shard追加は可能だが、追加時のマイグ
レーションがパフォーマンスに与える影響
が読めない
- Picoではパフォーマンスの影響が問題と
 なったため、メンテ中に対応している
最適なchunksize
? ユーザ情報のデータサイズが大きかったた
め、デフォルトの64MBだとマイグレー
ションが多発
? データサイズに合わせて調整する必要があ
る
- Collectionごとにchunksizeが設定出来
 ればいいのに???(まだない)
データの分析
? ユーザ情報を1つにまとめたため、データ
 の分析がやりづらい
? 必要に応じてIndexを貼って対応中
  - MapReduceも試したが、検証時にパ
  フォーマンスに影響が出たので利用して
  いない
まとめ
AWS
? スタートアップに最適
? サーバ構成の変更にも対応しやすい
  - 簡単に出来すぎるので、サーバ管理は
 しっかりと(特にSecurity Group)
? 積極的に機能追加/改善されてる
? 多少の障害は許容が必要(障害検知と早期
対応が大事)
? コストは定期的に確認
MongoDBについて
? 学習コストが低い
? 使いどころがあっていれば、開発も運用も
すごく楽
? RDBの単純な置換えはNG
? 絶賛開発中のプロダクトなので、いろいろ
覚悟して使う
ご清聴
ありがとうございました




  https://apps.facebook.com/animal-land/

More Related Content

ソーシャルゲームにおける础奥厂/惭辞苍驳辞顿叠利用事例