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 をアプリケーション起動ユーザで動くようにしたが、良くなさそう。
struct のタグを取り出すのはreflectを使っているので遅い、と聞いていたので、これを外そうとした。
DB から引いてjson にして返す部分はハードコーディングでできたのだが、全件取得して別のマイクロサービスに渡す辺りで設計が分からなくなってしまった。
時間もあまりなかったので、他にできることをやるために断念。
できることがなくなってしまったので、まだされていなかったことをした。
やることが分からなくなったので先輩に指示を仰いだ。業務じゃないんだから……という感じ。
アプリケーションからMySQL への接続をUNIX domain socket に変えてみたが、接続はできるようなのに、Query の処理(database/sql/sql.go のdb.mu.lock() )でnil 参照になってしまった。
パーミッション等かと思ってみたが動かず、時間がないのでできないままになってしまった。
この挙動は謎なので、後日また確かめる。(今日は疲れてよく寝ていたし、掃除をしていたら終わってしまった。)
感想
自分でなくてもできるような変更しかできなかった。非常に悔しい。
準備不足というのもあるし、普段意識していない内容というのもあると思う。
Golang でアプリケーションを作る知識というより、サービス全体の設計の知識が足りないと感じた。
特にパフォーマンスを見てやるべきことを考えられるよう、復習したい。