Shogo's Blog

Oct 7, 2013 - 1 minute read - isucon perl

ISUCON3の予選に参加してきた

こんにちは、いつの間にかチームぽわわ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点程度しか無いじゃないですか。怖!!! これ以上の侵攻はなんとしてでも食い止めなければ。