isucon練習記 isucon9(予選)
isucon9-qualifier-standalone をやってみる
Vagrantfileの一部をコメントアウトして192.168.33.10:8000にアクセスしたらブラウザからアクセスできた
前回の手順通りやってSSH出来るようにした
code:console
vagrant@vagrant:~$ sudo mkdir ../isucon/.ssh
vagrant@vagrant:~$ sudo cp .ssh/authorized_keys ../isucon/.ssh/
vagrant@vagrant:~$ sudo chown -R isucon:isucon ../isucon/.ssh
VSCodeからも開けた
とりあえずベンチマークを回す
./bin/benchmarker
1910点だった
プロファイラを入れてみる
参考:
net/http/pprofを使ってみた
ベンチマークを起動後、プロファイラを実行した
WebUIもついていてすごい
go tool pprof -http=":8081" isucari http://localhost:6060/debug/pprof/profile?seconds=100
デフォルトの30秒だと短いのでパラメータで指定してベンチ時間より長く取るようにした
見方
Flat:関数の処理時間
Flat%:各Flatの全体に対する割合
Sum%:スタック履歴からの累計Flat%
Cum:待ち時間も含めた処理時間
Cum%:各Cumの全体に対する割合
Name:関数名
プロファイラ結果を見た感じ、getNewCategoryItemsとgetCategoryByIDが赤い
WebUIの検索がエラー吐いててつらい
code:console
Uncaught TypeError: Cannot read property 'length' of null
at selectMatching (source:17762)
source:17722 Uncaught ReferenceError: updateUrl is not defined
at HTMLInputElement.handleKey (source:17722)
pprof -http=":8081" isucari http://localhost:6060/debug/pprof/profile?seconds=100
getCategoryByIDの中でSQLクエリが2回発行されてたので1つにしてみた
WITH句が使えないと思ったらMySQLが5.7だった
スコアは特に変化なし
計測結果で一番時間がかかっていたgetNewCategoryItemsのN+1を気合で改善
上:最初の計測 下:改善後の計測
https://gyazo.com/015191b6215cb673a714dd7b0526979c
めちゃ早くなった
でも点数はむしろ落ちた(なんで?)
あと時間がかかっているのはpostLoginくらいだけど、これはbcryptによる処理がそれの大半を占めてて、改善方法が分からない
完全に詰みなのでググってみる
最初に公式のレギュレーションについての記事を見た
ISUCONの課題アプリケーションとして、bcrypt の負荷を解決し高いスコアを出す方法がサーバの追加の一つだけであることは避けたく、bcryptの変更禁止ではなく軽量なハッシュ関数での代替を可能とする、「平文での格納を認めない」という文言をマニュアルに追加しました。
複数台構成は練習だと大変なので、別のアルゴリズムへの置き換えがよさそう
md5とか普通パスワードに使うべきでないやつでもいいんだろうか
ブログを読んでいて気付いたこと
kataribeを使う
nginxの準備
main.goで指定されているポート番号を8001に変えて、以下のnginx設定ファイル追加
code:/etc/nginx/conf.d/test.conf
server {
listen 8000;
location / {
}
}
sudo systemctl restart nginx.service
ログが/var/log/nginx/access.logで取れるようになた
kataribe対応
READMEを読んでnginx設定にlog_format追加
code:console
sudo rm -f /var/log/nginx/*
sudo nginx -s reload
実行
sudo cat /var/log/nginx/access.log | kataribe
/users/transactions.jsonが重いらしい...
キャンペーン機能の存在
ソースコードをリファクタリングすることだけ考えていて、仕様を全然読んでいなかった
OR句は2つのSELECTで置き換え可能
1つ目のORクエリに関しては、次のようにUNIONクエリをつかった形式に書き換えることでINDEXで十分に絞り込みが可能な状態になります。
SELECT * FROM items WHERE seller_id = ?
UNION
SELECT * FROM items WHERE buyer_id = ?
kataribeで分かった/users/transactions.jsonのN+1を治す
getNewCategoryItemsのSQLの一部を使いまわしたら部分的に改善出来た
とくにスコア上昇には繋がらなかった