azihsoyn's blog

技術のこととか釣りの事とか(書けたらいいなぁ)

isucon8に参加して予選敗退してきました

勝利を知りたい。。。

辛いです。辛すぎるので「今日は一日ラブライブ三昧」を聴きながら書いてます。 聴き逃し配信来ないですかね、、、

今年で3回目の参加のisuconですが、参加者もどんどん増えているみたいです。今回も去年と同じメンバー(おばちゃん (mobata) , ゆづるくん (yudsuzuk), azihsoyn)でチーム rehash.fm として参加したのですが、予選突破ならず。スマイルさんほんとすみません。

正確な順位はまだ出てませんが 100位のちょっと上ぐらいだったみたいです 62位でした。

isucon.net

一応前回よりは成長できたみたいなのでそこはせめてもの救いです。。

以下やったこと。敗退したので参考にはなりません。

事前準備

isucon7の予選問題を復習

一週間前におばちゃんがconohaで練習用インスタンスを立ててくれました。 この問題はまずcache-controlをどうするかが鍵だったのでnginxの設定ファイルをいろいろいじってました。他の人のブログを参考にしながらpublicにすればいいというのはわかってましたがなんとかベンチマークIf-Modified-Since を送ってこさせようとしたのですがうまく行きませんでした。publicにするのは簡単だったので本戦でもpublicつけとこって思いました。 練習は前日までやってましたが圧倒的準備不足でした。ただ直前まで練習していたのでisuconの感覚をもったまま当日に望めたのはよかったです。

リポジトリ, slack部屋を用意

最初githubisucon8-qualify-appisucon8-qualify-conf の2つのリポジトリを用意してましたが練習問題やりながらconfも同じリポジトリで管理したほうがやりやすいなと気づいて isucon8-qualify に統合されました。この判断は良かったと思います。 こんな構成でMakefileで全部最新の状態にできるようにしてました。

webapp/
nginx/
systemd/
db/
Makefile

当日やったこと

初期状態でベンチマーク

今回はpythonでやると決めていたのでアプリケーションをpythonにしてベンチマークを実行しました。確かデフォルトだと600とかだった気がします。

レギュレーション確認

やるのは当然なのですが、今回はスコア配分も載っていたので配点の低いところにリソースを割かないように気をつけてました。次どこやろうで悩んだときにこの基準に振り返れたのは良かったと思います。

サービス把握

e○lusのようなイベントの予約サービスでした。一通り触るのは今思っても大事だと思います。今回はadminの機能もあって売上レポート出力機能があったのですが、配点が低かったのでここはスルーすることにしました。

ここまでで30分ぐらいでしょうか。

そろそろBGMが必要だと思ったので BanG Dream! より Roselia をひたすら流してました。9/17がファンミだったので予習しないとだったんですよね。

ボトルネック特定

もはや定石となったalpやgo_accessなどを使ったnginxのログ解析。 さて設定ファイルいじるか、と思ったら

ない。。。?

とここでおばちゃんが、 h2o じゃない?と気づいて

そ、そうきたかー!!!ってなってました。 一番最初の判断ポイントで、h2oのまま行くかnginxに載せ替えるかの2択でしたが、h2oは全員ほぼ触れたことがなくドハマリする可能性があったのでまずはnginxに載せ替えることに。 nginxの設定ファイルの一部をいじることはありますが0から入れるのはほとんどやらないので意外と手こずって終わる頃には12時過ぎになってました。 ただ前日までにおばちゃんが用意してくれたisucon7の設定ファイルがあったのでそこまではまらなくて済みました。

その後alpを使って測定したところ、 GET / GET /api/event GET /admin/sales GET /api/users あたりがボトルネックになってました。 とりあえずの方針としして自分が GET /, ゆずるくんが GET /api/event , おばちゃんがDBサーバとWEBサーバの分離などを担当することになりました。

アプリケーション改修

辛い、、、コードが辛い、、、。トップページを表示するのに events テーブルをselectしてから その event.id でもう一度 eventsをselectしてそのevent.id でreservationsとsheetsを舐めるみたいなことをしていていわゆる N+1問題なのですがそのレスポンスのjsonが呼び出し元でkeyを削除していたり DBのカラム名をそのまま使っていたり違うkey名に変えたりと難読化されていて修正がだいぶ困難でした。しかもそのコードがいたるところで使われていて呼び出し元の引数によって返す内容も変わったりするので、あぁ、今回のisuconのテーマはリファクタリングとか歴史的経緯とか闇かな?って思ってました。 影響範囲が大きいのが嫌だったのでトップページ用の関数を新たに作りました。

