ISUCON10予選に参加して再起動試験でFailしました

2020-09-20
9/20/2020,

9月12日に行われたISUCON10予選にチームNaruseJunとして参加しました。
使った言語はGo言語です。
結果は最終計測スコア2370で、再起動試験でFailし失格となりました。

再起動試験でFailした理由についてはチームメンバーの@kazが調査してくれました。
https://gist.github.com/kaz/14fe1ab63a84a600891b3cea4b97f4ba

めちゃくちゃ悔しいですが、なってしまったものはしょうがない…
941さん曰くISUCONは来年も開催してくださるそうなので、来年までに精進しておきます。

以下、やったことを書いていきます。

予選開始まで

今年はkazさんに誘ってもらってチームで出ることになりました。
同じサークルのtakashi_trapを誘って3人チームとなりました。

去年までは事前にサークルで模擬戦したり、長い時間かけて準備したりしていたのですが、大学を卒業してそこまで時間が取れなくなってしまったのでISUCONに向けた準備は3週間前と1週間前にチームで通話をつないで会議をするくらいでした。

3週間前の会議では、ISUCON 夏期講習 2020の資料を元にチームでの動き方を検討したり、それに合わせて必要なツールや環境の準備について話し合ったりしました。

1週間前の会議では、前回の会議で決めた動き方をISUCON9予選で素振りするといった感じでした。

今年は僕はコマンダーということで

準備したもの

もう3年目になるチートシートを今年版に改良しました。

デプロイ周りは去年と同じくMakefileを用意してそこに便利スクリプトを書いていくようにしました。

今年はミドルウェアの設定ファイルもリポジトリで管理しようということになりました。
NaruseJunチームでは、リポジトリ以下に ${HOSTNAME} ディレクトリを作成し、その下にルートディレクトリの構造と同じようにファイルを配置することにしました。例えば、hostnameがs1のサーバーのnginxの設定ファイル(/etc/nginx/nginx.conf)は ${RepositoryRoot}/s1/etc/nginx/nginx.confに配置されます。
これを rsync -r $(HOSTNAME)/ /としてやると、どのサーバーでも同じコマンドでファイルを展開できるようになります。シンボリックリンクを貼るよりもシンプルに管理できるのですごい楽でした。

同様に各サーバーで起動するものの制御も ${HOSTNAME}以下に配置して実行するようにしました。

初動のツールのインストールなどは@kazがAnsibleを書いてくれて、slackcat, kataribe, myprofiler, netdata, dstat, PHPMyAdmin, kibanaが動くようにしてくれました。
さらに、今年は事前にレギュレーションで踏み台サーバーの先に競技用サーバーがいることが明記されていたので、@kazがアプリやpprofに事前に決めたドメインでアクセスできるようにもなっていました。

予選開始から

(得点の履歴をちゃんと取っていないので得点は大体です)
今回はアプリケーションを見てログ見て、kazとtakashi_trapに~~やったらスコア上がりそうって言って実装してもらうばかりだったので改善点の解像度もめちゃくちゃ低いです。

初動: 環境構築・NginxでのBotアクセス拒否・プーリング

初動は事前会議の通り、チートシートに沿って進めていきました。
僕はレギュレーション・当日マニュアルを読み、Makefileで必要な設定などを行いました。
kazはAnsibleでサーバー上に環境構築、pprofの導入をしてくれました。
takashi_trapはリポジトリに各種ファイルを追加、秘伝のタレの設定をしてくれました。

序盤はポータルが重く、ベンチも満足に回せなかったのでマニュアル上でわかるBotによるアクセスの拒否や、sync.Poolを使った配列のプーリングなどを実装していました。

nazotteの改善

15時頃になってようやくベンチが回せるようになってきたので、計測を行って重いことがわかったnazotteの改善にkazが着手しました。
Goのライブラリを使って内外判定をアプリ側でやるようにしました。
700点くらいに上がったと思います。

MySQLからMariaDBへの変更

MySQL5.7からMariaDBに入れ替えました。
800点くらいに上がりました。
いや~~これ入れ替えたせいでFailになってしまったのでめちゃくちゃ後悔しています。

EstateのFeaturesを正規化

takashi_trapがEstateのFeaturesがLIKE検索でインデックスが効いていない部分をインデックスが効くようになることを狙って正規化しました。
1100点くらいになりました。

lowpricedchairのキャッシュ

kazがやってくれました。
1400点くらいになりました。

chair, estateのrangeを定数で引けるように

takashi_trapがやってくれました。
初期実装ではIDで受け取った検索クエリをわざわざ範囲に変換した上で、DBに投げていますがそれをIDで直接検索できるようにしました。
1600点くらいになりました。

(講評を見て知ったんですが、Generated Columnというこれのため!みたいな機能があるんですね。まだまだDB力が足りない…)

2台構成に

to-hutohuがやりました。
サーバー1をAppにサーバー2をDBにしました。
DBの垂直分割は思いつかなかったです。
それぞれのテーブルが独立していることは議論の中で少し触れていたんですが、正解にはたどり着けませんでした…
それでも2台にして使えるCPUの総量が増えたのでかなり効きました。
2000点ちょいくらいになりました。

バルクインサート

to-hutohuがやりました。今回唯一の実装です。
CSV入稿の部分で1件ずつインサートして時間がかかっていたので、そこを一括でインサートするようにしました。
2100点くらい。

この時点で20:40(競技終了40分前)でした。

ログなどを切って再起動試験

導入したツールを落としたりNginx,Appなどのログを切って再起動試験を行いました。
記事最初で挙げた調査にもあるように再起動直後にベンチを回していたので、このタイミングでのベンチは通ったんですよね…
悔しすぎる…

ベンチを数回回して最高得点が出た2370でフィニッシュしました。

反省

完全にDB周りの知識が足りなかったなあという感じです。
競技修了後のDiscordを見てるとSPATIAL INDEXや降順インデックスなど知らないことがたくさんあって勉強になりました。
あと、ちゃんと必要なサービスがすべて正しく起動しているか確認する!!!!

良かったところとしては、MakefileやフォワーディングなどDXが最高だったところです。
これに関しては準備してくれたkazに圧倒的感謝です。
サークルの後輩たちがたくさん決勝に行ってくれたのもサークルおじさん的にはとても嬉しいです。

最後に、ISUCON運営の皆さんお疲れさまです。
楽しい問題をありがとうございました!

来年は絶対優勝するぞ!!!

Comments

コメントする
Name:
Content:
コメントは承認されると表示されます