Featured image of post ISUCON10予選参加してきました。

ISUCON10予選参加してきました。

ISUCON10に出て来ました!

ISUCONって?

いーかんじスピードアップコンテストです。

参加者のチームにインスタンスと各言語のアプリケーションのソースコードが与えられるので良い感じにスピードアップしつつインスタンスに展開するコンテスト です。

チームメンバー

チーム名はワンランク上のジロリアンです。

【ハッカソン】 第1回オンライン学生ハッカソン参加記 – 文章捨て場

このメンバーですね。

楽しかったです!ありがとうございます!

タイムライン

前日まで

ConoHaでVPSを借りてISUCON9の予選問題を建てて練習をしていました。 一週間くらい借りて1000円ぐらいで嬉しい!

あとはプライベートリポジトリを建ててた。

前日 PM 18:22

前日夜に打ち合わせしようって話をしていた。しかし集まる時間を忘れてDiscordでチームメンバーに今日何時から?って聞く。

非常に眠く、二時間ぐらい返信が無かったのでそのまま寝てしまう。

これは伏線ですが、僕が寝ている間に(たかひろ)@taka0110_さんが

sync.WaitGroupの正しい使い方 - Qiita

を貼っていました。これは伏線です。

前日 23:50

起きてしまった。(早寝すると)Discordを覗き見したらチームメンバーがめっちゃ打ち合わせして当日にやることとか書いてた。

焦る。とりあえず、Discordをオフラインにして睡眠導入剤(ネムリナ)を飲む。それでも全然寝れなかったのでゲーム(ゼノブレイド)やろうかと思ったけど、 なんか申し訳ないのでゼノブレイドの攻略サイトを見る。寝れる。

当日 5:30

起きる。起床のプロ。多分起床時間なら一位だと思います。対戦よろしくお願いします。 チームメイトはまだ起きていませんでした。

暇なのでsync.WaitGroupの正しい使い方 - Qiitaを読んでいました。

(これ、VG社のインターンでこの辺りのこと聞いてたのでそれのトラウ・・・いや、思い出もありまして、すんなり入りました。これはすごい)

当日 10:00

何やかんやで競技開始が12:00になったので、チームメイトと色々会話する。 ここで、slackを立ち上げて、そこに便利コマンド(SSHトンネリング)とかを投げまくって準備する。

僕はNew Relicの導入手順を書いてました。

当日 12:00

競技が始まる。とりあえずレギュを読む。僕は文章を飛ばし読みする癖がございますので、Botの部分完全に抜けていました。どうして・・・

とりあえず、僕はコマンドを介護してもらいながらインスタンスに接続しました。チームメイトが.ssh/config書いてくれて助かるなぁ・・・

  • 実装を読む
    • echoになっててnewRelicを組み込むのに少し苦戦した。 echo v4とecho v3があるので気をつけよう!

当日 13:30

New Relicも入れたことだし、とりあえず計測を行う

493点

当日 13:40

そういえばメモリの容量を確認して無かったので やぱた に確認してもらう。この時点でサーバー1は起動してなかったのでとりあえず放置した。 メモリ2GBである事が分かった。テーブルも2個しか無かったので、テーブルを変数に持つアプローチを止めるという運営の強い意思を感じた。

この辺りで、僕はGoのソースコードを読みながら高速化出来ないか探しつつ、やぱた と たかひろさん にnginxとmysqlの設定を丸投げしていました。 何をやっていたかは後々彼らが詳しく記事を書いてくれるでしょう・・・きっと

当日 16:00

そういえば、負荷確認してなかったので、htopコマンドを布教しつつ負荷確認する。DBとGo Appのインスタンスを分けたら、めちゃDBが重たい(100%貼り付きまくってる) ここから、DBを分けようという話になる。

reud,やぱた、たかひろさんの三人で提案アプローチが違いすぎて燃える。

僕からみた主観だと、大体こんな感じで別れた。(意図間違ってたらすんません!!!!!!!!!)

  • reud: 出来るだけ楽して点数を沢山あげたいので、 estate専用DB, chair専用DBでDBを分けよう
    • from chair,estate ってやっているテーブルがないので完全に分けられるはず。
  • やぱた: 学びを増やすために MySQL Clusterに挑戦しよう
  • たかひろさん: 堅実にMySQLレプリケーションを利用しよう

なんだかんだして僕の案で通すことに。chair*関数をもう一個のインスタンスに建てたDBに向ける。

当日 19:00

分散化しつつ色々変えてた(非同期処理出来るところを変えまくった)ら615点に伸びた。やったぜ。

nginxの設定やmysqlの設定をお願いしつつ別のインスタンスに向ける様にしてたらこの辺りの時間になった。

そして点数を確認すると・・・

615 -> 881

爆伸びです。これは勝ちました。

終わりまで

とりあえずなんでもかんでも、waitGroupにぶち込んでいく。

sync.WaitGroupの正しい使い方 - Qiita

これを使って並列化出来る所は並列化しまくりました。(ここ伏線回収ポイント)

errGroupを利用すると、まとめつつエラーを検出できるので本当に最高です。

いろんなところが go func(){} で包まれたサービスになりました。思ったよりもどんどん点数上がってて笑いながらやってました。

WaitGroupは神、errGroupも最高に良い。

881 -> 1121点 ここで終了。タイムアウトなどのエラーは無し。

