去年(2011)ソーシャルアプリの開発で失敗して今年(2012)改善したこと

去年(2011)ソーシャルアプリの開発で失敗して今年(2012)改善したこと

昨年はソーシャルアプリを3本程リリース。
反省としては、ゲームの内容うんぬんの前に
使い勝手と信頼性がまったく駄目だった。。という2点に尽きる。

具体的には

リリース直後->過負荷->レスポンス遅延->
APP,DBサーバー落ちる->トランザクション制御系でデータボロボロ->
ユーザー離れる

という流れを何度も経験。

特にトランザクションは、かなりルーズな作りだった為、
過負荷の時は、次のステージに行ったらボス不在というのはあったかもしれん<-酷過ぎる。。
※つまり、ステージクリア->次のステージ作成->ボス作成というフェーズが全て
成功した時点で処理を通さないと、ステージクリアして次のステージが無い等の状況に陥る。。
また過負荷を招いた原因としてログテーブルの存在が大きかったと言える。
ユーザーの行動履歴等をテーブルに残しているがこのデータが大量すぎて
deleteするにもできない位膨れ上がっていた。

これらを踏まえ、改善を行ったので箇条書きでまとめてみる。
※当たり前だろという内容ばかり。。

到達目標

  • 1.[レスポンスの向上]5秒以内に何らかのレスポンスを返す
  • 2.[データ信頼性向上]お金部分のトランザクションの制御など。

システム変更箇所

1.レスポンスのための設計を見直し

1-1.MySQLパーティション設定
ユーザーのアクションを記録するログテーブルの肥大化が
ボトルネックとなっていた。
日付毎でdeleteができない程肥大化する為、
日付別のパーティションを作成し、truncateで一括削除を行うように修正した。
インデックスサイズもパーティションで小さくなるため、検索速度も大幅に向上。
※パーティショニングはmysql5.1以上の為、5.0.77->5.5.19へ変更。

1-2.CakePHPのセッションストレージをcake->databaseへ
CakePHPで運用しているアプリケーションを複数台設置のため、
まずはセッションを管理するmemcaachedサーバーを用意。。
と思ったが、http://tech.kayac.com/archive/post_1.html
でmemcaachedでは他のデータの容量次第でセッションデータが
ロストする可能性があるとの記述。kyototycoonはまだ未調査のため
ひとまずセッション情報もデータベースに入れることに。
CakePHPのデフォルト設定で
cache[外部キャッシュエンジン],cake[/app/tmp配下],database[mysql].php[phpのセッションと統一]
が選べるのでdatabaseへ変更。
ついでに、cakephp1.2->1.3系に。
1-3.Apacheリバースプロキシ(mod_proxy)で負荷分散
appサーバーを複数台設置して、ロードバランスの設定。
書き方など非常に簡単でした。

1-4.負荷計測(Apache Bench)
Apache Bench,JMeterを使用して負荷計測。
JMeterだと単体テストのルール作りが面倒なため、サーバーの設定変更など
簡単に確認したいときはApahceBenchが便利だと感じた。
apacheやMySQLの設定、SQLの修正を行う都度
Apache BenchでRequests per secondを見ておき、
詳細なボトルネック調査などでJMeterを使うと便利な感じ。
ベースはsakuraVPSを入れて使うので、VNC必須。
1-5.MySQLのSlowQueryLogの確認
これは今まで通り。
cakephp標準のORマッパーを使っていて遅い部分はSQLで書いたり。
ActiveRecordも。
1-6.スクリプトの実行時間を制限
大規模ソーシャルゲーム「ドラゴンコレクション」運営の最前線で得られたノウハウ
http://codezine.jp/article/detail/6336?p=2
に書かれていた為、実践してみる。
内容はphpのset_time_limitを5秒に設定するという内容。
フレームワーク側ではこのset_time_limitをcatchできない為、独自の
エラーページを作成してそちらへ飛ばすように修正。
なんらかの組み合わせが影響して、長時間起動し続ける処理が制御できるのは〇。
このためにトランザクションの制御はきっちりかけておく必要がある。
1-7.ImageMagic->HTML5へおきなおし
簡単な画像の合成にも贅沢にImageMagic使っていた。
HTML5で画像重ねればいいじゃん、、ということで書き換え。
劇的に処理速度が上がった。
1-8.最新が必要でないテーブルのデータ取得はルーズに
トップページのお知らせ欄などは常にDBへ取りに行く必要がないので、
10回に1回等に変更した。

2.データの信頼性。

2-1.CakePHPトランザクション制御+MySQLのAutoCommitをOFF
cakephpのORマッパーだとテーブル毎にmodelを書くため、複数テーブルに対する
綺麗なトランザクションの書き方が今ひとつ分からない。
現状はすべてのmodel部分にそれぞれトランザクションを開始し、
全部製綱したら、さらにそれぞれcommitするようにしている。
A:begin B:bigin --> A:true B:true --> A:commit B:commit
2-2.MySQLのあいまいな自動変換をやめる
MySQLでは型より大きい値を入れようとしたり、型と違うものをねじ込もうとした場合
自動変換の機能でエラーを起こさずにinsertできてしまう。
例えば
数字大きすぎる->上限以下に切られる
数字型に文字 ->Nullになる
など。
mysqlでsql_mode='STRICT_ALL_TABLES'を設定し、
を全てphp側でcatchするように修正。

詳細ごとの細かい設定は随時メモ。
以上修正後、来月1本新しいアプリをリリース予定。
今年2012はどうなるか楽しみ。