ISUCON 10 予選参加も1139点で見事敗退 また来年

こんにちは、ジモティーエンジニアの吉田です。

普段はジモティーのバックエンド (Rails) とインフラを担当しています。2020/9/12 (土) に行われた ISUCON 10 の予選に参加したので、その内容をご紹介します。

ISUCON とは

ISUCON とは、お題となるWebサービスを決められたレギュレーションの中でチューニングして、そのスコアを競い合う大会です。

いい感じにスピードアップコンテスト、略して ISUCON (Iikanjini Speed Up Contest) のゆるい名前とは裏腹に、今年で10回目、参加チーム数は490組(1チーム最大3名)と国内でも比較的規模の大きいイベントです。ウェブ・インフラエンジニアであれば参加した事がなくても、一度は耳にした事のある方が多いと思います。

予選を勝ち抜いた上位30チームが本戦に出場し、優勝賞金はなんと100万円です。賞金額も大きいですが、業界でも有名なエンジニアがたくさん参加していて、その中で本選に出場できる事はスキルの高いエンジニアとしての証明にもなります。

チームメンバーとモチベーション

チームのメンバーは、まず、暑い季節もスカッと爽やかなギャグを飛ばす H さん、以前インフラとバックエンド、今は iOS を担当しています。次に、ビジネスチームとのブリッジングや仕様策定にとても強く、以前は主にバックエンド、最近は Android も担当している S さん、それに自分の3名です。

ジモティーではこのように複数の担当領域を兼務しているメンバーが多いのが特徴の1つです。

他の2人は初参加ですが、自分は過去に ISUCON 8 に参加した事があります。その時は再起動試験で失敗したのか、スコア0の残念な結果に終わってしまいました。

毎年この時期にタイムライン上で ISUCON が話題になると過去の記憶が蘇り、「あの時こうしておけば」「今の自分だったらどこまでいけるのか」といった思いに馳せる大会経験者は多いのではないでしょうか。ISUCON 9 はタイミングが悪く不参加に終わりましたが、技術研鑽よりもこういった思いが強く、参加を決めてすぐにメンバーを募集しました。

当日の朝から終了まで

前回参加時の失敗を踏まえて、事前に打ち合わせをして、担当や実施内容のおおまかな確認を行いました。プログラミング言語は複数から選択することができ、ジモティーでもバックエンドのメインで使用している Ruby を選択しました。

12:20に開始し、まずは準備していたプライベートリポジトリにアプリのソースコードや設定ファイルを登録して、初回のベンチマーカが無事成功する事を確認しました(スコア: 410)。

その後、インフラ周りのタスクとして alp のインストールや Nginx のログフォーマットを変更したり、Mackerel エージェントをインストールなど実施しました。alp で確認したところ、検索のエンドポイントが圧倒的に遅いのでここをなんとかしたいよね、と当たりをつけます。

ベンチマーカの挙動を確認した後、インデックスの追加でクエリの実行速度を改善できないか検討しますが、すぐに手を付けるのが難しそうだなと話しました。自分は Nginx の設定を変更してみたのですが、ベンチマーカとポータルが不安定で、変更の影響が不明なため、アプリ側をじっくり確認する方針に切り替えました。

16:00頃get '/api/estate/low_priced'get '/api/chair/low_priced' の結果を常に DB から検索していましたが、キャッシュ化できそうだったので Memcached をインストールし dalli 経由でキャッシュしました(スコア: 543)。また、get '/api/recommended_estate/:id'SQL クエリを改善し、以後参照のない変数で mapmap! に置き換えました(スコア: 558)。

その後、DB をインメモリ化しようとしてしばらく色々とやってみたのですが、ベンチマーカがことごとく失敗し作戦は断念しました。細かい改善をしながら、スコアが徐々にしか上がらず苦しい時間が続きます。

17:17頃、突如メインのサーバに SSH で接続できなくなり、Mackerel からも接続不能のアラートが飛んできたため、運営にマシンの再起動をお願いして事なきを得ました。この間ベンチマーカを実行できない事から、2台目と3台目にも同じ環境を構築し、打ち手を並列して試せるようにしました。事前の作戦でローカルには実行環境を構築しない方針にしていたので、これはもっと早い時間に実施しておくと良かったと思います。

18:21頃、ユニットファイルに指定されていた unicorn の実行環境を production に指定したところ、若干スコアがあがりました(スコア: 625)。

18:40頃MySQL のクエリキャッシュと InnoDB の設定を変更して、さらにスコアが伸びました(スコア: 928)。

18:50頃、どうしても DB の負荷が高いので、それまでアプリケーションと同じサーバで起動させていた DB を別サーバにする方針に舵を切ります。ところが設定ミスに気づかず、結局最後まで実現する事が出来ませんでした。estate と chair テーブルもそれぞれ別サーバに分けられそうだよね、と話していましたが、実現にはいたらず、これが一番の失敗だったと思います。

その後も細かい改善を実施しながら、19:00頃に、Nginx で一部の User-Agent のアクセスを一律 503 で返し、ベンチマーカを何度か実行するとスコアがかなり上がりました(スコア: 1066)。

終盤に chair と estate の検索をキャッシュ化しようと粘っていましたが、こちらはベンチマークが失敗し、残念ながら実現には至りませんでした。

ラスト20分はあわてないように予定通り変更をフリーズし、再起動後の動作確認を行って終了を迎えました。

振り返り

メンバーそれぞれができることを模索しながら、スコアアップに向けて手を動かす時間は何事にも代えがたい体験でした。また、仮説を立てて検証し、失敗を繰り返しながら正解した時にはそれまでの苦労がすべて吹き飛んでしまうほどの高揚感は、まさにエンジニアリングの醍醐味でもあります。

しかし、冷静にふりかえってみるといくつものミスや改善すべき点があったのも事実です。クエリの最適化にほとんど手を入れられなかった点、ボトルネックが DB の処理にある事に気づきながら別のサーバに切り出せなかったのは大きな失敗でした。

最後に

後日発表されたスコア(参考値)を確認すると予選突破ラインが 2100 付近だったようで、我々の 1139 ではまだまだ及ばない事が客観的に分かりました。来年こそは予選突破できるようにレベルアップをしたいです。また、ISUCON は普段の業務にもつながるとても素晴らしいイベントなので、社内でも複数チームで参加して感想戦をしたいです。

ジモティーではエンジニアを募集中です!一緒に ISUCON の話で盛り上がりましょう!