ソーシャルゲームにおけるAWS/MongoDB利用事例
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

ソーシャルゲームにおけるAWS/MongoDB利用事例

  • 13,197 views
Uploaded on

QCon Tokyo 2012で発表した資料。...

QCon Tokyo 2012で発表した資料。
AWSやMongoDBの利用のポイントなど。

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
13,197
On Slideshare
11,951
From Embeds
1,246
Number of Embeds
11

Actions

Shares
Downloads
94
Comments
1
Likes
37

Embeds 1,246

http://d.hatena.ne.jp 543
http://slide.yoshiday.net 308
http://pascal.plustar.jp 191
https://twitter.com 101
http://slide.localhost 76
http://127.0.0.1 19
http://s.deeeki.com 3
http://gacha.localhost 2
http://webcache.googleusercontent.com 1
https://si0.twimg.com 1
http://wayback.archive.org 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. ソーシャルゲームにおけるAWS/MongoDB利用事例 Masakazu Matsushita Cyberagent, Inc.
  • 2. About Me• 松下 雅和 / Masakazu Matsushita• @matsukaz• Cyberagent, Inc. - SocialApps Division - Ameba Pico (2011/01∼) • 海外向けピグ - Animal Land (2011/03∼)• DevLOVE Staff
  • 3. Agenda• MongoDB概要• Animal Land概要• AWS利用時のポイント• MongoDB利用時のポイント• 発生した障害• 課題• まとめ
  • 4. MongoDB概要
  • 5. Document-oriented• スキーマレス• BSON形式(Binary JSON)> db.users.save( { name : "Alex", age : 20 } );> db.users.save( { name : "Beth" } );> db.users.find();{ _id : ObjectId("..."), name : "Alex", age : 20 }{ _id : ObjectId("..."), name : "Beth" }> db.items.save( { id : "item01", name : "hoge", price : 1 } );> db.items.find();{ _id : ObjectId("..."), id : "item01", name : "hoge", price : 1 }
  • 6. Full Index Support• ドキュメント内のどの属性にもIndexを作 成可能• Unique Index、複合Indexにも対応
  • 7. Replication• ReplicaSetにより高可用性を実現 mongod (PRIMARY) mongod mongod (SECONDARY) (SECONDARY)
  • 8. Replication• ReplicaSetにより高可用性を実現 mongod (DOWN) mongod mongod (PRIMARY) (SECONDARY)
  • 9. Replication• ReplicaSetにより高可用性を実現 mongod (RECOVERING) mongod mongod (PRIMARY) (SECONDARY)
  • 10. Replication• ReplicaSetにより高可用性を実現 mongod (SECONDARY) mongod mongod (PRIMARY) (SECONDARY)
  • 11. Auto-Sharding• 指定したShard Keyで水平分割Shard 1users (shardkey=name) Alex Beth Chris Daniel Fred George Maria Nancy Philitems (shardkey=id) item01 item02 item03
  • 12. Auto-Sharding• 指定したShard Keyで水平分割Shard 1 Shard 2users (shardkey=name) Alex Beth Chris Daniel Fred George Maria Nancy Philitems (shardkey=id) item01 item02 item03
  • 13. Auto-Sharding• 指定したShard Keyで水平分割Shard 1 Shard 2users (shardkey=name) users (shardkey=name) Alex Beth Chris Maria Nancy Phil Daniel Fred George Maria Nancy Philitems (shardkey=id) ・データ量の偏りを元に自動で item01 item02 item03 マイグレーション ・マイグレーションはchunkと呼 ばれるShard Keyの特定範囲 (ここではMaria∼Phil)
  • 14. Auto-Sharding• 指定したShard Keyで水平分割Shard 1 Shard 2users (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情報
  • 15. Querying• field selection > db.items.find({id : "item01"}, {"name" : 1});• sort > db.items.find({}).sort({"name" : 1});• skip, limit > db.items.find({}).skip(20).limit(10);• cursor > var cur = db.items.find({}); > cur.forEach(function(data){ print(data.name) });
  • 16. Animal Land 概要
  • 17. Demohttps://apps.facebook.com/animal-land/
  • 18. 開発期間• 2011/03から開発スタート• 初ミーティングが 3.11• 本格的な開発は2011/05から• 2011/12/09 リリース
  • 19. 開発メンバー• Producer 2• Designer 1• Flash Developer 3• Engineer 4 +α
  • 20. 利用サービス• 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 高速 高速
  • 21. 利用サービス• Amazon Web Services - S3 - CloudFront - Route53 - Elastic Load Balancing• Google Apps• Kontagent
  • 22. システム間のつながりiframe 各種API呼び出し 課金 コールバック Web HTML サーバ JSON Command Flash サーバ AMF AMF : Actionscript Message Format
  • 23. AMF利用時の注意• RemoteObjectを利用すると、HTTPセッ ションが使われてステートフルになってし まう - スケールアウトしづらい• NetConnectionを直接利用することで、 ステートレスにして解決
  • 24. 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 バッチ MySQLShard 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 mongocEBS EBS mongos Maven SVN EBS Secondary
  • 25. ミドルウェア• nginx 1.0.x• Tomcat 7.0.x• MongoDB 2.0.4• MySQL 5.5.x• memcached 1.4.x
  • 26. フレームワーク/ライブラリ• Spring Framework、Spring MVC• BlazeDS、Spring Flex• Spring Data - MongoDB 1.0.0 M4• mongo-java-driver 2.6.5• Ehcache• spymemcached• RestFB• MyBatis
  • 27. AWS利用時のポイント
  • 28. EC2• 環境ごとに適切なリージョンを選択 - 開発環境は効率を重視して東京 - 本番環境はCalifornia(Virginiaは障害が 多いと判断)• 1年以上使うインスタンスはReservedに するとかなりお得
  • 29. 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を登録
  • 30. EC2• 必要に応じてEBSを利用 - 別のインスタンスにマウントし直すこと が出来るので、いろんな用途で使える- SNAPSHOTでバックアップ可能
  • 31. EC2• 注意点 - 別インスタンスで利用されていたIPアド レスが再利用される • 外部公開のサーバは、各種ログで異常 を確認しておいた方が良い
  • 32. EC2• 注意点 - 同じスペックでもI/O性能に差がある • ストレージで利用するサーバは、ツー ルなどで検証しておいた方が良い 連続書き込み 連続読み込み 対象 Char単位 Block単位 Rewrite Char単位 Block単位 K/sec CPU K/sec CPU K/sec CPU K/sec CPU K/sec CPUm2.2xlarge 55484 68 71216 12 61546 7 86701 99 3034488 99m2.2xlarge 81659 99 245211 47 133788 17 87943 99 3154005 99ebsマウント 81476 98 186995 34 129284 16 83300 99 3090866 99 bonnie++の分析結果の一部
  • 33. EC2• 注意点 - サーバ再起動がスケジューリングされる ことがある • 大抵は1W∼2W程度の猶予があり、期 間内に自分で再起動すれば良い- 稀にサーバ停止もスケジューリングされ る・・・ • 代替サーバを立てて移行が必要
  • 34. Elastic Load Balancing• 同じEC2インスタンスは複数のELBにはつなげられない• EC2インスタンスを全て切り離すと、次回つなげた際にELBの起動時間がかかる- メンテ時はSorryサーバをつなぐ運用 運用中 メンテ中 ELB ELB Web Web Sorry Web Web Sorry
  • 35. 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-modification
  • 36. MongoDB利用時のポイント
  • 37. MongoDB採用の理由• Ameba Picoでの利用実績• Animal Landの要件に合う - 複雑なデータ構造 (街のグリッド情報、 ユーザ/建築物のパラメータ、etc)- 順次処理中心で、同時更新が少ない- メンテナンスレス • データ構造の動的変更 • 耐障害性、スケールアウト
  • 38. MongoDB採用の理由• MongoDBが苦手な部分は他の方法で解決 - 特性に合わないデータは他のDBで • 信頼性が必要な課金関連はMySQL • 一時的なデータはmemcached - トランザクションは利用しない
  • 39. アプリケーション開発時• トランザクションがいらないデータ構造 - ユーザ情報などは、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", ... } ], ...}
  • 40. アプリケーション開発時• データ量を可能な限り削減 - 街のグリッド情報を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..."
  • 41. アプリケーション開発時• フィールド数は多すぎないように - 2万以上のフィールド (144x144の街の グリッド情報 )を持つと、find()にかかる 時間は5秒以上に・・・ - データ量だけでなく、BSONのパースに かかる時間も考慮する
  • 42. アプリケーション開発時• Shard Keyは以下の方針で決定 - カーディナリティが低い値は使わない - よく使われるデータがメモリ上に乗る - 使われないデータはメモリ上に乗らない - 参照や更新が多いデータはバランスよく 各Shardに分散- Targetedオペレーション での利用を意識 (後述) おすすめ書籍 →
  • 43. アプリケーション開発時• Globalは極力避けて、Targeted中心に - Shard Keyでデータを操作 - Shard Key以外の操作はIndexを利用 Operation Typedb.foo.find({ShardKey : 1}) Targeteddb.foo.find({ShardKey : 1, NonShardKey : 1}) Targeteddb.foo.find({NonShardKey : 1}) Globaldb.foo.find() Globaldb.foo.insert(<object>) Targeteddb.foo.update({ShardKey : 1}, <object>) Targeteddb.foo.remove({ShardKey : 1})db.foo.update({NonShardKey : 1}, <object>) Globaldb.foo.remove({NonShardKey : 1})
  • 44. アプリケーション開発時• 更新頻度をなるべく減らす - マスタ情報はサーバ上でキャッシュ - ユーザ操作はまとめて処理 (5秒に1度) • Flash側でキューの仕組みを用意 • サーバ側はキューから取り出してシーケ ンシャルに処理 キューで保持 シーケンシャル処理 ユーザ操作 キュー Command Flash サーバ まとめて送信
  • 45. アプリケーション開発時• O/D(?)マッパーで開発を効率化 - Spring Data - MongoDBとラッパーク ラスを用意して効率よく開発 @Autowired protected MongoTemplate mongoTemplate; public void insert(T entity) { mongoTemplate.save(entity); } - オブジェクトをそのまま利用できるの で、RDBのO/Rマッパーより扱いやすい - Javaでも言うほど大変じゃない
  • 46. アプリケーション開発時• ロールバックは出来ない前提で実装 - ある程度のデータ不整合は諦める - 必ずユーザが不利益を被らないようにす る
  • 47. インフラ構築時• 従来のDBと同様に見積もり - データ量/1ユーザ (50 KB) - 想定ユーザ数 (DAU 70万) - データの更新頻度 - 各サーバの最大同時接続数 - 各サーバの台数、スペック、コスト - 想定ユーザ数を超えた場合のスケールの ポイント整理
  • 48. インフラ構築時• 性能検証 - 帯域幅を確認 (350Mbps程度) - MongoDBを検証 (MongoDB 2.0.1、 ReplicaSetのShardを2つ、ジャーナリ ング有効) • 参照/更新の処理性能 • マイグレーション時の性能比較 • Javaドライバー経由の性能比較 - アプリケーションを通した性能を確認
  • 49. インフラ構築時• 障害を想定した動作検証 - mongodが落ちた場合 • PRIMARYへ昇格するか • 起動したらデータが同期されるか • SECONDARYが落ちても問題ないか - mongocが落ちた場合 • 全体の動作に影響がないか - バックアップから戻せるか → 全て問題ナシ
  • 50. インフラ構築時• ReplicaSet、Shardの構成と配置を決定 - メモリサイズを大きめ - ディスクI/Oが高速 - mongocはmongodと別サーバに - 信頼性を高めるためにEBS利用 (負荷軽 減のためSECONDARY専用に) - 見積もりに合わせたサーバ台数
  • 51. インフラ構築時• ジャーナリングを有効化 - 障害時のデータロストの危険性を軽減 - パフォーマンスは低下するので注意• oplogsizeを10GBに設定 - デフォルトは全体の5%で大きいため - 障害発生から復旧作業にとりかかるまで の予定時間から算出
  • 52. インフラ構築時• 必要なIndexはあらかじめ作成しておく - 通常のIndex作成中は、全てのオペレー ションがブロックされてしまうため - 20万件のデータ (それぞれ50KB程度) にIndexを貼ると、2分程度かかる - あとから追加する場合は、メンテ中に作 成するか、バックグラウンドで作成
  • 53. インフラ構築時• コネクションプールをチューニング ※ mongosに対するコネクションプール 項目 意味 値 connectionsPerHost コネクション数 100 threadsAllowedToBlockFor 1コネクション辺りの 4 ConnectionMultiplier 接続待ち数- nginxのworker数、TomcatのThread数 とのバランスを考慮して設定- プールが足りなくなったときのエラー (Out of Semaphores) に注意 上記例では、100 + (100 * 4) = 500
  • 54. 運用時• db.printShardingStatus()でShard間の chunkの偏りを定期的にチェック - 必要があれば手動でchunk移動• 新しいCollectionの追加は慎重に - 最初はPrimary Shardにデータが偏り、 急激な負荷がかかる可能性があるため• それ以外は監視任せでOK
  • 55. 発生した障害
  • 56. MongoDBがダウン• mongoc x 1 & mongod x 1 (SECONDARY) が落ちた• 原因はEC2インスタンスの仮想サーバホス トの障害• プロセスを起動するだけで復旧• サービスへの影響なし
  • 57. Shard情報の不整合• mongos上でmoveChunkしたら、他の mongosからはデータが見えなくなった - Shard情報がうまく伝わらないことがあ るらしい - 普段のマイグレーションでは問題ないの で、手動で行ったときはmongos再起動
  • 58. 数値の型変換エラー• アプリから数値を入れると32-bit integer だが、コンソールから数値を入れると doubleとして扱われ、型変換に失敗 - 入れる場合はNumberIntを利用  ※ まだドキュメントには書いてない > db.foo.save( { val : 1 } ); > db.foo.save( { val : NumberInt(2) } ); 1 : double 16 : int > db.foo.find( { val : { $type : 16 } } ); { _id : ObjectId("..."), val : 2 }
  • 59. mongoimportの不具合• mongoimportを実行したら、データ件数 が1件減った• ヘッダ行を無視する --headerline オプ ションが誤動作している模様 - 再現性が不明(一部環境でのみ発生) - mongodumpを利用&件数を常に確認
  • 60. データロストしかけた• movePrimaryを実行したら、Shard情報 が更新されないままデータが別Shardに移 動してしまい、データが見えない状態に - 数万件のデータがロストしかけた - この問題は、当時ドキュメントに書いて なかった(今はこの問題が警告されてい る)
  • 61. AWSネットワーク障害• 数分間のネットワーク障害• サーバへのPINGも通らない状態• AWS Service Health Dashboardを見て 復旧を祈る・・・ http://status.aws.amazon.com/
  • 62. 課題
  • 63. オンライン・バックアップ• MongoDBはやはり難しい• 当面はメンテを入れてバックアップ• 以下のSECONDARYバックアップも検討中1. balancerをオフに2. SECONDARYでwrite lockをかけて ディレクトリ毎バックアップ3. SECONDARYのロックを解除
  • 64. MongoDBアップグレード• バージョンがどんどん上がるので、サービスを運用しているとアップグレードのタイミングが難しい- 基本的には、Release Noteで問題のあ るバグがFixされてたら対応
  • 65. Shardの追加• Shard追加は可能だが、追加時のマイグレーションがパフォーマンスに与える影響が読めない- Picoではパフォーマンスの影響が問題と なったため、メンテ中に対応している
  • 66. 最適なchunksize• ユーザ情報のデータサイズが大きかったため、デフォルトの64MBだとマイグレーションが多発• データサイズに合わせて調整する必要がある- Collectionごとにchunksizeが設定出来 ればいいのに・・・(まだない)
  • 67. データの分析• ユーザ情報を1つにまとめたため、データ の分析がやりづらい• 必要に応じてIndexを貼って対応中 - MapReduceも試したが、検証時にパ フォーマンスに影響が出たので利用して いない
  • 68. まとめ
  • 69. AWS• スタートアップに最適• サーバ構成の変更にも対応しやすい - 簡単に出来すぎるので、サーバ管理は しっかりと(特にSecurity Group)• 積極的に機能追加/改善されてる• 多少の障害は許容が必要(障害検知と早期対応が大事)• コストは定期的に確認
  • 70. MongoDBについて• 学習コストが低い• 使いどころがあっていれば、開発も運用もすごく楽• RDBの単純な置換えはNG• 絶賛開発中のプロダクトなので、いろいろ覚悟して使う
  • 71. ご清聴ありがとうございました https://apps.facebook.com/animal-land/