ISUCON7予選に学生チームで参加して1日目3位枠で突破しました!

学生 3 人チームで ISUCON7 予選に参加し,1日目3位,総合10位で予選突破しました!チーム名は「都営三田線東急目黒線直通急行日吉行」です!

チームメイトは僕の研究室の同期である @0gajun と,Wantedly 2018 年卒内定者として同期の @izumin5210 の 3 人でした.@0gajun とは昨年の ISUCON6 にも2人で参加しました.ISUCON6 では,学生枠で本戦には進出できたものの最終結果は 3 位,学生枠と社会人枠の圧倒的なスコア差に打ちひしがれるという経験をしました.今年は最後の学生枠出場戦を全力で戦いたかったので,内定者として同じ Wantedly People チームでインターンをしていた @izumin5210 を誘って 3 人チームで出場してきました.

チーム編成は @0gajun がインフラを担当,@izumin5210 がアプリケーションを担当,僕はその間をうろうろしながら連携と分業がうまくできるように振る舞うのが役目でした.

事前練習

メンバー全員が Go を普段からインターン等で書いているチームだったので,言語選択は Go にしました.

チーム全員での事前練習として,ISUCON6 の記録を見ながら pixiv 社内 ISUCON に挑戦しました. Wantedly がイベントとして主催した ISUCON もくもく会で,個人練習をしたりもしました.ISUCON6 の予選・本戦のリポジトリと Slack ログが残っていたので,重宝しました.

