ソーシャルアプリにおけるKVSの利用事例
株式会社gumi堀内康弘
• 株式会社gumi CTO• Twitter: horiuchi• 10年くらいウェブアプリ作ってます。
– Perl 10年、Python 1年• ゲームが好きです。
– モンハン3予約しました!• ランニング、筋トレにはまってます。
自己紹介
会社紹介
• 35タイトル以上のアプリを開発・運用• 延べユーザ数10,000,000人• 多プラットフォーム展開
– mixi、モバゲ、GREE• ソーシャルゲームはもちろん、ソーシャル
ライフ分野のアプリも作ってます
ソーシャルゲーム x ソーシャルライフ
ソーシャルライフ系 ソーシャルゲーム系
サポートツール系
・空飛ぶ →マイミク通信簿 340万
Rekoo 650万 →サンシャイン牧場 460万Rakoo 380万 →みんなの農園 160万 →みんなの動物広場 140万
・DeNA →怪盗ロワイヤル 250万・ ウノウ →まちつく 270万・ ベクター 190万 →恋する私の王子様 150万
・ GPS連動アド・ リワードプラス(アドウェイズ)・ poncan(ドリコム)
・ Facebook connect・ mixi connect・ connect with twitter・ gree connect
ファンクラブ同級生掲示板卒業アルバム同級生を探せ
幕末英雄伝キャバウォーズ刑事ハードボイルド現在開発中×2
占い診断系×40+
ソーシャルライフ
ファンクラブ 220,000人
同級生掲示板 520,000人
卒業アルバム おとなver. 300,000人
同級生をさがせ! 120,000人
占い、診断系アプリ
SM診断〜あなたの本性暴きます
浮気性チェック!その愛本物?ニセモノ?
犬タイプvs猫タイプ
草食系 vs 肉食系ザ★おバカ検定
むっつり度ちぇ〜っく!!A型度判定〜本当にA型ですか?
常識・非常識〜あなた常識人?KY診断〜空気読めてる?ナルシスト★診断モテ↑非モテ↓診断
B型度判定〜ジーマーで型B?じじばば検定〜若さ保ってる?フリ派?フラれ派?AB型度判定〜ABですが何か?
O型度判定〜う〜んO型かなぁ?
2人のラブラブ度診断
恋の成就度診断のだめカンタービレ進級試験初級
戦国雑学王決定戦★立志編
のだめマエストロコンクールノーマル?orアブノーマル?
のだめカンタービレ進級試験中級
のだめカンタービレ進級試験上級
戦国クイズ王全国ランキング
合計 約600万ユーザー
ソーシャルゲーム
• 2010年2月 幕末英雄伝 670,000人• 2010年3月 キャバウォーズ 1,320,000人• 2010年4月 刑事ハードボイルド 600,000人• 2010年5,6,7月 多プラットフォーム展開• 2010年8月 ハッピー☆モデル 70,000人
ソーシャルアプリの特徴
従来のウェブアプリとほとんど変わりません
ソーシャルアプリと従来のウェブアプリとの違い
• やりとりする相手が違う。• ユーザー認証の方法が違う。• APIが用意されている。• アクセス量が半端ない。• データの更新頻度が高い(ゲーム)
やりとりする相手が違う
• 相手はプロバイダ(mixi,モバゲ,GREE)
ユーザー認証
• Oauth signagureで身元保証• QueryStringからユーザーID取得
– opensocial_owner_id
GET /m/?opensocial_app_id=1234&opensocial_viewer_id=5678&opensocial_owner_id=5678
APIが用意されている
• PeopleAPI– ユーザー情報、友達情報を取得
• ActivityAPI– ユーザーの行動履歴を更新
• PaymentAPI–課金を行う
• 招待を送れる仕組み• 位置情報を送信する仕組み• ひと言を送信する仕組み
膨大なアクセス量
• リリース直後に数万人• 1ゲームで3000万PV/日
最初から負荷を考慮した設計が必要
どこがボトルネックになるの?
どこを考慮したらいいの?
ずばりDBです。
なぜDBがボトルネックになるの?
● Writeのスケールが難しい● テーブル毎にDBを分けたり● テーブル自体を分割したり
● SQLによっては時間がかかる● たくさんの行を一度に読むようなSQL● 大きいテーブル同士をjoinするようなSQL
解決策は?
• 遅いクエリの見直し– 主キーによる参照を意識する– ManyToManyは基本使わない– Filterもあまり使わない– Joinもほとんど使わない
• テーブル設計の見直し– 更新の多いカラムは別テーブルにする
それでもだめなら
DBへのアクセス自体を減らす
どうやってDBへのアクセスを減らすか?そこで登場するのがKVS です
gumiで活用しているKVS
• Memcached (Readを減らす)– オンメモリなハッシュテーブル– スケーラブル– サーバを再起動するとデータは消える– Django標準機能で簡単に使える
● TokyoTyrant (Read Writeを減らす)– モダンなDBMでデータの永続性あり– MySQLより高速に読み書きできる
● 読み書き20000qpsくらい
memcachedの使いどころ
• 毎回取得するようなモデルをキャッシュ– Playerインスタンスをキャッシュ
• リアルタイム性の低いページをまるごと– @cache_pageデコレータ
• 2度押し対策の軽いセッション管理に
キャッシュ実装例
def get_player(id): """ idからプレイヤーインスタンスを取得 """ path = "/player/"+str(id) player = cache.get(path, None) if player is None: # キャッシュに存在しない try: player = Player.objects.get(id=id) cache.set(path, player) # インスタンスをsetできる except Player.DoesNotExist: player = None return player
TokyoTyrantの使いどころ
• 更新頻度の高いデータの管理– プレイヤーの現在のパラメータ– 経験値、所持金
• 取得コストの高いSQLを発行するようなデータを管理する
– 自分の近況一覧– 全国ランキング– 最大攻撃力– 貢ぎ物総額
サーバ構成
まとめ
memcached + TokyoTyrantでDBのボトルネックをすっきり解消!
それでもだめなら「okuyama」で
ご静聴ありがとうございました。
人材絶賛募集してます!Twitter: horiuchi
Mail: [email protected]