2012年8月23日木曜日

HEKK流ソーシャルゲームのアプリ構成

このエントリーをはてなブックマークに追加
エンジニアの草苅(@kusakari)です。

Happy Elements株式会社(以下、HEKK)では、モバイル向けのソーシャルゲームに注力して開発を行っています(PCアプリは中国の Happy Elements Ltd. で開発しています)。

HEKKでは全社的にサーバーサイドのプログラミング言語を Ruby で統一しており、フレームワークは Ruby on Rails を使用しています。

データストレージには Cassandra と MySQL を併用しており、スケールする必要のあるデータ(ユーザーデータ)は Cassandra、マスターデータ(例えばアイテム情報)は MySQL に保存するという形で区別しています。

HEKKで開発しているソーシャルゲームの典型的なリクエストフローは、次の図のようなものです。

今回は Rails より後ろのデータストレージ3つを、どのように利用しているかについて簡単にご紹介します。

Cassandra

Apache Cassandra は facebook で開発された大規模データ処理用のKVS(Key Value Store)です。
利用箇所としては前述の通り、ユーザーデータ用のストレージとして利用しています。
HEKKでソーシャルゲームのデータストレージに Cassandra を選択した主な理由は、次のようなものです(一般的によく使われていると思われる MySQL との比較)。

書き込みがリニアにスケールする
ソーシャルゲームは通常のウェブサービスなどと比較して、書き込みの割合が多くなるため、書き込み処理がボトルネックになりやすい傾向があります。そのため、書き込みがリニアにスケールする必要があります。

単一障害点がない
MySQL の場合、マスターが落ちた際に無停止でサービスを運用し続ける難易度は高めです。特にソーシャルゲームで MySQL をメインのデータストレージとしている場合、必然的にDB分割なども必要になってくるため、さらに難易度は高くなります。しかし、Cassandra であれば単一障害点がないため、シンプルな構成で安定したサービス運用が可能です。

書き込み先のサーバーを意識する必要がない
MySQL の場合、アプリかアプリと MySQL の中間層が、書き込み先の MySQL サーバーを意識する必要がありますが、Cassandra であれば ring 内のどのサーバーに書き込んでも問題ないため、サーバーが増えたとき、減ったときなどにシャーディングに関する面倒な問題が発生しません。

ここまで Cassandra の良い点ばかり書いてきましたが、もちろん実際は良い点ばかりではありません。Cassandra と MySQL を比較した時に弱い点の一つとして、クライアントライブラリがあります。

Ruby 用のクライアントライブラリである cassandra.gem がミニマムな機能であることもあり、HEKKでは、Cassandra 内のデータへ ActiveRecord に近い感覚でアクセスできるように cassandra_object.gem を利用しています。また、実運用に耐えうるように、独自に次のような機能拡張を行っています。
  • Cassandra 0.7 以降に対応。
  • 追加の Callback Methods に対応。
  • register_attribute_type の MessagePack 対応。
  • Ruby 1.9.2、1.9.3に対応。
  • Rails3 専用にリファクタリング。

例えば、CassandraObject::Base を使うと次のように書けます。
class User < CassandraObject::Base
  attribute :nickname, :type => :string
  attribute :date_of_birth, :type => :date
  attribute :joined_at, :type => :time_with_zone
  attribute :preferences, :type => :msgpack
  key :uuid
  consistency_levels :read => :one, :write => :one
end
user = User.new(:nickname => "kusakari")
user.preferences = {:hoge => "A", :fuga => "B"}
user.save
user = User.get(uuid)
 => #<User:0x000000XXXXX @schema_version=nil, @key="YYYYY", @attributes={"nickname" => "kusakari", "preferences" => {"hoge" => "A", "fuga" => "B"}}>

さらに、CassandraObject::Base で対応できない、動的な Column Key のデータに対応するため、 cassandra.gem のラッパーライブラリとして CassandraObject::Lite::Base を開発して使用しています。


Memcached

Memcached はご存じの通り、キャッシュ用のミドルウェアです。
利用箇所としては主に MySQL のマスターデータのキャッシュ用ストレージとして利用しています。

memcached 用クライアントライブラリとしては dalli.gem(または memcache-client.gem) や memcached.gem がありますが、大きな違いは dalli.gem と memcache-client.gem はピュア Ruby、memcached.gem は c で書かれているという点です。HEKKでは memcached.gem を使用しています。
ただ、Windows 機で開発している場合、 memcached.gem が利用できないということもあり、memcached クライアント用のラッパーライブラリを作ることによって、アプリからは内部的に使用している gem を意識しないで済むような作りになっています。また、このラッパーライブラリ内で marshal load 時の Model の自動ロードなどの処理を行うなど、実用的な作りとなっています。

MySQL

MySQL については特筆すべきことはありませんが、前述の通り、基本的にはマスターデータのストレージとして使用しています。それに加えて、検索条件が必要になる場合や 、(Cassandra にはない)トランザクションを使って、強い一貫性を保障したい場合には MySQL にデータを格納するようにしています。
また、テーブルが一定以上の大きさになるような場合は、MySQL 5.1 以降で利用できるパーティショニング機能を使用するようにしています。


ということで、HEKK で開発しているソーシャルゲームのアプリ構成の中から、データストレージ部分について簡単にご紹介しました。

Rails や Cassandra を使って、大量のトラフィックをさばくソーシャルゲームを、京都で開発してみたいというエンジニアの皆さん、ご応募お待ちしています!

3 件のコメント:

  1. I suppose that happens because of educational problems. Moreover, I can advice you https://domyhomework.guru/blog/make-homework-fun if you want to be educated person, but don't know what to do with your homework.

    返信削除
  2. I'm the new one in programming. Can you tell me how to build my own profile database for this blog? Thanks!

    返信削除
  3. Thank for sharing!!!
    Ngày 10/12/2001, tại Doha, Qata, Bộ trưởng Bộ Hợp tác kinh tế và Ngoại thương Trung Quốc – ông Shi Guangsheng đã có mặt tại Hội nghị lần thứ 4 cấp Bộ trưởng các nước thành viên của WTO đã nhất trí thông qua quyết định về việc Trung Quốc gia nhập WTO.
    Hiện nay trên thị trường có rất nhiều loại Lens khách nhau. Để tránh trường hợp mua phải loại Lens giả kém chất lượng xin giới thiệu bạn cách phân biệt Lens Trung Quốc.
    order hàng Quảng Châu cũng là một trong những chuỗi kinh doanh trực tuyến, lấy nguồn hàng từ thành phố Quảng Châu – Trung Quốc và bán lại cho khách hàng trong nước

    返信削除