正直再起動試験があまり通っている気がしない(何も対策していない)のでFailかも

振り返り

ガチでボロボロの時は反省点が後になるけど、比較的良い結果だったので良い点は後ろに行きます。(最後に一番そう思っているものを置く修正)

当日の反省点

  • 負荷確認が遅かった
    • DBに律速しているのはもっと早く確認すべきだった。
  • ベンチで走ったSQLのクエリを解析したかった。
    • これは普通に準備不足かも。ベンチが投げるAPIが偏ってるのでそれを見てできることがありそう
  • 想像での会話が多くなってしまった。
    • New Relicだけじゃなくてこれもっと計測データが必要だと思った。
    • 次参加するときは「ここが遅そう」じゃなく「ここが遅い」ってデータを持って言えたら良さそう
  • 何もわからんDBより「なぞって検索」のコードをよく読むべきだったかもしれない
    • MySQL内で多角形内に物件があるかの判定を投げている(らしい)のでそれをGo側でやる様にするだけでかなり点が伸びそう
    • いうて結局MySQLが分からないって心持ちだったので詰んでいる気もする。苦手意識を減らしたい。
  • 「なぞって検索」の操作が分からなかった。
    • なんか適当にクリックしていて、「これスマホじゃなきゃいけないやつか〜」って思って完全に放置してしまったのがかなりしくじり

これは結果論だけどDB周りのチューニングはDiscordのrandomチャンネル見ている限りまじで何も分からなかった&「なぞって検索」が競プロ力 を使えるポイントぽかったのでそこで投げているクエリを俺が読み込むべきだった・・・・ (Goのコード読む担当してたのにここサボったのがかなりもったいなみが強い)

当日の良い点

  • 負荷確認をした
    • 練習で一回もしてなかった(よね?)のにここで「しよう」って思えたのは普通に偉いと思う
    • 実際、DBが重いことに気づかなかればDB二台に分けるアプローチは出てこなかったはず
  • 「DBをテーブル毎に分割する」が良い感じに刺さった。
    • ソース自体は5分くらいで出来る変更に収まっているのでかなりコスパが良い。 - この発想が出てきた自分が偉い
  • 非同期の鬼になった
    • これ、どっちが先に終わっても良いよね?って感じのコードが沢山あったのでそこを非同期にしてWaitGroupでまとめるなどを沢山した。めっちゃ刺さった

お気持ち

  • 競プロのマラソンもそうですがこんな感じの「レギュレーション内なら何やっても良いから上を目指す」系のコンテストがかなり好き

    • 実際滅茶苦茶ゴリ押しgoroutineで点数が上がると楽しい気持ちになる。
    • 面白い(普通じゃ書けない)発想で高速化出来たら楽しい
  • 「本気でやったらどこまで行けるのか」が知りたくて冒険をガン捨てしました。

    • 正直思ったよりもいけてかなり嬉しい(学生上位50%ぐらいに収まると思ってた。)
  • 自分が苦手な部分(nginx,mysql)が気がついたら出来ていたのでチームメイトに感謝しています。

    • 一ミリも心配していなかった(なんか良い感じにしてくれるじゃろって思ってた)のでやはり信頼は大事・・・
    • 丸投げすぎてこの記事には書くことがない・・・(何も分からない)

まとめ

椅子に座ってるだけにならなくて良かった。時間を使い切れた。

思ったよりも成果が出せてとても良かったのと、インフラ触る機会滅多にないので結構楽しかった。

nginxとかmysql、趣味開発だとheroku+Firebaseとか使っちゃうので本当に触る機会が無い・・・

毎度毎度チームメイトの@taka0110_,@yapatta_progに感謝しかありません。 役割が良い感じに分担できていて暇な時間があまり無く出来ました。

今年度でチームメイトが卒業するのでその前に学生の肩書きとその優秀な能力に養分させてもらって もっと色々ハッカソンやコンテストに参加したいです。

ISUCON10 randomチャンネルに書いてあった謎の単語メモ(ISUCON11に利用する)

  • AppArmor (なんか罠らしい)
  • query cache (MySQLの設定らしい)
  • 空間インデックス (Special indexとかの話かな DBで空間ってワードが出て来て何・・・・?)
  • カバリングインデックス(mySQL8 で出来るらしい・・・)
  • generated columns

おまけ

やぱたさんがとても良い画像を持っていたので共有します。

瞬間最大風速学生7位。

追記

全チームの予選スコアが公開されました。

ISUCON10 オンライン予選 全てのチームのスコア(参考値) : ISUCON公式Blog

弊チームが再起動試験でFailしていない前提ですが。

  • 学生枠本戦通過ボーダーチーム 1173点 全体 134/468位 学生枠 9
  • 弊チーム 1122全体 143/468位 学生枠 10

でした。(全体順位は再起動試験でFailしたチームを考慮していません。)

ガチで惜しかった〜〜!!!! 悔しい!!!

来年は絶対に本戦通過してみせる。覚悟を。

追記: 2020/09/22

ISUCON10 本選出場チームの追加、また追試による失格チームのアナウンス漏れについて : ISUCON公式Blog

色々ございまして、弊チーム「ワンランク上のジロリアン」は本戦出場決定しました!!!!

このチームでのISUCON参加紀はもうちょっとだけ続くのじゃ。がんばるぞい!

Licensed under CC BY-NC-ND 4.0
Built with Hugo
テーマ StackJimmy によって設計されています。