ISUCON 13

ISUCON 13に参加した

少し前だが、11月25日に開催されたISUCON 13に参加した。これが初参加。

これまでISUCONとは縁がなかったのだが、今年は社がスポンサーでポジションをとっていたのと、ありがたいことに同僚から声をかけてもらって「じゃあせっかくなんで…」という感じ参加させてもらうことになった。

当時のSlackを振り返ってみると、最初はヒヨって期待値を下げるコメントを残している。

image1

この時声をかけられていた他の同僚はみな数回は参加したことがあるメンツで、ポケモンでいうと多分レベル60くらいな感じ。そこにレベル5でマサラタウンなやつがパーティに組まされたらこうなるのは当然である。

チームは自分とiguchi-san(@dorakueyon)とchiba-san(@metalunk) と参加し、結果は223位。

image2

目標は50位くらいだったので、残念ながらそこには及ばず。悔しい気持ちが残ったが、初参加の身としては参加しただけでエラい!という気持ちもあるので、総じて満足している。

ISUCONの概要をざっくりしか知らない状態から個人練習をそれなりに重ねた中で得られた結果としては、個人的にちょっと物足りないなという感じ。準備をそれなりに頑張った方だが、現実は厳しかった。

一緒に参加した (させてもらった) 二人は数回参加しており、当日も小慣れた感じで問題を解いていたので経験値が違うなと。自分は最初につまづいてテンパってしまい、そこからなんとか解法を見出して改善をいくつか加えていたが、あまり大きく伸長する成果は残せなかった。

途中でchiba-sanが「DNS水責めの問題をなんとかせねばな〜」と話し始めていたが、自分は全くピンときていなかった。そもそも「DNS水責めってどういう問題…?」という状態で、問題の肌感さえもつかめていなかったのである。gnn… (後に復習して理解した)

ほかにも「NGワードの扱いをなんとかせねば」「統計の集計クエリをどうにかせねば」という感じで、自分たちの問題解決の方向性と議論自体は間違ってなかったものの、いかんせん解決の動きが遅く、解決手段の見出しも完璧に仕上げられずで終わってしまった。

image3

布陣的には自分がアプリケーション改善を主担当だったこともあり、もっと上手く解法を当てていけたらなら〜と、反省が残る。

当日はLINEヤフーのオフィスで参加させてもらって、久々にどデカいオフィスビルに足を運んで懐かしさを感じた。

作問含め運営の方々は当日までの準備への感謝はもちろん、開催を支えながら並行してベンチマークのバグ修正なども取り組まれていたのには驚いた。

運営の方々にはとても感謝しています。ありがとうございます。お疲れ様でした。

image4

参加までにやったこと

やったこと

  • isucon9-qualifyをGCPで環境構築して解いてみる (1回)
  • isucon本を通読する (3回)
  • private-isuをAWS環境で解く (2回)
  • isucon9-qualifyをAWS環境で解く (2回)
  • isucon10-qualifyをAWS環境で解く (1回)
  • isucon11-qualifyをAWS環境で解く (3回)
  • isucon12-qualifyをAWS環境で解く (3回)
  • 初動の動きのすり合わせ (2回)

ざっくり書き出すと上記のようなことをやった。

他にも細かくはいろいろやっていたが、大まかにやっていたのは上記。

isuconのルールや概要、仕組みすらも知らない状態からスタートしていたので、そこから考えればだいぶ進捗はしたように思う。とはいえ結果には結び付かなかったが…

最初は「とりあえず触ってみないとわからないだろう」ということでisucon9-qualifyを自身が慣れたクラウドであるGCPに0から環境構築をしてみるところから始めた。

image5

(初めて問題を解いた時の図)

ざっくり理解して、どう問題を解けば良いのかを掴んだ後はisucon本を通読 (&精読) し要点を掴んで、それ以降は問題を解きながら研究を重ねる感じで準備していた。

環境構築まではスムーズにいって、問題を解き初めから躓いて全くスコアが伸びずに1日が終えることも数回あった。途中でネットに転がっている解法を当てていくことや、自分の中に問題解決のストックを貯めていくことで練習回数を重ねるごとにスムーズに点数を伸ばしていける状態までできるようにはしていた。

後でも触れるが、ISUCONの問題はAWSでAMIが配布されており、それを使うと数分で環境を作り切れるとわかったので、GCPで環境構築を一周だけして、それ以降はAWSを使っている。

解いた問題も、箇条書きに挙げなかった他にも本戦問題をいくつか解いていたが、真に学びのある解き方をしたなと言い切れるのは挙げている予選問題の方だった。というより、厚い解説が多いのが予選問題だったので、解法や仕組みを深く理解できたのは予選問題の方が多くなった。

他の参加者の方々も推しているように、練習問題にはisucon11-qualifyとisucon12-qualifyを解くのを特にオススメする。

理由は、問題解決の種類が豊富なのと、その比重 (軽い変更と重い変更の必要量)が絶妙で、2つを集中して解くだけで、問題解決に結構自身が持てるようになるから。個人的にはキャッシュやデータベースのマイグレートをやり切れるようになって、少し自信がついた。今後もし新たにisucon参加のための準備をしたいという方は、2つの問題を解くことをオススメしたい。

