isucon4の予選に参加してみた

名前は聞いたことあったのでどんなもんかと思い参加してみた。本当は同僚と参加しようと思っていたのだが同僚が捕まらず一人で参加することに。まあ予選通過できなくても一人だしー不利だしーとか言ってればプライドが守れるしそんなに悪くないのかも。俺も成長したのか精神をコントロールする術を身につけた。

言語は普段使ってるRubyにする。

前日

  • AWSよくわかってないのでisucon3のAMIを起動したりDB接続したりして操作方法を調べる。
  • 一人しかいないのでソースをvimで直接編集することにし、dotfilesをcloneしてvim起動してプラグインインストールしたら久しぶりのプラグインアップデートでいくつか機能が動かず.vimrcを修正
  • 細かくプロファイルとってる時間ないと思うし、取るスキルもないのでざっくり遅いところを確認するためNew Relicとrack-mini-profilerのセットアップ方法を確認
  • Sinatraいじったことないので少し仕様を確認。シンプルですね。

明日に備えて0時就寝

当日

8:30に起床。近所のエクセルシオールでアイスカフェラテとビッグハムサンドを食って気合を入れる。 予選突破したら同僚に自慢しようとか考える。

10時

とりあえず環境セットアップ。EBS Availableの意味がわからずちょっと時間を無駄にする

11時

ざっとルーティングやらDBやらを確認。シンプルですね。初期スコアは1500くらい。

ぱっとみたかんじデータを全部メモリに載せれば早そうだけど、再起動時とかを考えるとちょっとあぶないのと、一人なので時間がたりなさそう。普通のチューニングをすることにする。普通にやってもまあまあ早くなりそう。

とりあえずIPでのbanとログインアカウントごとのlockがあるのだが、これらをlogin_logというテーブルから毎度毎度集計していて重そうなのでlogin_logにトリガ作って新しく作った集計テーブルとusersテーブルにon duplicate insert(update?)する。

これでlogin_logのselectはなくなる。トリガは通常のアプリだと複雑になりがちなのでこれまで使わなかったため、人生初のトリガになった。けどこれくらいシンプルなアプリならトリガでも問題ないだろ、という希望的観測。トリガそのもののパフォーマンスが悪いと死ぬけどまあ~大丈夫・・・だろ。

12時

ban判定からlogin_logへの参照を削除 スコアは2000台

13時

lock判定からlogin_logへの参照を削除 スコアは2000台 少しインデックスを調整するがそんなに早くなりそうもないので少しにしておく

14時

mypageで参照してるデータを全部login時にsessionに入れてmypageでdb読まないようにする。 スコアは3000前後であんまり上がってない。もう1万超えているチームもいて焦る

DBアクセス周りは大体こんなもんで、そろそろ静的ファイルをunicornからnginxにしようかな・・・と調べるとログインページとエラーページが全部静的ファイルにできそうなのでレギュレーションを確認。URLは変更してはいけないようだがquery stringは対象外らしくベンチでもfailしなかったので、ログイン失敗時にquery stringを付与し、nginxで判定して静的ファイルにマッピングすることにする

15時

nginxの設定にドはまり

16時

nginxの設定にドはまり(´;ω;`)ウッ…もうダメp

すごい絶望的な気分になるがこの設定を成功させないとこれ以上スコアを伸ばすのは難しい。

なんとか終わらせたが2時間くらいかかってしまった。

スコアは11000くらいで上がったが上位との差は埋まらない。

17時

もう時間もなくなってきたのでNew Relicとrack-mini-profilerをはずす。スコアは15000台

パスワードハッシュの計算をRubyからMysqlに移してみたがあんまり変化なし。

init.shにmysqlのウォームアップを入れるもそんなに変化なし。

my.confも少しいじる

しかし全然サーバに負荷かからねーな・・・やっぱメモリに全部載せるべきだったのかなーなどと考える

18時

タイムアップ!結局スコアは15000台で予選通過は5万前後かな?

はぁ〜俺って大したことないのかなー・・・意味ねえけどAMI提出すっか・・・辛い・・・同僚に自慢できない・・・

ここでworkloadというパラメータの存在に気づく

ためしにworkloadを設定してみるとポートが足りないエラーが出るので使えるポートを増やすのとリサイクル設定を入れる

workloadを20くらいにしたら38000くらいになった。(´;ω;`)ウッ… まあでもどうせ予選は通過できませんʕº̫͡ºʔ isuconは一人だと難しいと聞いていたが単純に時間が足りないので本当なんだということがわかった。 ログ出力消したりnginxとunicornのパラメータ詰めたりしたらもうちょい上がりそうだけど時間が足りない。

感想

  • いろいろあったが楽しかった。
  • NewRelicは良い。

反省

  • サーバまわりのスキルの無さを痛感
  • 知り合いをもっと作ろう