未経験3人でISUCON11に予選参加しました

チーム「SLA一億パーセント」として @Kumassy @Gaku-Kunimi とISUCON11に参加してきたので、準備としてやったことや本番に経験したことについて書いていく。

ISUCONは簡単にいうとWebアプリのチューニングコンテストであり、面白そうと思いながらも必要とされる知識が多く敷居が高いと思っている人も多いと思う。

自分も未経験だし他の人を誘って参加するのはハードルが高いなあと思って二の足を踏んでいる人たちに向けて、どうやって練習すれば競技の土俵に上がれるのか、スムーズにチームビルディングができるのか、というところの経験を共有して、少しでもISUCONの普及に貢献できたらと思う。

TL;DR

  • 初回練習の導入にチュートリアルを用意してモブプロするのは有効だった
  • 三台構成にしてデプロイまでを短時間でできるようにするために、インフラ担当が素振りをちゃんとするのが大事
    • 特にデプロイスクリプトのスムーズな作成と使用法の啓蒙が大事
  • 結果は予選敗退だったが「測定して改善する」サイクルをチームで回せたという点で手応えはあった

前提

  • 三人全員ほぼISUOCN未経験
    • Webアプリの仕組みはわかっているものの、N+1問題やインデックスについては単語しか知らない、レベル
  • 基本的なスタンス
    • スコアガチ勢ではなくエンジョイすることを重視
    • 全員社会人で他にやることもあるので、過去問8時間x3回の通し練の参加以外の練習は強制しない
  • 立てた目標: "エンジョイ" できる程度のレベル上げをする
    • ISUCONのセオリー「測定して改善する」を実践できるようになる
      • 具体的には、alp (Nginxログ集計), pt-query-digest (SQLログ集計), netdata (モニタリング) など有名どころのツールを使えるように
    • チームでやるべきことの分担をして効率的に競技時間を使えるようになる
  • 分担は自分がインフラで他の二人はアプリを担当、実装言語はPythonを使用

事前の通し練習

  • 環境構築はAWSのEC2テンプレートを使用
    • t3.microで4台立てても一ヶ月数千円しかかからない、土日だけONにするともっと安い、何より環境構築が簡単
  • 初回の練習は、インフラ担当の自分がチュートリアルを準備してきて、アプリ担当の二人のメンバーにベンチを走らせて測定・分析するところまでをモブプログラミング形式で体験してもらった
    • サービスの起動、ミドルウェアのインストール、コンフィグの設定、Git管理、デプロイスクリプト(後述)の作成、ベンチの起動、分析ツールの使用、といったISUCONの基本的な部分を、最短距離でつかんでもらうことを目指した
    • このチュートリアルは本番に使用するコマンドリストとしても有用だった
  • 二回目・三回目は、各人が開始後の2時間(理想)に行うべき典型的なプロセスと、その後の高速化サイクルに慣れてもらうことを目指した
    • 典型的なプロセスとは、インフラ担当でいうと、分散構成の構築、デプロイスクリプトの作成など、アプリ担当でいうと、ローカルの環境構築、エンドポイントごとの特徴をスプレッドシートに整理するなどの部分に相当
    • 高速化のサイクルとは、「ローカルでブランチ切ってコード修正→ローカルで基本的な挙動確認→ワンコマンドでデプロイ→ベンチ実行→ワンコマンドでログと測定結果の算出→問題なければmasterにマージ」のこと
    • (とはいえはじめからスムーズにできるわけがないので、はじめは典型的なプロセスの部分をこなすだけで疲れ果ててしまっていた)
  • 使用したAWSインスタンスは練習後も電源をONにしたままにしておいて、やりたい人は延長戦ができるようにしていた
    • 講評や参加ブログを読みながら再実装してスコア上げ

