本稿では、「Developers Summit 2012」(デブサミ2012)において、2月16日に行われた株式会社サイバーエージェント 桑野章弘氏、並河祐貴氏によるセッション「大規模化するピグライフを支えるインフラ ~MongoDBとChefについて~」の内容を紹介する。 ピグライフは、サイバーエージェントがアバターチャット「アメーバピグ」内で提供するソーシャルゲームで、ガーデニングや料理・裁縫、ティーパーティー、牧羊などを楽しむことができる。2011年5月31日のオープンから3週間で100万ユーザを獲得し、2012年1月現在の会員数は360万人。サーバーサイドJavaScript(node.js)など先進的な技術の取り組みでも知られるが、本セッションではその一端が開発者自身によって語られた。
大規模環境でもスケーラビリティや冗長性を確保するMongoDB
ピグライフはアメーバピグのサービス内ゲームであるが、まったく別のシステムで動作しており、アーキテクチャもまったく異なる。アメーバピグがJava+MySQLという従来型のWebアプリケーションであるのに対し、ピグライフはアプリケーションサーバがNode.js、データベースサーバにはMongoDBを採用している。
MongoDBは、オープンソースのドキュメント指向データベースで、米10gen社によって開発・提供されている。いわゆるNoSQLの一種だが、KVSほど単純ではなく、JSONをベースとした「BSON(バイナリJSON)」によるスキーマレスで柔軟なデータモデルであることが特長だ。
本セッションの前半では、ビグライフでMongoDBを採用した理由とその運用成果について桑野章弘氏が発表した。その理由としては、次のようなアーキテクチャの課題を解決するためだという。
- 開発スピード
- サービスアーキテクチャの課題
- システムアーキテクチャの課題
- 冗長化
- スケーラビリティ
開発スピードの面で桑野氏がまず挙げたのは、Node.jsとの相性の良さである。データモデルがJSONベースで統一されるためシリアライズが不要になる。また、データ管理が柔軟に行えるため、機能追加時にSQLサーバならカラム追加が必要になるところが、スキーマにオブジェクトを追加してやることで、新しい機能に必要なデータセットをすぐに追加できる。
また、データベースサーバーにつきものの課題である冗長化とスケーラビリティに関しては、それぞれSharding(シャーディング)とReplicaSets(レプリカセット)という機能によって解決できる。
Shardingはデータ分散の仕組みで、データを自動でChunk(チャンク)に分割し、複数のmongodに分散して配置してくれる。これによってサーバの負荷を分散することができ、サーバを「横に増やしていく」スケーラビリティが実現できる。どのサーバにどのチャンクがあるかというシャード情報はmongocが管理している。
なお、MongoDBは、mongos、mongoc、mongodから構成される。mongodはShardingされたデータベースサーバー、mongocはその管理情報を持つサーバー、mongosはクライアントとShardingされたサーバー群を仲介し、ここではアプリケーションサーバに同居する形になっている。
ReplicaSetsは非同期レプリケーションの仕組みで、自動でプライマリ/セカンダリ構成を取ることができる。プライマリ昇格の決定のために実サーバが3台は必要になる(ただし投票権のみを持っているプロセスを利用してサーバを少なく保つことも可能)。
こういった機能により、アプリ側の実装コストは軽く、スケーラビリティと冗長性を確保したシステムが構築できた。現在は、140台という大規模のMongoDB群を運用している。ここで得られた障害対応などのノウハウが説明された。
まず、各サーバプロセスのキャパシティ・プランニングについて。mongocでは冗長性は同期書き込み(2フェーズコミット)で確保されているが、スケーラビリティがないので潤沢なリソースを使える状態しておくほうがよいという。
mongodは定期的にディスクに書き出すので、ディスクI/Oにはある程度の性能が必要だという。また、データをメモリキャッシュするため、メモリは多ければ多いほどよい。mongostatで状況を確認し、エラーが多くなったらメモリやShardingを追加する運用が必要だ。
そのほか運用のポイントとしては、explain()でクエリの確認をし、必要な箇所にindexを貼る。それにより、クエリの高速化を図ることができる(例では最大100倍の高速化が見られた)。2.0で高速化・コンパクト化されているのでバージョンアップしたほうがよい。
バックアップでは、fsyncコマンドでレプリケーションを一時停止してdumpを取得する。シャードごとに実行することで完全なデータが取れること。グローバルロックを避けるためには、書き込みの多いコレクションを別のクラスタに分ける。今後、コレクションレベルロックが実装されれば対応されること。
Chunkの偏りはAutoBalanceで勝手に移動してくれるが、データアクセス頻度ではないので、新しく入ってきたデータが頻繁にアクセスされると負荷分散にならない。手動でChunkを移動してバランスすると、全mongosの再起動が必要となるため運用が必要になる。今後の課題だが、2.0系ではAutoBalanceが改善されているようだ。
このように仕様や改善の余地はあるものの、 MongoDBはスケーラビリティを確保する要素は十分に持っており、ソーシャルゲームやモバイルゲームで開発するにはよいプロダクトで、サービスを安定運用しながら成長させるために大切な要素になる、というのがサイバーエージェントでの認識だ。
この記事は参考になりましたか?
- 【デブサミ2012】セッションレポート連載記事一覧
-
- 【デブサミ2012】17-A-1 レポート Jenkins開発者が語った、これからの「継続...
- 【デブサミ2012】16-C-2 レポート ピグライフのスケ―ラビリティを支える2つのイン...
- 【デブサミ2012】16-C-5 レポート より扱いやすく進化する次世代JavaScrip...
- この記事の著者
-
CodeZine編集部(コードジンヘンシュウブ)
CodeZineは、株式会社翔泳社が運営する開発者のための情報メディアです。日々の開発に取り組むエンジニアやテクノロジーを学びたい方に向けて、プログラミングやAI活用、開発ツール、エンジニアの学びとキャリアに関する記事をお届けしています。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社
この記事は参考になりましたか?
この記事をシェア
