feature image

2020年9月13日 | ブログ記事

ISUCON10予選学生2位で通過しました。

はじめに

「がんもどき」(@sappi_red, @ryoha, @temma)というチームでISUCON10予選に参加して、全体5位・学生2位で予選突破しました。
全員、初出場でしたが練習のおかげでスムーズに作業できてよかったです。最終スコアは 3407 でした。

構成

仕様実装: Go

やったこと

準備

部内WikiのISUCON攻略記事やこれまでのwriteupを読んだりしながら、部内ISUCONを10万点まで触りました。あとは、Makefile書いたり、リポジトリ作ったり、攻略をMDにまとめたりとほそぼそ準備をしてました。

Makefileには初動のセットアップ周りと計測周りが書いてあります。僕は結構ポカをやりがちなのでsetupコマンド以外で必要な操作をechoで色付き出力するようにしておきました。

役割分担は

みたいな感じでした。

当日

結局5:30ぐらいまで寝れなくて、朝めっちゃしんどかったです。1億年ぶりに朝ごはんとかいうの食べました。

誰かの家に集まるか迷っていましたが、ディスプレイが多いほうが良いってことと通話での作業に慣れていたことからDiscordとSlackでリモート参戦することにしました。

10:00

12時からになったので、とりあえず集まって初動とか全体の流れの話をしてました。あとは、レギュレーションの再確認やGeneratedColumnの書き方とかを確認しつつ雑談タイムという感じです。

12:20 競技開始

アクセスが集中したせいかteamID等が確認できなかったので、とりあえず開けたmanualから読むことにしました。

少ししたらportalが開けるようになったので、他の二人にはmanualやコードを読んでもらいながら

などを進めました。この間に、コードを読んでいる二人はTODOをコメントで追加してくれていました。
色々やって、とりあえず改善を入れていける状況になるまでで大体1時間程度でした。

一旦体制が整った13:15分時点の初回ベンチでスコアが 482点 です。

13:50

この時点で@ryohaがpostChairのbulk insertを実装して、ひとつN+1を解消してくれていたのですが、ベンチマーカーが回せないとのことだったのでそれ以外のエンドポイントを触ることにします。

manualを読んだ時点で、@sappi_redがbotをブロックする方法を思いついていたのでrobots.txtとnginxでのブロック($http_user_agent)を導入しました。

他には、@ryohaがsearchChairssearchCondition+limitOffset付きの重いクエリが2回飛んでいるところをmysqlの情報関数を使って軽くしてくれていました。

14:50

ベンチマーカーが回せる様になったのでこれまでの改善を修正しつつ、改善を加えていきます。

計測

計測には以下のツールを利用しました。

これらをMakefileのコマンドから実行し、結果をslackcatでslackに送信するようにしていました。


ここまでの改善でスコアが 1219点 に伸び、加えて以下のような改善後のスコアが 1427点 でした。

小話: @sappi_redがfeaturesをSET型でDBに入れようとしていたのがずっとfailしていて、ベンチのreasonも不具合で返ってこなかったので運営に問い合わせたら、DBに入っている順を保持して返してほしいとのことでFULLTEXT INDEXを使うことにしました。DBに入っている順を保持して返す意味がよくわからなかったので有識者は教えてくれると助かります。

18:00

ここまででなんだかんだ結構改善を入れていたのですが、思いの外、DBのCPU使用率が改善せずボトルネックのままでした。
INDEXの効きが悪いように感じたので@sappi_redに頼んで実行計画を見てもらいながら、裏でtable毎にDBを分けることにしました。tableを同時に参照するような処理がなかったからです。DBを2台構成にしたタイミングで2500点弱出るようになり、@sappi_redが凸包の内外判定をアプリ側で行う処理を実装したことで3000点近く出るようになりました。

19:00

1時間前にコードフリーズすることを決めていたので、残り1時間です。
@sappi_redが改善してくれたはずのINDEXですが、いまいちスコアに反映されなかったのでestateのrange_id系の判定をGenerated Columnを使って高速化できないか試してみました。時間がないので、@ryohaにアプリ側のコードを書いてもらいつつsqlを書いていました。

裏では@sappi_red自作の超速JSONエンコーダーを@sappi_redが導入してくれたのですが、他がボトルネックすぎてスコアが伸びなかったので全部revertしました:sad:

若干スコアが伸びたもののあまり効果はなかったようです。ほかのところでINDEXを貼るために使うと良かったみたいですね。初めて使う機能だったので、最初に手を出して沼るのが怖くてなかなか発想に登りませんでした。割とスッと導入できることが分かったので、本戦ではうまく使っていきたいです。

19:40

時間的にほとんどできそうなことが残ってなかったので、最後に@sappi_redがNginxのUnixDomainSocket利用を試してくれましたがやっぱりうまくつながらなくて断念です(試したことはあったけどうまくつながらなかった)。
DB側のメモリが余ってたので、パラメーターをちょこちょこいじってましたがあんまり改善しなかったです。キャッシュヒット率とか求めてなかったのでMySQLTunerとかちゃんと使えばよかったなという感じです。

20:00

コードフリーズして再起動試験を行いました。@sappi_redが設定を戻し忘れててオイオイ落ちとるやん〜〜みたいな事があったのでちゃんと再起動試験してよかったです。

あとは、ログとか外してガチャタイムです。2

実は、最後の方のベンチガチャで「レスポンスが不正です」でまれにFailすることがあったのですが、アプリケーションのコードに不備を見つけられなかったので、ベンチマーカーの不備であることを祈ってました。

学生1位だと思ってたのでshallow verseが発表されたときはマジで絶望しましたが無事通ってて嬉しいです。

まとめ

改善に関してはINDEXのチューニングが甘かったこと以外はずっと沼っているとかもなく、及第点という感じです。

コロナ期間、この三人でずっと通話していたのでそれぞれ何が得意か共有できていたのと全体的にチューニングに関する知識を共有できていたのでコミュニケーションコストは小さかったと思います。(「これ多分例のアレで悪いからあの手法で直しといて」みたいなのが通じて良い。)

本戦では学生1位を目指してがんばります!!

P.S.
がんもどきはto-hutohuさんの豆腐を原料に(ぐちゃぐちゃにして)できているってことから名付けました:love:

temma icon
この記事を書いた人
temma

19 生命理工学院

sappi_red icon
この記事を書いた人
sappi_red

19B。SysAd班。 JavaScript書いたりTypeScript書いたりGo書いたりRust書いたり…

ryoha icon
この記事を書いた人
ryoha

美少女ゲームをするためだけに生まれてきた真の戦士です。夢は「グガガガガガ...コレガ....アイ..」ってなることです。

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2019年12月17日
部内ISUCONを開催しました
xecua icon xecua
2020年10月14日
ISUCON10本選3位とりました
sappi_red icon sappi_red
2020年9月16日
学生枠でISUCON10の予選を通過しました
oribe icon oribe
記事一覧 タグ一覧 Google アナリティクスについて