ISUCON6に参加して得られた経験と見えた壁

こんにちは。2016新卒ホットペッパービューティー開発チームの伊芸です。
先日行われたISUCON6予選に参加してきました。全員初めての参加でして、2年目のエンジニア2人と新卒のぼくの合計3人での出場でした。基本的に社内だけの世界しか知らない僕らに一体どれくらいの実力があるのか確かめるために出場してみましたが結果としては予選敗退でした。ただ、出場してみないと見えてこない気づきや学びが多かったので、ここに書き記していきたいと思います。

ISUCONとは

Iikanjini Speed Up Contestの略。とにかくチューニングしまくって、処理の速いサービスをデプロイしていくような、エンジニアの天下一武道会的なコンテストです。ちなみに今年の参加チームは317組。人数にしておおよそ900人の参加がありました。その中には有名な技術書書いてる方がいたり、みんな使っているであろうOSSにコミットしている方がいたりと、本当に戦々恐々な心境でした。

ISUCON参加実況

前日

事前勉強会を開催。まだ業務でgolangは使えないが、パフォーマンス良いらしいし、使ってみたいという技術的好奇心による判断でgolangを選択。最高に良い感じにスピード出していくぞ!と意気込み、対策を始めました。なお、3人中2人はgolangビギナー。golangをやりはじめて正味3日、といったレベル。だけど大丈夫です。大事なのは努力・友情・勝利です。
事前勉強会ではAzureの使い方をさくっと確認したり、Dockerを導入してすぐに環境をつくれるようにしたり、CircleCIを使ってデプロイフロー整えられるようにしたりと、日頃業務でやるにやれないことを試したいということもあり、わりと運用面に意識を向けた勉強会をしました。なお、Azure以外は本番当日全く使えなかったのは内緒です。

当日

10:00 〜 11:00

サーバーにログイン・環境確認。 Azure初心者すぎてISUCON運営者側からの設定依頼を読むも、どこで設定したらよいのかわからないためログインできず、最初から雲行きが怪しかったです。日頃AWSしか触らないことに対する罪と罰だと反省しました。ちなみに時代はGCPらしいです。
とにかくレギュレーションをじっくり読んでやっとこさログインができました。

11:00 〜 13:00

無事サーバーに入り、ディレクトリを確認。とにかく開発体制を整えにかかりました。ざっくりとファイルやコードを眺めていました。
とりあえず初期設定で読み込まれていたPerlのプログラムをベンチマークツールに流し込み、どんな感じのエラーやスコアが出るのか確認。パスが通ってないよ、POSTできてないよ、などのエラーメッセージと共に、スコア1400点獲得。
とはいえ、golangでやろうと決めていたので、golangで動いているプログラムへ切り替えをしました。
golangに切り替え後、改めてベンチマークを取るとなんとスコア0点。全員驚愕。道は遠く、そして険しいと認識できた瞬間でした。実際にリクエストを投げると、なにかしらの処理が遅いようで、画面表示までに10秒ほどかかっているのが判明し、「これはあかん。どっか絶対ボトルネックになっている処理があるぞ」ということで調査開始。
そこからメンバーの一人がnginxで静的ファイルをブラウザ側にキャッシュする処理を追加したり、全員でタイムスタンプ張って処理に時間がかかっていそうな部分を探していく作業へ移りました。ちなみに、全員初参加ということもあり、問題に気づいた人がとりあえず取り掛かる、ぐらいの緩い感じの役割分担と進め方でした。

13:00 〜 15:00

腹が減っただとか、各々が弊社でやっていきたいことなどをざっくばらんに話しながら相変わらずコードリーディング。golang力が低いぼくは別ディレクトリに存在するRubyでされている実装を参考にしながらgolangプログラムを解釈していた。ここらあたりで、どうやらhtmlify(キーワードに自動リンクを貼る処理)が遅いということがわかり、その周辺の処理を集中的に分析。最初はMySQL側の問題だと思いDBのログみたりselect文発行してみたりしていましたがどうやら見当違い。ボトルネックはgolang側でやっている処理でした。解決策として、Redisにとりあえずぶっこんでキャッシュしたものを読み込ませる、といった処理を実装。シェルスクリプト・PythonでMySQLに入っているキーワードデータを抜いてRedisに入れるというスクリプトを書いて、改めて試してみた。このあたりでスコア230点ほど。先は長い。

15:00 〜 18:00

時間的に「あーやばいぞこれは」という心境になりつつもチューニングに励んでいました。なんやかんやしてたらスコア32000点を叩き出し、、みんな一気にテンション上がりました。ところがベンチマーク測るたびにキーワードが増えていたので、POSTされるタイミングで一旦キャッシュにも追加するという処理をつくりました。そこでなんと50000点に突入。上位層に食い込んでいきラストスパートに拍車がかかってきました…が、ここで伊芸、体調不良で沈没。他2人が頑張ってくれていました。そこからもチューニングに勤しむも、あえなく時間となってしまいました。

振り返りと学び

もし次ISUCONに参加するなら今後気をつけていきたいなと思った点が以下になります。

  • 前日は十分な睡眠をとること
  • メンバーのスキルセットや得意なレイヤーを共有しておくこと
  • 当日作業中は役割分担をしておくこと
  • 複数回出て、上位にランクインしていこうという気概が必要だと認識すること

さらに業務レベルでも活かせるし、ISUCONに出て強く意識できるようになったと思えた点が以下になります。

  • 言語周辺のライブラリの理解(golangでよく使われているライブラリやFW)
  • ベンチマーク・ログ出力(ネットワーク・データベース・アプリケーション)
  • ヘルスチェック(OS上で何が行われているのかを把握する)
  • 代替案のストック(Redis使う、とか分散処理させるなど)
  • よく使っている言語・早く読める言語を増やす

とても基本的ですがOS・ネットワーク・データベースの理解が求められること、インフラ・ミドルウェア・アプリケーション・フロントエンドをまたいだ実装経験が求められること、かつ大規模サービスでよく遭遇するケースに取り組めることがISUCONの特徴といえるので、本当に学びの多い機会でした。とにかく、ISUCONはすごく特殊なコンテストでもあるので、どんなにへっぽこであっても、出場できるのであれば出場して場数を踏みながら足りない知識や経験を補っていくことが大事だと思われます!

以上、参加レポートと学びの共有でした。