練習を通して思ったこと

  • デプロイスクリプトは超大事
    • deploy_from_local.sh
      • git pull、ログの退避、サービスの再起動をワンコマンドで行うやつ
    • run_after_bench.sh
      • ログをリモートから持ってきて集計・分析するやつ
    • ブランチを指定してデプロイできる機能はとても有用だった
  • ISUCONをエンジョイできるようになるためには、少なくともインフラ担当が素振りを繰り返すことは必要
    • 毎回やることは同じだけれど、やったことないと時間がかかる/詰まる作業が多い
    • 繰り返すことで秘伝のタレの作り込みと時間短縮ができる

本番の動き(インフラ担当目線)

  • 9:30
    • 三人とも起床していてえらい
  • 10:00
    • CloudFormation便利、インスタンスが数分で立ってすぐログインできるようになっているのは助かる
    • Regulationの読み合わせとGUIチェック
      • スコア算出が複雑だな
    • 初期状態でベンチを走らせたところ3000くらい
  • 10:30-12:00
    • サクサクと3台分散構成とデプロイスクリプト作成の典型作業を終わらせていく
    • 3台とも全てミドルウェアがインストール済みだったのでうれしかった
    • ついでにappのサービスがPythonを直叩きしていたのに気づいたのでgunicornを導入
  • 12:00-13:00
    • nginxでのhttpsの振り分けをするときに証明書どうするんだろうって詰まってた
      • alpを初期状態で流すのをサボったので分析ができず、アプリの人たちにすいません早く解決しますって言ってた
    • 証明書を自分で作らないといけないと思ってオレオレ証明書を作ってベンチ通らんwってやってたけど、よく探したらsites-enabled以下のconfigに場所が書かれていたという
    • やっとをベンチを通すことができて、9000点くらいに
    • netdataを見たところappのサーバのCPU使用率が100%ほど
  • 13:00-14:00
    • エンドポイントのparseするスクリプト正規表現をバグらせながら書いてalpを動かす
      • /api/isu api/condition あたりが重い
    • ようやくコードリーディングを開始
  • 14:00-16:00
    • 一番時間を食っていると思われる /api/isu のN+1を修正しようとするも苦戦
    • windows関数を使わないとできなくない?って思って調べながら試行錯誤
    • バグを取って実装し切るもスコア上がらず
  • 16:00-17:00
    • 他のメンバーのbulk insertや /api/trend のN+1改善を実装してもらうも、逆にスコアが下がる
    • その時に /asset/* へのアクセスが異常に増えたのが観測できたので、Nginxでの静的配信を実装
      • GUIのレスポンス向上は体感できるもののにスコアは伸びず
    • ついでにNginxがディスクにbufferしてるerrorが出たので client_body_buffer_size を調整したり
    • その他インデックス貼ってもらうも効果なし
  • 17:00-18:45 (途中中断1時間あり)
    • app二台構成にしようと思うものの、session振り分けが必要なことに気づいて色々調べるも結局実装できず
    • アプリメンバの /api/condition の実装が終了するもマージまでは至らず
    • 再起動試験対策に、再起動してサービスが動いていることを確認

最終的には無事再起動試験には通り、9670点(330位) でfinishでした

振り返りと感想

  • インフラ担当なのに二台構成に早めに手をつけなかったのは反省
  • 戦えるレベルのスコアが出たわけではないけれど、ISUCONの型は身についたと思う
    • 毎回練習を繰り返すごとに成長を感じられるのでよかった
    • とはいえ圧倒的にスピードが足りてないので反復練習が必要
  • 密にチームメンバで連携して開発ということをあまりしてこなかったので楽しかった
  • ISUCONももう10回目なので、alpですぐ判明するボトルネックの改善やN+1解決でスコアが簡単に上がるような問題は出ないよなあっていう
    • スコア計算式から求めていることを把握しなければいけなかったのかも?しっかり復習したい
  • ここまで出題に開発コストがかかるイベントが続いているのは奇跡に近いと思うので、ISUCONの運営・スポンサーのみなさんには感謝の気持ちしかない