isucon6予選に出場した感想
isucon6 予選に参加した。1 日目に、LINE 社にお邪魔しました。
準備
isucon は初参加だったが、昨年に isucon4 予選の過去問をやっていたので、引き続き勉強っぽい感じで行っていた。
スコア出した記事を事前に読んでいたので、なんとなくやればいいことは以下の感じで想像してた。
- MySQL(innodb)の設定をパワーを使うように書く
- 静的ページを nginx で配信する
- アプリケーションと UNIX domain socket で繋ぐ
- テンプレートエンジンをやめる
- 明らかに悪手っぽい処理をやめる(言語ごとの慣習に倣うとか)
参考にさせて頂いた(理解できた/記憶に残った)情報は主に以下。
- ISUCON4 予選の問題で 31 万点を出すためにやったこと - Qiita
- ISUCON 予選突破を支えたオペレーション技術 - ゆううきブログ
- ISUCON4 予選問題で(中略)、”my.cnf”に 1 行だけ足して予選通過ラインを突破するの術
- ISUCON4 予選でアプリケーションを変更せずに予選通過ラインを突破するの術 - Hateburo: kazeburo hatenablog
パフォーマンス測定が大事だというのは分かっていたし、先輩から pprof 使えるようにしておいてと言われていたのだけど、パフォーマンスを見てどうこう、というのができなかった。
業務でパフォーマンスが求められるシーンがあったので、その時から DB とか計算とかは少し意識するようにはなったけど、ボトルネックを探すというところまではできなかった。
当日
当日の試験問題は近いうちに出るだろうので割愛する。
アプリケーションが 3 つ立っていた。
UI と基本機能を提供するサーバ、json を返す API サーバ、アプリケーション内部からのみアクセスされる API サーバ、と、マイクロサービス?っぽい感じだった。
isucon 慣れしていなかったので、構築がどうとか、リポジトリがどうとか、my.cnf 書き換えるスクリプトとかは、チームの先輩にやって頂いていた。(ふがいない……)
自分は以下の内容に着手したが、手間取ってしまったり、うまくいかずやめてしまったりした。
- UNIX domain socket に書き換える。
nginx とアプリケーションを UNIX domain socket で繋ぐのだが、アプリケーションが別のアプリケーションを呼ぶので、その部分で戸惑ってしまった。
完全に準備不足なのだが、sock の所有者を誰にするかで悩んでしまった。結局 nginx をアプリケーション起動ユーザで動くようにしたが、良くなさそう。
- Golang の struct の json タグを外す。
struct のタグを取り出すのは reflect を使っているので遅い、と聞いていたので、これを外そうとした。
DB から引いて json にして返す部分はハードコーディングでできたのだが、全件取得して別のマイクロサービスに渡す辺りで設計が分からなくなってしまった。
時間もあまりなかったので、他にできることをやるために断念。
- MySQL に innodb の設定を書く。
できることがなくなってしまったので、まだされていなかったことをした。
- Golang アプリケーションから MySQL に UNIX domain socket で接続する。
やることが分からなくなったので先輩に指示を仰いだ。業務じゃないんだから……という感じ。
アプリケーションから MySQL への接続を UNIX domain socket に変えてみたが、接続はできるようなのに、Query の処理(database/sql/sql.go の db.mu.lock() )で nil 参照になってしまった。
パーミッション等かと思ってみたが動かず、時間がないのでできないままになってしまった。
この挙動は謎なので、後日また確かめる。(今日は疲れてよく寝ていたし、掃除をしていたら終わってしまった。)
感想
自分でなくてもできるような変更しかできなかった。非常に悔しい。
準備不足というのもあるし、普段意識していない内容というのもあると思う。
Golang でアプリケーションを作る知識というより、サービス全体の設計の知識が足りないと感じた。
特にパフォーマンスを見てやるべきことを考えられるよう、復習したい。