こんにちは、いつの間にかチームぽわわ2のメンバーになっていたいっちーです。
@9reさんと @mackee_wさんとでISUCON3の予選に参加してきました。 主にアプリの書き換えを担当していたので、やったことを残しておきます。 チーム全体の方針とか役割分担とかはまこぴー先生の#isucon 予選でとりあえず10位だったを参照。
お題
gistみたいなWebアプリ。 社内ISUCONのときと似たようなお題ですね。 違いは…
- スターは無い
- Recent Postsのサイドバーが無い代わりに、ページングしてたどっていけるページがある
- privateな投稿ができる
- Markdown形式で投稿できて、表示はHTMLでレンダリングされる
詳しくは、れもんさんの#isucon 2013年予選問題の解説などを参照。
やったこと
一言で言えば、Redisにキャッシュするようにしました。
RecentをRedisのリストで管理
Recentの表示で日付順ソートしているのが重たそうだったので、 公開メモのソート結果をあらかじめRedisのリストに入れておく作戦。
RedisのSORT
コマンドが高機能で面白いなーって思ってたので使ってみました。
リストにはメモのIDだけ入れておいて、メモの実体は別のキーを参照する、なんてことができます。
このコマンド、SORT
って名前なのに「ソートしない」ってオプションあるところがいいですよね!
MySQLがボトルネックになっているのはこれで解消できました。
bin/markdownを使わない&レンダリング結果をキャッシュ
Markdownのレンダリングを外部コマンド叩いてやっていたので、 Text::Markdown::Discountを使ってレンダリングするように変更。 qx{hoge}って記法はじめて見ました。Perlってやつはいろんな書き方があってよくわからないです。
Markdownの文法って亜種が結構あるので、レンダラをかえるのはちょっと怖かったんですが、全く問題なし。 スコアも3000くらい上がってかなり効果がありました。
さらにレンダリング結果をRedisに入れてキャッシュで+1000くらい。
Recentのレンダリング結果をキャッシュ
RecentをRedisでさばくようにしたけど、そもそも100要素もあるHTMLのレンダリングそうとう重いはず。 と、いうわけでここもRedisにキャッシュするようにしました。 公開メモが投稿されたらRecent/:pageのキャッシュを全部削除。 Postのたびにキャッシュクリアされるのであんまり効果ないかなーと思っていたけど、わりと効果あったみたい? (正確なスコアよく見てなかった)
Redis::Fast!!
残り時間も少なくなり時間内にできることも限られれきたので、最後の最後でRedis::Fastを投入。 これで+1000くらい上がったらしい。(正確なスコアよく見てなかった)
s/Redis/Redis::Fast/ するだけの簡単なお仕事の予定が、githubからのインストールに一番手間取った。
cpanfileにgitのレポジトリを書くと(非公式だけど)インストールできるよ!ってどこかで見た気がするけどなかなかうまく行かず、
自分でgit clone
してそのディレクトリを指定してインストール(したってまこぴー先生が言ってた)。
(hiredis.h
が無い!って叫んでいたから、cartonがsubmoduleをうまく処理できていなかったと予想。
非公式の機能に頼るの良くないね。)
できなかったこと
- my.cnf?なにそれ美味しいの?
- SQLクエリをいじる余裕がなかった
- Newer/Olderのクエリが残念なのはわかってたけど、結局いじってない
- Nginxでキャッシュしたい
- 必要なモジュールは事前にCPANにあげておこう。
まとめ
結果は13192.1点で10位でした。 特に問題がなければこのまま予選突破できるはず・・・!
ところで、魔王軍が学生枠を制圧していて恐ろしいですね。 てか、僕らのチームとの差、500点程度しか無いじゃないですか。怖!!! これ以上の侵攻はなんとしてでも食い止めなければ。