当日の開始直後に何をやったらいいか迷って時間を無駄にするのを防ぐために,あらかじめ僕の Github 上に private repository を作っておき,そこに issue としてやることのリストアップをしておきました.(https://github.com/agatan/isucon7-qualify/issues/1)

また,3 人でうまく分業するためにローカルでそれぞれがアプリケーションを動かして動作確認をしようということになったので,使う可能性のあるミドルウェア群を docker で動かすワンライナー集を issue にまとめたりしました.

監視ツールもある程度さわっておいて,インストールや集計に手間取らないようにしました.リソースの状況を見るために htop / iftop / dstat / netdata を使いました.また nginx のログの集計には https://github.com/tkuchiki/alp が便利でした.

Wantedly オフィスの一室を借りて,予選に望みました.

開始直後

まずは 0gajun がサーバ側をいじるための準備をしている間に,残りの2人でレギュレーションを熟読し,アプリケーションがどんなものかを触りながら調べました.

一旦ベンチマーカを走らせて,alp で集計したところ,ひたすら /icons の配信にもっていかれていることがわかったので,画像をキャッシュしないといけないことがわかりました.画像は DB に保存し DB から持ってきて配信するようになっていたので,まず POST /profiles での画像更新を DB ではなくファイルに吐くようにし,@0gajun に頼んで nginx から try_files/icons を配信するようにしてもらいました.ファイルが無くてアプリケーションまでリクエストが来たら,その場でファイルに吐き出しつつレスポンスを返し,次回からはファイルが使われるようにしました.(https://github.com/agatan/isucon7-qualify/pull/12)

適当に index をはってちょこっとスコアを上げて喜んでいたところ,@0gajun が /icons で 304 が返るように適切なヘッダをつけてくれて,16558 → 55330 までスコアが一気に上がりました.ここからしばらくの間は僕らのチームが一位で「行けるのでは」感がチームから溢れ出ていました.( 15:00 時ごろ )

中盤

ここまでで大体 2 時間弱が経過していました.インフラサイドが /icons を始め,静的ファイル配信を改善している間に @izumin5210 が,既読数をカウントするための haveread テーブルをまるごと redis に乗せる PR を作ってくれていました.サーバ側が /icons をやったり定番の nginx / mysql 設定を置いたりしていて手が回らず,redis の準備ができていなかったのでしばらくマージできない状態でしたが,ここで redis を導入し 71814 までスコアが上がりました.

落穂ひろいで,画像をファイルに吐き出す際に ioutil.ReadAll して ioutil.WriteFile していたのを io.Copy を使うようにし,ファイル名をきめるために全バイトの sha1 を計算するのをやめる PR がマージされて,worker connection を増やす調整を @0gajun が行ったあたりで 96630 になりました.

このあと一旦1位を譲ることになり,チーム全体が意地っ張りになりましたが,基本的な N+1 を潰す改善が残っていて,それを直したところ 171801 点と大きくスコアを伸ばせて再び「行ける」感を取り戻しました.

さらに,このタイミングで @izumin5210 が,redis からとってくるだけでいいのに書き換え忘れで DB から持ってきている部分に気が付き,それを直したところ 244432 とさらにスコアを爆上げできたので完全に調子に乗りました.(これが 17:41 の出来事でした)


終盤

ここから何をやってもスコアがあがらない地獄に入りました.同じコード・同じ構成でベンチをもう一度走らせたところ 150000 点台までスコアが落ち,PR をマージしてもよくなったのか悪くなったのか分からない状態が続きました.

@izumin5210 が全面的に redis を使うようにするという大々的な改修を仕込んでいる間に,僕と @0gajun で複数台構成にする準備をはじめました.

画像を静的ファイルとして配信するため,POST /profileGET /icons/... は一台のサーバで受ける必要がありました.そこで,1 台は MySQL + Redis,1 台は Go App,最後の 1 台に nginx と Go App を配置し,画像に関するリクエストだけは nginx と同居しているアプリケーションに投げ,それ以外をもう一台のアプリケーションサーバにプロキシするようにしました.最終的に nginx + Go App のサーバは CPU が余ったので,weight をつけて画像関連以外のリクエストも分散させるようにしました.

ついでにセッションがオンメモリだったので Redis を使うように変更しました.

これで晴れて台数を増やすことが出来たのですが,スコアをあげることができませんでした.結局この時点でのスコアは 248316 点と,1 台のころとほぼ変わらないスコアでした.

@izumin5210 の Redis 大作戦の実装は,ぎりぎり 21:06 に完了したようですが,再起動試験でそわそわしている中,精神的・時間的な余裕もなく,博打を打つ必要があるスコアでもなかったため,マージしない判断をしました.ベンチマーカも待ち時間なしで回せる状況だったので,さくっとマージして試しダメだったら戻すくらいの時間はぎりぎりあったような気もしますが,さすがに fail の恐怖に勝てませんでした.

というわけで最終スコア 256,120 点で終了,これが僕らのベストスコアでもありました.


振り返り

結果発表までとにかく再起動試験 fail が怖すぎて震えていました.スコアだけ見れば学生枠ではまちがいなく通過出来るだろうし,もしかすると社会人枠に食い込めるのでは,さらにさらに上位争いにも食い込めていたので上位枠もありうるのでは!という思いもあり,とにかく fail していないことを祈りまくっていました.

@0gajun のお陰で無事 fail することなく,1 日目 3 位枠を勝ち取ることが出来ました!本当に嬉しかったです.

目標は予選突破でしたが,野望として「社会人枠に匹敵するスコアを取りたい」という目標も密かに持っていて,それを達成できたのがなにより嬉しかったです.ISUCON6 で社会人枠は別世界のように感じていたので,そこに食い込めたというのは今でも信じられないくらいです.

反省として,台数を増やしてもスコアを伸ばせなかったこと,今でもどうするのがベストだったか正直よくわかっていないというのがあります.結局僕らのスコアは 17:41 から 21:13 まで,下がることはあっても上がることはほとんどないという結果になっていて,終盤の息切れ感は悔しいなぁという感じでした.結局なにがボトルネックなのか今でもわかっていないので,色んな方のブログを見ながら感想戦をしようと思います.

チームに恵まれたというのが僕にとっての一番の勝因だと思っています.ばっちりインフラ・モニタリングをまかせられる @0gajun と,アプリケーションをガンガン書き換える馬力のある @izumin5210 がいたので,僕はパイプ役と落穂ひろいしかやることがなかったくらいです.ISUCON 的にも人間的にもバランスのとれた,楽しくて強い最高のチームでした!本戦も楽しみつつ,優勝めざして頑張りましょう!

最後に,ISUCON 運営の皆様,本当にありがとうございました!予選から複数台構成は驚きましたが,その分勉強になることも多く楽しかったです!

Anonymous
Picture?1523116231
48c7cd7d ecdc 4094 a6c0 aa674f0750fa?1520473766
4f0f8e38 6610 425f 903b c081e9e8e2bf?1528614662
Bf4fbd40 7e10 445c 8b5a d6b3739799b2
7dc24b43 66a9 45af a3d2 98440a39b9e6?1522371626
13 Like
Anonymous
Picture?1523116231
48c7cd7d ecdc 4094 a6c0 aa674f0750fa?1520473766
4f0f8e38 6610 425f 903b c081e9e8e2bf?1528614662
Bf4fbd40 7e10 445c 8b5a d6b3739799b2
7dc24b43 66a9 45af a3d2 98440a39b9e6?1522371626
13 Like

Weekly ranking

Show other rankings

Page top icon