ISUCON5に出て学生枠1位のチームの金魚の糞をした

YAPCも感想エントリ書こう書こうって結局書かずじまいになってしまって、こういうのは拙くても即日に書いた方がいいと気づいたので書く。ちなみにYAPCの感想を一言で言うと、「これは積極的にアウトプットしている人間じゃないと100%は楽しめないからなにかしらアウトプットしないとなあ」みたいな感じだった。

ISUCON5というwebアプリケーション高速化コンテストにサークルの後輩と「チーム古典論理の犬」として出場した。このエントリを見るような人には大体わかっていると思うのでISUCON自体の説明については省略する。あとチーム名の由来だけど、同サークルからもう一つ参加チームがあって、そこが全員notaという会社で働いている人間で構成されていたので「not nota」 => 「not not a」 => 二重否定 => 「二重否定を使うような奴は古典論理の犬」という感じでチーム名が決まりました。これはインターネットのどこかで見たフレーズで、なんでこんなこと言われているのかはわかってないけどなんだかかっこいいのでこれでいいやって感じで決まりました。

おべんきょう

サークルの内部webページにISUCON出るぞというのをたきつけたのが僕ということもあって、勉強自体は9月に入ったあたりから個人でもそれなりに積極的にやっていた。と言っても今から思うとぬるいもので結果的にあんまり技術は身についていなかったのだけど。内容としては、とりあえずチームで過去問を解いて、解説エントリ読んだりして知らない技術があったらそれを勉強するみたいな感じ。また、本番時に同じページをググり直すのは非効率的だったからとりあえず有用そうな知見は簡単にまとめたり、リンク集を作ったりしていた。

gyazo.com

ほんばん

サークルの部室に三人集まって、設備は各人のサブディスプレイとホワイトボードくらい。大まかな進め方としては最初に軽く互いの担当を決めて、1hごとに進捗確認兼方針確認みたいなのを行うみたいなことをしていた。

ISUCON4のチーム練習をやった際に初期実装の速度がGo >>>>>> Rubyよりだったということがあって。練習では私が安牌のRuby実装改善兼インフラ担当あたりで残りの二人でGo実装を進めるみたいなことを考えたんだけど、ISUCON4とは違って今回はかなりアプリケーション自体の実装がヘビーだったのと、Goの初期実装にバグがあるということもあって脇目も振らずにRubyでチャレンジした。

まず僕が静的ファイルのnginx配信とか、workerprocessをあげたりとかバックエンドアプリとの通信をunix domainソケットにするとかいう基礎的なことを行っていた。このあたりはすでにお手本のnginx.confみたいなのを用意してあったのですんなりぺたっと貼るだけで済んだんだけど、cssとかをgzip圧縮して送るとなにやらベンチマーカーに怒られたのでそこだけ直した。

また、RhebokというUnicornより早いrack-server gemがあるとか調べてたのでそれをすげ替えたりしてた。しかしあんまり効果が上がらず、この時点ではまだ1.3kとかそんなんだった気がする。

アプリコードをバーっと眺めていて、今回はクソクエリ改善ゲーだということが薄々チームメイトで共有できたのでそこらあたりの改善に乗り出したのが14:00〜だったと思う。一部のクエリ結果をRedisにキャッシュするとか、有効な複合インデックスを探るとか、先にjoinするとかいうのをサブクエリに変換するとか言うことをやってた(diffはリポジトリがpublicになったら貼ります)。

一番重かったget "/"のところを改善するといきなりスコアが10kとかに乗り出して、TOP20に食い込めはじめてびっくりした。その後クエリキャッシュとかカーネルパラメータとか適当に設定を書き加えるだけで済むようなところをちまっと直して最終的に13kほどのスコアに落ち着いた。結果としては、学生枠としては上に書いたnotaチームの次点で学生枠二位ということだったんだけど、notaチームはそれ以前の(最初に3k到達チームと各日TOP4を除いた)二日間のTOP10に食い込んでいたので学生枠扱いから外れて、暫定的に学生枠一位になった。

反省

競技中

notaチームのuiureoさんの

SQL初心者の留年野郎がISUCON予選通過した方法 - UIU

のエントリにあるように、分析 -> 改善というフローを徹底すべきだった。かなりいきあたりばったりな改善になっていて、最後の方のクエリ改善でやっとスロークエリログとかを眺めるとか言う有り様だったのでひどい。

あと、チーム内の役割分担が後半結構グダっていて、作業領域がコンフリクト寸前まで来ていたり、コード、設定の変更はリポジトリ管理、本番機は基本git pullするのみというフローと決めていたのに直接本番機で作業してしまっていたりしたのも良くなかった。

どうやらviewのerbの中にもsqlが埋め込まれていたということがあったらしく、ソースコード全体に目を通すことは大事だなと思った(viewには全く目をくれてなかった)。

メンバーとの間でレギュレーションの理解に相違があって、それがけっこう遅くなってから発覚した。レギュレーションを読むことは重要だというのはわかっていてみんな最初にある程度時間をかけてそこに充ててはいたんだけど、同じ文章からでも汲み取る内容に齟齬がある場合があって、その暗黙の前提の上で作業を始めたりするので認識合わせは大事だな、と思った。

競技前

普通に勉強不足。とはいえそれは結果論ではあるんだけど、控えめに見てもここ一週間はほぼスプラトゥーンとギターの練習しかしてないという感じだった。猛省。

チーム練習は本番と同じ、直接集合してやるべきだった。やはり情報の伝達の感触の違いとか、あと緊張感とかが全然違う。リモートでは練習してたんだけど途中で晩御飯で脱退してたりとか、ダレてきたので8hのところを5hくらいで「学生枠超えてるしもういいか」とか言って適当に終わらせるとかやってて著しく緊張感に欠けていた。というかそもそも競技中には学生枠ラインとかは発表されないと思ってなかったので(今から思うとそれによって戦略が変わってくることもあるかもしれないしそれはそうだろ、と思うのだけど)割となめていたなあと。

一応自分も休学して半年くらいweb業界で働いていた身ではあるんだけど、その時の経験とかを活かせていたかというと全くそんなことはなかったし(まあActiveRecordにくるまれたRailsだったということもあるけど……)、チームの最年長者なのに優秀な後輩の金魚の糞をしているだけで結構情けなく感じたので本戦ではなんとか一人分の働きぐらいはしたいな……。がんばります。

最後に。idobataでの様子やドキュメントの内容などから今回運営の負担がかなり大きかったんだろうなということがうっすら見えました。ISUCONは一ヶ月程度完全に離れていたwebとかプログラミングの世界をもう一度学び直すきっかけになってくれて、そのおかげで夏休みは(最後の方はちょっと怪しいけど)とても充実した時間を過ごすことができました。このような素晴らしい機会を設けてくださった運営の方々に感謝します。ありがとうございました。