owned this note
owned this note
Published
Linked with GitHub
ISUCON7 ワイルドワイクボタ
==
# 公開鍵
## ykubota
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDZq5NVhmgrFPnw31uT+2twqJBQmnhZMx5SNfxq/mov78i8VpAykitNjhtE+KSGE7rm8Bz4gomclkPGZ8aYX9XHp6B/N9cGEALj5QAqdIyIK+sQMlBEqUdUMyMJI/qSIx5hsYwx1GTIyNBx2cM6N/1uwJ4MJ4ieArn6PQZv0gdiONpUSc8WO4oGjcLQrG0fIcqWCpkgDlEKt66IG68L7ffuQY6eweVNlyVLCL0jzYl2HwBmOUikAhybLnmWMOoLU2pdX39sSYXBxyD6nSF2h4BE76hSha/jVF/SmBV7XXP4PP/bNlO+hFGi8KNLCAtP6ruQPxgfKPLdHolHGgG4NkZR/IyyAd87VCqNX/N6R5Q0alHSO5UR1B1F35J8PAHEh9Wx50bfiEoazLLdJf5j+lGCRAwu5uaTh8oeEu8czckAL0TZMQb+BsZuNxv9DVKYY9AEuRia3EAf5wH/Ow2YLJaQMVR3u6+ZLO1rbLvUlhGnrvf26rzWgwhIbpAkU5HoTCRYWwJDQrKCThcsBEKNdyM86whBv1IILGoEhVRXVRqSLOBeC5pu4Mdl6m0bc/HADhYE1yhmFDbqEvi/dzgeR9Yzyw64qn0+dXNnvgmFJFLtQTaHBdJ83m1DjjN5BRry7tz/nqXAU9/H1zUDpuCxYrcxccJXAGtL6e0Kk59bdr38QQ== jarkeys@gmail.com
## simd_nyan
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMU242Or2tJoJvhlJDEdqn0e8YAunfkJSNF+Sq8FR341RSaUgucObiAj+WCKmEgRp6PnIW9sy8VYsUN9zuAK6ggojBEXlA58G4X0a04BO0H3JnlODGxjHXUM6nnAIwwGvEqZPTiO80ARgdQ4bivO79yqQ5mUT2WjRHZobvEBrQ9+hvS8Lmr/lDk9t9Ru+0bF/L06eP9ZYD+vQKXtj+bGhGb9UYQdwIJ0y2RITRCg1bP5JpU8AAkKhQaxiDMptOhiNmmChvuPaGndgeQCx8XJggWOmG7ruk2XAqTK4VCahnRo8siw7cEzH0u1jw/va1Jp3t3Xhgy7Sn7UOOYUrLhTDv Y.Shimada@X1C
## yamada-h
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDmwE8xAyJnYqw/MYBaYCqeUtxvJF5x2KFecdDsToWCBoZk2eq9bB5A9z9pYAJzW+1SAV2JhfkFq+XgCZD87Z5PhinUYAVKzOBwVL5Vnrg4cMQTyK2nPeoxcT5pZgMa6KuhFFmQHmWAZ1hHmUiDDOgxJ+AC8mYac3bPC2TEhsXdVRv/NjZ7+hJXZyrS0F641+GzAWVngTIRlA2P247l3z4p0meb+tp/PQT3G8XBSsR+EWSMl08XlYM8X8BooG6cHKYlvgiuXofiVnQjuzZQ7LeAYUJ5kVuINOpvrPQHF/ysjT2eAuHa8bFcrk5BCDVH0XTZSfuNixwDBBrmDNrxwCf .ssh/github
# ツール類
## xbuild
各言語のランタイムインストーラ
https://github.com/tagomoris/xbuild
## netdata
いい感じにリソースモニタリングできるやつ
https://github.com/firehol/netdata
## kataribe
nginxのログを解析してURL毎のアクセス分析するやつ
https://github.com/matsuu/kataribe
## pyflame
pythonコードのどの辺が重いかあたりをつけるやつ
https://github.com/uber/pyflame
## alp
アクセスログの解析
https://github.com/tkuchiki/alp
```
wget https://github.com/tkuchiki/alp/releases/download/v0.3.1/alp_linux_amd64.zip
unzip alp_*zip
sudo install ./alp /usr/local/bin
```
Apache
```
httpd.confに以下を追加
LogFormat "time:%t\tforwardedfor:%{X-Forwarded-For}i\thost:%h\treq:%r\tstatus:%>s\tmethod:%m\turi:%U%q\tsize:%B\treferer:%{Referer}i\tua:%{User-Agent}i\treqtime_microsec:%D\tapptime:%D\tcache:%{X-Cache}o\truntime:%{X-Runtime}o\tvhost:%{Host}i" ltsv
```
Nginx
```
http { }に以下を追加
log_format ltsv "time:$time_local"
"\thost:$remote_addr"
"\tforwardedfor:$http_x_forwarded_for"
"\treq:$request"
"\tstatus:$status"
"\tmethod:$request_method"
"\turi:$request_uri"
"\tsize:$body_bytes_sent"
"\treferer:$http_referer"
"\tua:$http_user_agent"
"\treqtime:$request_time"
"\tcache:$upstream_http_x_cache"
"\truntime:$upstream_http_x_runtime"
"\tapptime:$upstream_response_time"
"\tvhost:$host";
access_log /var/log/nginx/access.log ltsv;
$ rm /var/log/nginx/access.log && systemctl reload nginx
$ alp --sum -r -f /var/log/nginx/access.log --aggregates='/keyword/.*'
```
## MySQL(SlowLogParse)
percona-toolkit
https://www.percona.com/downloads/percona-toolkit/LATEST/
```
MySQLにSlowLogを有効にする
/etc/mysql/mysql.conf.d/mysqld.cnf の[mysqld]部分を編集
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 0
log_queries_not_using_indexes = 1
systemctl restart mysql
systemctl restart (アプリ)
```
```
wget https://www.percona.com/downloads/percona-toolkit/3.0.4/binary/debian/xenial/x86_64/percona-toolkit_3.0.4-1.xenial_amd64.deb
sudo apt install libdbd-mysql-perl libdbi-perl libio-socket-ssl-perl libnet-ssleay-perl libterm-readkey-perl
sudo dpkg -i percona-toolkit_3.0.4-1.xenial_amd64.deb
sudo pt-query-digest --limit 10 /var/log/mysql/slow.log
```
## MySQL(profiler)
myprofiler
https://github.com/KLab/myprofiler/releases/download/0.2/myprofiler.linux_amd64.tar.gz
```
wget https://github.com/KLab/myprofiler/releases/download/0.2/myprofiler.linux_amd64.tar.gz
tar zxf myprofiler.linux_amd64.tar.gz
sudo install ./myprofiler /usr/local/bin
sudo myprofiler -user=root -interval=0.2
```
# チューニング前の準備(目標1時間)
- 公開鍵の登録
- 鍵で接続できることを確認するまで、一度接続したものは接続しっぱなしにすること
- ユーザ作成と鍵の登録はansible化済み(yamada-h)
- アプリコード, DB, 設定ファイル(nginx等)をプライベートリポジトリへアップ
- 初期状態に戻せるように、ディレクトリ丸ごとリポジトリに上げる
- gitignore で * で丸ごと無視指定し、必要なディレクトリやファイルだけ ! で指定
- /home/isucon (アプリ実装など)
- /etc (OS、ミドルウェアの設定)
- DBのバックアップ
- MySQLならmysqldumpで
- ツール類のインストール
- アプリの仕様を読み解きながら各自の専有環境を構築
- ローカルベンチがないと専有環境で作業しても結果確認が厳しそうなので、ユーザーを分けるくらいにする
# Todo
* DBのボトルネック解析ツールが欲しい
* ベンチマークはキューイングされそうならミニマムなものを作れたら作る
* https://qiita.com/bonon0/items/577b8f03525e99439b6c
# Tips
## MySQL
* MySQLのパスワードなしにする設定
https://qiita.com/komatsubara/items/95383e68d8959db97a78
MySQL 5.7からrootの初期設定がパスワードありになって、ISUCON5のansibleが流れなかった。
* レコード数を一覧表示したい
※正確ではない※
https://qiita.com/tomohiko_isobe/items/6efff247484f8e4fccae
全DBの全テーブル
```
mysql> select table_name, table_rows from information_schema.TABLES;
```
DBごと
```
mysql> select table_name, table_rows from information_schema.TABLES where table_schema = 'DB名';
```
## SSH
* ssh-agentをsudoしても使いたい
```Defaults env_keep += "SSH_AUTH_SOCK"```
`/etc` の管理をするため。
# 最適化の経緯
## friends_mapの改善
https://github.com/yamada-h/isucon5_home/commit/eae80e375ee355f21c310e51a23ef4513f077a1d
```
done
success
288.2
{"success"=>278, "redirect"=>102, "failure"=>1, "error"=>0, "exception"=>0}
```
## gunicornのworker数を4に
https://github.com/yamada-h/isucon5_etc/commit/5e5d91a2dfaec9fecb5aa2b75bbcdcc718d3ea5c
```
done
success
677.6
{"success"=>657, "redirect"=>206, "failure"=>1, "error"=>0, "exception"=>0}
```
## 実は更新していないテーブルがあった
ベンチを回して show table status を見れば一撃(Update_timeがNULL)
```
% grep -rE "(INSERT|insert)" *
app.py: query = "INSERT INTO footprints (user_id, owner_id) VALUES (%s, %s)"
app.py: query = "INSERT INTO profiles (user_id, first_name, last_name, sex, birthday, pref) VALUES (%s, %s, %s, %s, %s, %s)"
app.py: query = "INSERT INTO entries (user_id, private, body) VALUES (%s, %s, %s)"
app.py: query = "INSERT INTO comments (entry_id, user_id, comment) VALUES (%s, %s, %s)"
app.py: db_execute("INSERT INTO relations (one, another) VALUES (%s, %s), (%s, %s)",
% grep -rE "(UPDATE|update)" *
app.py: query = "UPDATE profiles " \
% grep -rE "(DELETE|delete)" *
app.py: db_execute("DELETE FROM relations WHERE id > 500000")
app.py: db_execute("DELETE FROM footprints WHERE id > 500000")
app.py: db_execute("DELETE FROM entries WHERE id > 500000")
app.py: db_execute("DELETE FROM comments WHERE id > 1500000")
+--------------------+
| Tables_in_isucon5q |
+--------------------+
| comments |追加、削除あり
| entries |追加、削除あり
| footprints |追加、削除あり
| profiles |追加、削除、更新あり
| relations |追加あり
| salts |不変
| users |不変
+--------------------+```
```
## friends_mapをRedisに載せた
https://github.com/yamada-h/isucon5_home/pull/3/files
get_friends()は上手く動かなかったのでrevert
https://github.com/yamada-h/isucon5_home/commit/c0271cd7b38f00c5d8a0a3a0390dbc2ad5f89088
```done
success
908.2
{"success"=>882, "redirect"=>262, "failure"=>1, "error"=>0, "exception"=>0}
```
## friends_mapをpreloadするようにした
```
done
success
975.0
{"success"=>947, "redirect"=>280, "failure"=>1, "error"=>0, "exception"=>0}
```
## userをRedisに載せた
https://github.com/yamada-h/isucon5_home/pull/4
```
done
success
1021.0
{"success"=>991, "redirect"=>300, "failure"=>1, "error"=>0, "exception"=>0}
```
## get_friends()をキャッシュから取るようにした
https://github.com/yamada-h/isucon5_home/pull/7
キャッシュを落としてなかったからPOSTしたやつが反映されなくてfailしてた
https://github.com/yamada-h/isucon5_home/pull/8
```
done
success
1239.6
{"success"=>1204, "redirect"=>356, "failure"=>1, "error"=>0, "exception"=>0}
```