LoginSignup
3
4

More than 5 years have passed since last update.

ISUCON6予選参加記

Last updated at Posted at 2016-09-19

会社の同僚(J_ogawa,hama_du)とチーム「週5労働撲滅委員会」で参加した。

背景

常日頃J_ogawaが週5労働は体に悪いと力説していて、そのためには相応の開発スキルや生産性の高さが必要なので、チーム名を「週5労働撲滅委員会」とした。(命名は私)
業務ではRuby/RailsなのでRubyで参加することに。

練習1 pixivの社内ISUCON

各自で予習する。普段はRailsを使っていて、Sinatraは未経験なのでまずそこから。
NginxやMySQLの設定、ローカル環境で動かす、indexを貼るなど、基本的なところのみやってみた。
Slackを使い始める。

練習2 ISUCON4予選

実践的な練習ということで、部屋を借りて4時間ほどやる。なお部屋はSpaceeで探した。(安くて良かったけど、レビューを読むとWifiが使えない部屋も多いようなので、確認したほうがよい)

各自で環境構築や、重そうなところの共有など。
rack-lineprofで解析、Redisでキャッシュするなど、ISUCONでよくあるアプローチをやってみた。

refererがないときはNginxで静的ページを返せば爆速になりそうだが、そこまで至らず。

練習3 ISUCON5予選

同じ部屋が予約できなかったので、会社でやることに。
ちょうどこちらの記事があがっていて、Azureだしこれに挑戦。
isucon5 予選の復習を Azure 上でやってみる(1)
当日はUbuntu 15.04だったようだ。最初にUbuntu 14.04で試したらsystemdの仕様が違っていて起動スクリプトが使えなかった。openjdk-8も非公式だったり。
Ubuntu 16.04では大丈夫だった。

当日と同じような感じで進められるように練習した。
githubのリポジトリで、個人でブランチを作って各自で適宜デプロイいつつ、いいものはmasterにマージする、という感じ。
デプロイはrsyncでローカルディレクトリをコピー。

ベンチでUnicorn直接だといけるけど、Nginxを通すと「リダイレクト先が / でなければなりませんが http~ でしした」というエラーが出てNginx経由のベンチができず。

#TARGET=IP_ADDRESS:80
TARGET=IP_ADDRESS:8080
jq '.[0]' < ../webapp/script/testsets/testsets.json | gradle run -Pargs="net.isucon.isucon5q.bench.scenario.Isucon5Qualification $TARGET"

のように切り替えていたのだけど、あとでわかったが、Nginx経由かつポート番号を指定するとだめだったらしい。

userを丸ごとキャッシュした。最初(クラスのメンバ変数ではなく)インスタンスのメンバ変数に入れていたせいで、アクセス毎に全ユーザを読み込んでいて実は遅くなってたとか、いろいろなバグをエンジョイする。

帰宅後、こちらを読んで一通り試す。
ISUCON5 予選問題の解説と講評
rack-lineprof、ログの取り方、Nginxの設定、kataribeの使い方などを復習した。

1000件取得してから友達かどうかでフィルタして10件取得するのと、relationをjoinして10件取ってくるのだと結果が違わないか? とか、push型(ユーザー毎に友達の日記ID用のテーブルを用意して、自分が日記を書いたときにそこに配信するやりかた)のときに、友達を追加したら過去のぶんにも配信しないといけないのでは、などコーナーケースを考えてみたり。(今回のベンチマーカーはそこまでチェックしていないっぽい)

予選突破ラインは13898点だったらしいが、解説記事の手法なども取り入れたけどAzure Basic A3 (4 コア、7 GB メモリ) だと7000点くらいしかいかなかった。やりかたがまずいのか、GCEの性能が高いのか?

その他

UnicornをPassenger(Raptor)に切り替えたら速くなるのか、調べたり試したりしたが、全体に与える影響は軽微なようなので、やらなくて良さそうだった。

Why is FastCGI /w Nginx so much faster than Apache /w mod_php?
速さに違いが出るのが謎なときはシステムコールの呼び出し回数を測ってみるといいかも、みたいな記事を読んだりした。

一応C++でもいけそうか試した。
Writing Hello World in FCGI with C++
このページのFCGIのサンプルはとてもわかりやすく、簡単に試せた。ただ今回はRubyでチーム戦をするというのと、MySQLやRedisにアクセスするコードまでは書かなかったので、使わなかった。

当日

10時
初期設定はPerlでスコアは3283。Rubyに切り替えたら0になった。
Nginxでcss,img,js,favicon.icoを配信するようにした。

11時
isutarをisudaにマージしてdeployする。がホームディレクトリを全部消してしまいインスタンスを作り直す。ちょっと焦る。
クア・アイナの配達を頼んで気持ちを盛り上げる。

12時
keyword_lengthをカラム化したり、インデックスを貼ったりしてスコアが4000くらいを記録。
htmlifyが一番重そうなので、キャッシュするのと、処理の中身を軽くする方法を模索する。

13時
キーワード一覧をRedisにキャッシュするが、いくつかのページにキーワードが含まれていないと言われ、FAIL

14時
htmlifyの結果をキャッシュする。キーワードの更新(追加または削除)を記録するテーブルを用意して、キャッシュの作成時間よりもあとに更新されたキーワードがdescriptionに含まれていたときだけhtmlを再生成するようにした。スコアが10000を超える。

16時
キーワードの一覧をviewで一回だけ取得するようにした。スコアが30000を超える。

17時
ハッシュ化したキーワードをキャッシュしてみたが、FAIL

17:59
masterブランチに戻してqueueに投入して終了。18時ちょうどに見えなくなり、最終スコアは不明。33000くらい?

感想

事前に練習したおかげで、共同作業はおおむねうまくいったと思う。
VMのインスタンスを作り直す際、運営の方のレスが早くてとても助かった。(ストレージがacceptedから進まないので質問したが、結局待つだけでよかった。まっさらから作ると15分くらい必要だった)
CSSのcontent-typeがtext/plainでChromeで見たらプレーンになっていて、それを直したりしたが、ベンチマークには関係ないので無駄な時間を使ってしまった。午前中の時間の使い方はあまりよくなかった。

キャッシュのバグがつぶせなくて先に進めず、スコアが出なかったが、基本方針は間違っていなかったのかなと思う。くやしいのであとで復習する。
週5労働を撲滅する日は遠い。

とても面白かったので、運営の方々とチームメンバーに感謝!
また来年も出たい!

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4