個人での練習のほかに、チームで2回初動の確認もしている。

リーダー兼インフラ担当の iguchi-san(師匠)が最高な環境と秘伝スクリプトを整備してくれたおかげで、当日の改善はもちろん、練習もスムーズにこなせる環境にしてもらったのはとても良かった。

image6

最終的にはコマンド1つでブランチデプロイ, ログローテート, ベンチ実行, 計測, 結果共有までのサイクルが確立できている。

途中まで泥臭いコマンド入力や手修正を重ねたやり方を取っていたが、確立した型で問題を解くようになって効率が上がった。

なるべく早い段階で問題に触れて理解を進めることが大事だが、合わせて初動の型を確立するのも大事なので、これも来年以降に新たに参加される方にはオススメしたい。

もし周りに経験者がいなければ、優勝チームのリポジトリにある秘伝のスクリプトなどをコピって自分なりに扱いやすい内容に書き換えて使うと良い。0から確立するよりも、"優勝"というわかりやすい結果を残すチームの型を真似るほうがプラクティスに乗っかれるので良い。

image6

(isucon11-qualifyで50万点まで研究する)

練習のやり方

今年はISUCONに参加するぞ!となった時の将来の自分に向けて、今回確立した自分なりの練習のやり方をメモ的に残す。

  1. AWSで環境を作る
  2. 初動を型通りに行い、改善サイクルを回せる状態を作る
  3. 回答解説を読まずに解く (2時間~4時間)
  4. 回答解説を読む
  5. 3で解き終えた環境で、解答例を見ながら解き直す
  6. 2の環境に戻り、解答例を見ながら解き直す

2で状態を作ったら、AMI化しておく。そうすることで6で模範解答例で解き直す際に、わざわざ環境構築しなくてもよくなる。

必ず回答解説を読まずに解いた方が良い。後の解答例を見ながら解き直すときに気づけることや吸収できる内容が大きくなるため。先につまづいていた方が後に学びに変えられる。

問題を解きながら疑問に思う点は全てメモしておく。メモは模範回答と照らし合わせて考えや仕組みを理解するためのヒントになる。

回答は最低2時間くらいは粘るべきだが、最悪1時間弱で終えても良い。長いと4時間くらいかけてそれなりのスコアまでは持っていけるようになる。

解き終えたら公式講評とその問題でハイスコアを取っていたチームの振り返りブログを探して読む。ここでわからないキーワードや概念はできるだけ解消する。先に書いたメモが役に立つはず。

解説も一定読み終えたら解き直す。この時直しはひたすら続ける。満足いくまで解き続ける。日を数日跨いでも良いので満足いくまで解き続ける。

“満足” というのはスコアがN満点まで出たらといった定量的なゴールもあれば、仕組みや概念を説明できるといった定性的なゴールでも良い。

研究しきったなと思えたら次の問題に移る。

このサイクルを1度ではなく、2週くらいの間隔を空けて取り組むと良い。

1回目よりも2回目の方が精度が良くなるし (当たり前だが) 、1回目で気づけなかった点や気付けた点が明確になるため、2回目の方が1回目の時よりも楽しくなる。周回は可能な限り回した方が良い。

image7

(初動で寝かしつけ)

課題感

参加して最後に2つの課題感が残った。

  • 問題解決の引き出しの少なさ
  • 問題解決の精度の低さ

もしまたISUCONに参加するなら、次はこの2つに真っ直ぐ向き合わないとスコアは出ない。

「問題解決の引き出し」というのは、Aという問題を見たときに解法を解決するイメージを含めて思いつくかという、解決手段の幅の広さのこと。

練習でストックした解決手段は以下。

  • インデックスの不足を補う
  • N+1の解消
  • 参照データのハードコーディング
  • ログ出力の最適化
  • ミドルウェアの設定変更 (Proxy Server, Database)
  • キャッシュの導入 (redis, memcachd, varnish)
  • 静的ファイルのミドルウェア配信
  • 画像のストレージ変換
  • データベースのサーバー分離
  • 特定APIのみのサーバー分離
  • バルクインサート
  • データの部分変換
  • パッケージの変更
  • コマンド処理のパッケージ化
  • アルゴリズムの変更
  • 非同期処理
  • データベースの変更

過去問を解いた中で時間をかければ解き切れるであろう解決手段は一定見出せたが、これを実際に初見問題に正確に適用できるか、つまりは問題を解き切るだけの精度があるかはまた別の話。

解法の幅を持ちつつ精度を上げなければ、着実にスコアを伸ばしていくことは難しい。

特に自分はここ3年はDartしか書いておらず、Goを選んで言語機能の扱いでつまづき過ぎてしまうので、Goを澱みなくかけるようになる方が実は精度を上げるには重要かもしれない。Goに習熟するだけで30点から70点まで伸ばせる的な。

希望だけを言うなら、Dartの問題が出て欲しい。Dartで出たい。

さいごに

まとまりのない、雑な内容になってしまいましたが、ISUCONに参加して良かったです。

とても学び多い機会でした。来年もまた参加したい。

誘ってくれたsotaさん、ありがとうございました。

一緒に参加したiguchiさん、chibaさん、ありがとうございました。

普段はお会計チームなので、率先して打ち上げの精算もやりました。

image8

SHARES