また、この修正なら動くだろと思って実行した結果エラーが出たりとpython力の無さがだいぶ出てました。なぜpythonにしてしまったんだ、、、。 レスポンスのjsonの構造を変えないようにフィールドとテーブル定義などとにらめっこすること3時間ぐらいでやっとスコアが上がる修正ができました。 この時点でスコア1545。 その後ゆずるくんのランクの固定値かや不要なフィールド返さない修正で2319。

多分この時点で16時ぐらい。

その間おばちゃんの2台構成も試してみたところスコアが下がったのでロールバック

次の方針を決めるためにベンチマーク実行したところ トップページやevent apiはそこまでボトルネックではなくなっていたので users系の改修に入りました。これはそこまでスコアにはならないのですが明らかに遅くて他にも影響ありそうだったので悩みましたが手を付けました。

usersも動くかわからないまま本番で確認しながら修正したので時間がかかって17時ぐらいになってました。この時点でスコアが2849。

もうほぼできることがなくて諦めムードが漂ってたんですが、トップページ用に作ったイベント取得処理を他の箇所にも適用したら早くなるんじゃね? と思ってえいやでやってみたらスコアが一気に7010に。

この時点で17時半。

同じことを全部のイベント処理にも適用しちゃっていいんじゃね??と最後のワンチャン実装を試したところadmin系ではエラーになったのでadminを除くevent処理の書き換えを試したところ更にスコアが伸びて16156に!!

全員テンションぶち上がってました。

流石にこれ以上はやる時間がなかったので記念写真撮って残り10分はひたすら祈ってました。

f:id:azihsoyn:20180917235942j:plain

結果はまぁ予選敗退だったんですけどね。 それでも最後のライブ感は参加しないと味わえないなと思います。 死ぬほど悔しいですけど!!!

結果出た後しばらくこんな気持でした。

f:id:azihsoyn:20180917235619j:plain

来年同じ思いをしないために振り返っておきます。

振り返り

Keep

  • レギュレーション読み合わせ めっちゃ大事だと思いました。認識があってるのが大事。
  • アプリケーション一通り触る これも時間取りすぎたかと思いましたがやってよかったです。
  • リポジトリの構成 1コマンドでミドルウェア含めて最新の状態にできるのが本当に大事だなと思いました。去年はgit管理していながらmasterで動かないみたいなことがあって今年はめっちゃやりやすかったです。出題のinitializeが良かったというのもありますが。
  • tagでスコア記録 isucon7で次回はやろうと言っていたのができました。

めっちゃ便利。振り返りにも便利。

Probelm

  • 慣れてない言語で挑む 勝ちに行くのであればやはり自身のある言語で行くのが一番だなと思いました。違う言語で挑むのも勉強になるので一概には言えませんが。
  • 役割分担 去年も書いた気がしますが気づいたら同じところをやってたみたいなのはもったいないのでなにか考えないとですね。。
  • 部分最適になってしまった alpでエンドポイント別の対応をしたんですが、アプリケーションコードの全体像を見る前に修正を始めてしまったので改修の割にスコアが伸びなかったというのがあったのかもしれません。
  • パフォーマンスを上げるための必殺技ばかり意識してしまった なるべくDBにアクセスしないでメモリに乗せるのがほぼ定石になっていますが、そもそもDBの構造がおかしい(予約がないと座席の空き状態がわからないとか)のを直せなかったのが悔しいです。データ構造を変えるということに頭が回りませんでした。

Try

  • そろそろgoで出たいぞ
  • ローカル or 個別の環境で動かせるようにする 動くかどうかまで本番環境で試すのは流石に効率悪いので…
  • 全体最適を意識する 自分がこのサービスを作るならどういう設計にするかみたいなことを考えながらやる

今年も予選突破は叶いませんでしたが解いていてじわじわスコアが上がっていくとてもいい問題だと思いました。運営の皆さん毎年ありがとうございます!あと3年連続で弊社オフィスを使わせて頂いてありがとうございます。外部の人でも快諾してくれて懐の深さに感謝しかありません。

チームメイトの二人も今年もありがとう!

f:id:azihsoyn:20180917235745j:plain

(写真にチームメイトじゃない人が写ってますが)

あ、rehash.fm も相変わらずよろしくおねがいします。 rehash.fm