ISUCON10に出場して再起動試験で泣いてきました

ISUCON10にチームINJとして学生枠で出場し、結果としては学生本戦出場枠には入っていましたが、再起動試験で失格でした。

isucon.net

今年は最後の学生枠みたいなところがあったので、まぁ思い出づくりも兼ねて id:unimarimo (jogo)と研究室の後輩でありシス管のmkくんと出場しました。ちなみにチームは id:unimarimo以外は初参加。

シス管メンバー集結みたいな形になったのだけど、なんとisuconの予選と大学のネットワーク機器の入れ替え工事日が被ったので関係各所にはご迷惑をおかけしました...。ちなみに今回は各自自宅からzoom繋ぎっぱなしで参戦しました。

ちなみにチーム名INJはIikanji Na Jogo の略です。

f:id:anatofuz:20200913045123j:plain

役割分担としては

  • AnaTofuZ
    • 全体, 声掛け
    • webapp
  • Jogo
    • インフラ全般
  • mk
    • 遊軍

みたいな感じでした。 特にJogoくんがインフラ専門として活躍していて、マルチに活躍できるmkくんが遊軍としていろんな領域を見れていたのは良かった気がする。

やったこと

まとめると

  • チームの声掛け
  • デプロイスクリプトの用意
  • ヤバそうなエラーの解決要因
  • dlvを投入してのデバッグ
  • jsonライブラリの変更
  • 細々したSQLの変更
  • いらんORDER BYの削除とか

このあたりをしました

だいたい時系列ごと

2hの猶予が与えられたので、シェルでデプロイスクリプトをしこむ。わりと便利だったのでやってよかった。

ポータルが508騒ぎの中、「当日マニュアルはdiscordにURLがあるぞ」という話になり、みんなでポータルが復旧するまでマニュアルを音読していた。

「とりあえず椅子と資料請求させとけばええんか」「なるほどな」みたいな話をしていた。あとここでBot対策が重要そうだけどまだ実装されてないとかあるので、実装せないとな.....みたいになった。

ポータル回復後みんなでsshまつりをする。ssh先のIPの計算ができなかったが、mkくんがバシッと運営のconfigをupdateしてくれてそれを使うことになった。ポートフォワーディングのconfigの書き方とsshコマンドの使い方を理解する。

gitリポジトリ化とpprofとgo-sql-proxyをしこみ(mysql:proxyの書きミスとかがあり手間取ったが)大体開始1hちょいくらいには全体のボトルネック等をチームで共有した。アクセスログはalpが上手く読めず、全体を通して活用できてなかった。どうもUserAgent周りとアクセス先のエンドポイントが重要そうだったので、ちゃんと見るべきだった気がする。

pprofの結果json関連とnazotteがネックになっていることがわかったので、golangで使っているjsonライブラリを github.com/goccy/go-json にひとまず切り替えるなどを仕込んだ。そこまでスコアが上がらなかった気もするが...。

github.com

なんとなくテンプレートがねぇなという話になり、そもそもこの画面はどこから来ているかを探したところ、「あっ静的HTMLでjs経由か!?」みたいな話になる。「えっ画像もほとんどこのディレクトリじゃん.......」と連鎖的に確認し、jogoくんにnginxのキャッシュとgzip等の最適化を依頼する。

そういえばbotの解決もするかと思い、軽くググるとuser-agentのブロックはnginx側で出来るらしいので、jogo先輩に脳筋if文コピペを以来する。

nazzoteのN+1を解決すれば伸びそうというのはわかったものの、JOINするわけでもないので「ぐぐぐ......」となり、とりあえずSELECT *している不毛な箇所を消してまわろうという作戦に出た。一箇所の変更は問題なくて、ある程度いい感じになった。

