ISUCON10 の練習・予選・本選でやってきたことをふりかえる
実は先月開催された ISUCON10 で「Team MN」のメンバーとして参加しました.
そして本選に出場することができました!!!(正直今でも驚いている...)
今回のISUCONでは主にアプリ・DB 周りの分析を担当したため,今回はISUCON10 の練習・予選・本選で私が分析まわりでどんなことをやってきたのかをまとめようと思います.
アプリ・DBの分析まわりで少しでも参考になれば幸いです...というか,他のチームがどう分析しているのか気になる...
本記事で書かないこと
- 本選での技術的な作業内容
- 内容がさらに長くなるため別記事にてまとめようと思います🙇♂️
前回のISUCON9では...
実は去年も参加していました(初参加でした).結論から言うとあっさり予選落ちしました... 今思うと当時の私は何をすれば良いのかわからずひたすらアワアワしていただけでした...
ISUCON10 での私の役割
前回の反省を踏まえて,「今年はせめて何かしら手を動かせるようになるぞ」と思いで参加しました. チームで練習を何回かやった結果,主にアプリ・DB 周りの分析周りを担当しました. 各担当については下記を参照.
そのため今回の ISUCON では「分析した結果を共有し,チームメンバーがアプリケーションの仕様について調べる時間を可能な限り減らし,生産性を上げる」というのが自分の役割だと判断し,取り組むことにしました.
やったこと
hirosuzuki はアプリケーション,beppu4 はインフラ周りを取り組んでいる中,私は Google スプレッドシートを使って下記のことに取り組みました.
やることの洗い出しとロギング
まずは競技開始時(Opening)や終了前(Closing)にやることが決まっていることは事前に洗い出しておきました. 本番では特に緊張するため,やり忘れが起きる可能性が非常に高いため結構役に立ちました.
競技中(Playing)にやったこともスコアとともに適宜ロギングし,ふりかえりができるようにしました.
ER図の作成
DB のテーブルの全体像を把握するためにER図を作成します.ER図は MySQL Workbench で作成しました.
課題のアプリーケーションが起動したタイミングで手元の PC から ISUCON の競技用マシンに SSHポートフォワーディング で接続し,MySQL Workbench でER図を作成します.DB に接続さえできれば下記のように簡単にきれいなER図を作成することができます.(下記は予選のアプリケーションである ISUUMO のER図です.)
アプリケーションが複雑だった場合やテーブル数が想定よりも多い場合はER図を印刷し,わかったことをメモしていきます. (下記は本選のアプリケーションである XSUCON のER図です.)
テーブルの調査
各テーブルのレコード数やカラム,インデックス情報をシートにメモしました.
SHOW INDEX
などの構文をテーブルごとに実行するのも良いですが,クライアントツールを使うと該当箇所を箇所をクリックするだけでわかりやすく表示され,メモしていくのが早かったです.
私は DBeaver を使って下記のようにスプレッドシートにメモしていきました. (MySQL Workbench はあくまでER図の作成でしか使ったことがなかっため,普段使っている DBeaver で調べました.)
CRUD分析
ヘッダ列にアプリケーションのファンクション名を,ヘッダ行にテーブル名を記入し,どのファンクションでどのテーブルにどんな SQL が実行されているのかを調べました.
作業の流れとしてはテーブル名でアプリケーションのプロジェクトを grep 検索し,該当の箇所のファンクションに書いてある SQL をスプレッドシートにメモしました.
コード量の多いアプリケーションの場合,調べ切るに時間が掛かりますが,これによりどのファンクションの処理がオンメモリキャッシュできそうなのかがわかります.
例えば各ファンクションから様々なテーブルに対してSQL文が実行されていますが調べていくと各ファンクションからUPDATE文やDELETE文では無く,SELECT文またはINSERT文しか実行されていないテーブルが実は見つかったりします.
その場合はファンクションでオンメモリキャッシュ化の処理を実装することでスコアが上がる可能性があるため,見つけたら下記のように別シートでメモしていきました.
※オンメモリキャッシュ化の処理の実装後,ベンチマークが fail や不安定になる場合は元に戻します.
遅い SQL の調査
hirosuzuki が事前に用意した「isucon-viewlog」にあるSQLログ解析には総実行時間が大きい順で SQL が表示されるため,その SQL を EXPALIN で実行計画の情報を取得し,INDEX が貼れそうな SQL をスプレッドシートにメモしていきました.
isucon-viewlog はベンチを回した後のログを利用し,各ログを一覧で見ることができます.
このツール,結構便利なのですがリポジトリを見ると README が無さそうなので記憶があるうちにプルリクを投げようと思います(汗).
ペアプロ・N+1 の調査
上記までの作業を ISUCON の練習・予選・本番で私が担当してきたことでした. 最初のうちは一つ一つの作業に時間が掛かってしまいましたが,回数を重ねるごとに取り組む課題アプリケーションは違いますが作業が段々慣れていきました.
慣れていくと飽きてくるように思いますが,「余裕が生まれた」とも言い換えることができます. そのため競技の後半の時間は hirosuzuki が改修したコードを git clone し,N+1になっている処理の調査やペアプロをしコードを多少読むことができて良かったです.
取り組んだ結果
役割分担をする前は情報共有が上手く行かなかったり,各メンバーが適宜 DB に接続して「SHOW TABLES」などを実行するなど無駄が作業が多い状態でしたが, 各メンバーからの「各テーブルのリレーションを知りたい!」,「Aテーブルのレコード数は?」,「Bテーブルはキャッシュできそう?」のような質問に対して即答・または私が作成したシートを見るようになり,無駄な作業を減らせたことで各々の担当領域に集中してもらうことができました. また予選では早いうちに「アプリ-DB-DB」サーバの構成にする意思決定をすることができたきっかけにもなりました.
ISUCON を通して学んだこと
チューニングできそうな箇所がわかってきた
今までは APM を何となく眺めたり,「N + 1 は bullet っていう gem を入れればわかるんでしょ?」程度のものでしたが,アプリケーションサーバの負荷が大きく,DBサーバの負荷が大きい場合は SQL にボトルネックがある,N + 1はループ文の中にある SQL を発行している処理を見つけ出すなど,実際に手を動かせるようになってきました.
仕様を把握するためのヒントを得ることができた
大事な箇所は印をつけるのは勿論,その仕様の裏を推測する・言い方を変える・仮設(または問い)を立てることで,ただ書いてあるドキュメントを何となく読むのに比べて素早く集中して仕様を理解できることが今回でよくわかりました.
チームメンバーの技を盗むことができた
エディタやツールの使い方,ログや仕様の着眼点や読み方,物事の考え方など自分には無い視点だらけで沢山吸収し,することができました(特に beppu4 のドキュメントの読み方や着眼点はとても参考になった).普段の業務では一緒に仕事をしていないメンバーなこともあり ISUCON が無かったら吸収できなかったかもと考えると,とても良い時間を過ごすことができたと実感しました.
まとめと所感
今回は ISUCON10 で私がやったことについてまとめてみました. 去年は自分が何もできなかった分,チームに貢献できたのが嬉しかったです.ましてや予選を突破して本選に出場できたのは去年の今頃の自分では考えられないほどの快挙でした.
チューニングできそうな箇所を見つける力がまだまだな点やスプレッドシート頼りな作業ではありますが今回の経験を業務でも活かし,更に磨いていこうと思います. 加えて自分は何かしらの方法でチームの生産性に貢献するのが結構好きなんだなぁとも改めて思いました.
本選の結果は12位という何も賞がもらえない結果となりましたが,ISUCON を通して様々なことを学ぶことができたのと自分ができることの幅を広げることができました. ここまでの結果を残せたのはチームメンバーの hirosuziki,beppu4 のおかげです!ありがとうございました!
そして ISUCON の運営・スポンサーの皆さん,完全オンラインという新しい形式で面白い課題と環境を提供頂きありがとうございました!
来年以降の参加は未定ですが,もしやるならアプリメインで挑戦してみたいです,