こんにちは, yapattaです!
今日はISUCON10(いい感じにスピードアップコンテスト)に参加してきました!!
点数は1122点です!
[追記]
学生内10位になり本戦出場できました!嬉しいね!
チームメイトはreudとたかひろさんです.
僕らのチーム名は「ワンランク上のジロリアン」です!! なんでそんな名前になったんでしょうね??
では早速, 僕らが8時間で何をやったか記載していきたいと思います!!
やったこと
リストに上げていきます.
- サーバーの構成確認
- ssh config設定
- NewRelicを噛ませる
- NginxでBotを503に投げる
- Nginxの設定見直し
- MySQLの設定見直し
- Where句の最適化
- index貼り
- goroutineで投げまくる
- MySQLの並列化(2台)
では具体的に一つ一つ見ていきましょうか〜
1, サーバーの構成確認
ちゃんと(公式のドキュメント)https://gist.github.com/progfay/25edb2a9ede4ca478cb3e2422f1f12f6は見ましょう. 要件確認は最重要項目です. 制約を見る力がAtCoderで鍛えられたと思います, きっと.
2. ssh config設定
踏み台サーバーを経由して, webserver群にアクセスする必要があります. .ssh/config
に設定を書くとそこいらへんが非常に楽になります.
Host isucon-bastion HostName 踏み台サーバーのIP Port 20340 User isucon Host isucon-server1 ProxyJump isucon-bastion User isucon HostName server1のPrivateIP Host isucon-server2 ProxyJump isucon-bastion User isucon HostName server2のPrivateIP Host isucon-server3 ProxyJump isucon-bastion User isucon HostName server3のPrivateIP
またトンネルを掘ってポートフォワーディングすると, プライベートネットワーク内のwebserverにhttpアクセスできます. 以下例↓
ssh -L 8888:10.163.89.101:80 isucon-server1
ローカルの8888ポートにプライベートネットワークの163.89.101:80をバインディングしている例です.
3. NewRelicを噛ませる
遅いエンドポイントがわかりました. まあそうだなという感じでした.
4. NginxでBotを503に投げる
Botからアクセスが来たら正規表現で判定して, 503 Server Unavailableに投げます
if ($http_user_agent ~* "^ISUCONbot(-Mobile)?$") { return 503; }
上が例ですね.
5. Nginxの設定見直し
静的ファイルをキャッシュした. README見たら意味がないことに気づいた. 制約はちゃんと見ましょうね.
あとは, worker_rlimit_nofileを30000にして, worker_connectionsを7500にしました. いっぱいコネクションを張れそう.
6. Where句の最適化
estateを取り出すwhere句が冗長だったので, 最大最小を考えて条件を半分に減らした.
hd := h
if h > d {
hd = d
}
みたいなイメージです.
6, Index貼り
DBのIndexを貼りました. 少し早くなった気がします.
7. goroutineで投げまくる
これがめちゃめちゃ早くなるのに貢献した. 並列化できそうなところでとりあえずeg.GOでgoroutineに投げて, eg.Waitで最後に並列処理を回収しまくった.めちゃめちゃ早くなった.
8. MySQLの並列化(2台)
SQLサーバーを並列化しました. 大層なことを言っていますが, クラスタを組んだわけでもなく2つのSQL Serverをただ起動したです. つまり全く違うDBにクエリを投げてもデータの整合性が取れそうなところでそれぞれのDBにクエリを投げて処理を分散させています. goでdbのインスタンスを2つ持つという鬼畜ぶりです. まあとりあえず早くなったから良し.
コンテスト後にDiscordを見てやっておきたいなと思ったこと
- クエリキャッシュ
- 空間インデックス
- AppArmer
- Geometryのライブラリを使う
- Chairのいらないクエリを削除
- MySQL Server8系統を使う
- Redisを使う?
- nazotteを計算量最適化
- generated columnsを使う
- popularityをマイナスにする(idとpopularityをマイナスにできる)
感想
楽しかった. 前日話し合ったことが結構役に立った. goroutineに感動した. 並列化は正義. 疲れました, おやすみなさい.