社内ISUCONに参加した話
與那城有
こんにちは、 2017年4月に入社した與那城です。
今回は7月27日に開催された社内ISUCONに参加したので感想と何をやったかを書きたいと思います。
同じく新人の宮地さんと上司の古川さんとチームisucon_friends
として参加していました。
問題はPixivさんが公開しているPrivate ISUCONを使っていました。
※ちなみに、企画者視点記事もありますので、ぜひご覧ください!
チューニングバトル!社内ISUCONを開催しました
ISUCONとは
Iikanjini Speed Up Contestの略です。チーム対抗でお題のWebサービスを決められたレギュレーションの中でどれだけ高速化できるかを競うチューニングバトルです。
これまでにも個人的に社外のISUCONには参加していて、ISUCON4・5・6と予選に出ていました。
ISUCON6ではチーム(´・ω・`)
として学生枠ですが本選に進むこともできました。
何をやったか
全体を通して特に意識したことは「速度改善のための意思決定は計測結果を元に行う」ということです。
いわゆる「推測するな、計測せよ」を守るということです。
分担
- 古川さん: 問題の特定、方針を出す
- 宮地さん: ミドルウェアの設定、 アプリケーションの改修
- 與那城: アプリケーションの改修
初動
- GitHubのPrivate Repositoryにコードをあげる
- nginxのlogの設定を変更しresponse timeを含めるようにする
- 初期ベンチマークを動かす
- kataribeによるendpointごとのプロファイリングを行う
- pprofによるプロファイリングが行えるようにコードを追加
まず最初に、レギュレーションの確認、計測できる環境作り、コード・構成の把握を主に行いました。
ISUCONにおいて得点の計算式などはヒントが隠れていることも多いので、時間を取って確認すべきだと思います。
序盤
- TOPページが遅いことを特定
- TOPページ表示までに実行されているクエリを調査し、インデックスを貼る
- blobで画像を保持している箇所があり、ファイルに書き出しnginxから返すようにする
序盤では簡単に実践でき、かつ高い効果が予想される施策を実施しました。
ある程度得点を上げておくことで心の余裕を作ることができます。
中盤
- pprofによりgetIndexが重いことを特定
- getIndexの処理の前後、結果の使われ方を見てクエリを修正
- getPostにも同様の問題があり、同じように修正
- requestスコープでsessionを一度しか取得しないように変更
- makePostsに存在した部分的なN+1クエリを修正
計測し、ボトルネックになっている部分を修正するというのをひたすら繰り返しました。
終盤
- ハッシュ化を外部プロセスで行っていたのを内部で行うように変更
- COUNT(*)をCOUNT(id)に変更
- 各種logを出力しないようにする
- pprofを使えないようにする
終盤は、大きな変更はもうできないだろうということで、簡単な修正でわずかでも効果が出そうな施策を実施しました。
そんなに効果はないだろうと思っていたハッシュ化を外部プロセスで行っていた部分ですが、かなりの効果がありました。
プロセスのforkコストや、言語のランタイムがどういった処理をしているかについて自分はまだあまり理解していないなと痛感しました。
結果
全体で2位、 75000点くらいでした。 1位になれず非常に悔しい。
良かった点として
- 大きな粒度のプロファイリングから行うことができた
- 計測->改善のサイクルを回すことができた
- gitを使って管理していたのであとからの振り返りに使えた(gitのログを見返しながら書いています)
反省点として
- 完全にN+1クエリを排除しきれなかったこと
- デプロイをずっと手動でやっていた
web上で公開されているwriteupで今回提供されたインスタンスより性能の低いインスタンスで500000点を超えているものもあり、まだまだ精進が足りないなと感じました。
普段の仕事から離れて、ISUCONに取り組めて最高に楽しかったです。
こういった場で得た知見を業務にも生かしていきたいと思います。