考える×つくる×動かす

主に技術系のことを書いていきます。

社内のISUCONに参加しました。

昨日のことですが社内のISUCONに参加しました。

ISUCON2に関しては以下のブログに書いてあります
http://blog.livedoor.jp/techblog/archives/67728751.html
http://github.com/tagomoris/isucon2

今回はPHPを選択しました。
だって一番慣れてるしー
ホントだったらRubyでやりたいんだけどねー

実を言うと自分は業務がちょっと忙しくて
ソースを完全に見たのが当日の昼という状況でした。

まず基本的な設計指針

PHP不要モジュールの削除
→ほぼ必須モジュールのみだったので手を加えず

Apache不要モジュールの削除
→Auth系とかProxy系はOFF

・不要なサーバーのサービスのKill
→chkconfigで確認してPostfixとかOFF

CSS,JS,画像ファイルの最小化
→JSはGoogleから引っ張ってきて画像は圧縮してBASE64エンコで内部に埋め込み

・Memcacheの導入
→別途記載(1)

・DBテーブルカラムの最適化
→別途記載(2)

Apache等各種ログファイル出力のOFF
httpd.confですべてOFF

・Keep Aliveの設定
→一回のリクエスト数が少ないので重くなりOFFにした


まず初期状態でのベンチスコアは110チケット前後
WebよりもDBのLoadAverageがいっぱいな感じ。

Memcacheの導入(1)

スロークエリーが出ていた場所は

SELECT stock.seat_id, variation.name AS v_name, ticket.name AS t_name, artist.name AS a_name
FROM stock
JOIN variation ON stock.variation_id = variation.id
JOIN ticket ON variation.ticket_id = ticket.id
JOIN artist ON ticket.artist_id = artist.id
WHERE order_id IS NOT NULL
ORDER BY order_id DESC LIMIT 10

最近購入されたチケットの10件を取得して表示する場所。

これは様々なページで呼ばれていたのでMemcacheに入れた。
チケットが売れた時に10件を超えていた場合はarray_popし古いのを1件削除して
array_unshiftで直近で売れたチケット情報を加えることにした。

Memcacheの導入(2)

他の部分でスロークエリーが出ていた場所は

SELECT COUNT(*) FROM variation
INNER JOIN stock ON stock.variation_id = variation.id
WHERE variation.ticket_id = :ticket_id AND stock.order_id IS NULL

残りのチケットの枚数を取得する場所。

はじめの枚数をMemcacheに入れて、
チケットが売れた時にそのvariationの枚数を-1する処理に変更。

ここで400前後のスコアまで改善した。

APCの導入+サーバーのチューンナップ

APCを入れたらスコアが一気に700前後まで改善した。
KeepAliveはスコアが落ちたのでOFFにした。

DBテーブルカラムの最適化

アーティストとチケットと開催場所をDBではなくソースに直接配列として記述した。
これらの値は基本固定だったので配列として処理した。

以下やらなかったこと

・nginxの導入
→時間が足りなかった
Mysqlのエンジン変更
Mysqlサーバはボトルネックになってなかったから
フレームワークの変更
→時間が足りなかった
Mysqlのテーブルカラムの構造変更
(stockのseat_idをvarchar255から2個にカラム分割してintに変換しindexを貼り直す)
Mysqlサーバはボトルネックになってなかったから

以下反省点

・事前に時間を作ってちゃんとソースとサーバーを見ておくべきだった
・テストのソースをしっかりと確認してどこをテストしてるのかを確認すべきだった
・Webサーバっていう大まかな負荷を見るだけじゃなくて、
どの画面がボトルネックになっているのかっていうのをしっかりと把握すべきだった
・実際の業務じゃないので新しい技術に積極的にチャレンジしてもよかった

最後に

チームメンバーのお陰でなんと優勝することができました。
最小の処理でなかなかのパフォーマンスを引き出すことができ良かったかなと思います。
運営の皆様お疲れ様でした。次回ありましたら是非また参加したいです。

賞金5000円分の商品券もらったんで飲みにでも行きましょう(笑)