ここで調子に乗って「表示に影響しないJSONの要素も落とすか」となったが、この施策をし始める前後でベンチが何も言わず死ぬ減少が多発する。いろいろロールバックしていたが状況がわからず、運営に問い合わせたり色々していたところ、mkくんがレギュレーションに「JSONの変更はNG」との文脈があることを発見。泣きながらロールバックする。ここでだいぶ時間をとられた......。

jogo先輩とmkくんが作ったindexのsyntax errorを解消していたり、自分のSQLのsyntax errorを解決していたりもしていた。デバッグしたかったので本番にgolang 1.15とdlvをいれて気合で見ていたけれど、このへんがあんま良くなかったかも知れない。

index周りだとSELECT * FROM estate ORDER BY rent ASC, id ASCみたいなクエリのindexを有効化しようと頑張っていたが、FORCE INDEXしないとindex貼られないという事件に遭遇していた。感想を見る限りMySQL8を使うかデータ構造に手をいれるのが大正解だったらしい。ぐぐぐ。。。

終盤でMySQLのクエリキャッシュが結構聞くことがわかったので、2台目をDBサーバーにするという背策をjogoとmkくんに頼み、ベンチマークを回していくと過去最高の1200台を記録。かなり盛り上がった。

レギュレーションで学生が上位25チームに入ればそれを除いた学生上位5チームが本戦出場なので、ギリギリいけるかな〜みたいな話をしていた。結果はギリギリ行ける枠にはいたのだけど、再起動試験で失格でした。再起動チャレンジやってなかったので痛いところ。まぁ再起動しても気づいたかどうかは別っぽい。

所感

ということで学生最初で最後のisuconでした。チーム運用もめちゃくちゃ良くて、ギスギスせずに進められたので良かった気がする。(configのコピペ忘れをしたjogo先輩に「舐めプか?」と煽ったのはノーカン)

全然俺はSQLもHTTPもわからん.....なにも...........。みたいになったので、webの勉強ちゃんとしないとなぁと思いました。細々した修正を中心にやってしまい、もう少し責めのコミットができるくらいの知識が必要でした。特に序盤ではsqlx関係のエラーを多発させてしまい、「sqlライブラリの慣れと、SQLの知識が必要だったな.....」と痛感しています。N+1は最初に気づいたにも関わらず、解決できなかったのが痛いです。他にもなんとなく改善できそうなとこは何個かあったけど、歯が立たなかったです。。。nazotteの改善でいろいろミスを踏みましたが、dlvいれてからは冷静に対処できたのでそこは良かった、そもそもミスをしたのは、経験値不足なのでツラミですね。。。

他にはテーブルが2つなのでDBを分けるという話がrandomチャンネルにありましたが、思いつかなかったですね。

あんまり練習時間が取れなかったチーム(全員シス管なので)+初めてのisuconでしたが健闘できたのは良かったですね。もちろん学生上位とのスコア差は大きいですが、普段からweb専門にやってる人がいないチームで1000点超えれたのは大きい気がする。これはid:unimarimoとmkくんの働きがすごかったというのがほとんどですね。これで本戦に行っていればもっと良かったので再起動試験が悔やまれます。一度再起動試験を試すべきだったな.....。ちなみに再起動試験のどこで死んだのかは調査中です。(どうもベンチで使ってたサーバー以外の方をみられていたらしく、そっちはnginxを動かしていた為に勘違いされた or そいつがDBを使いにいってベンチ側のサーバーからDBにアクセスできなかったのではという話を推測しています)

全員就職先の土地がバラバラなので、次回このチームになることはオンライン開催でない限り無理ですが、チームとしても良い経験になったかなと思います。シス管の作業頑張っていこうな...。

チーム関連だと他メンバーへの声掛けとか詰まってるとこを協力して解決ができてよかったです。ISUCON夏期講習の「手が止まっている時間を作らない」がちゃんとできたのはチームに貢献できた点かなぁと思います。

次回のisuconがあれば社会人枠ですが、ここで本戦出場目指してやっていきましょう。バンバンスコア上げたいしもっと貢献したいね。。。。現場からは以上です。