問題文を熟読し、スキーマ/アプリをざっくり把握! SQL 使ってるとこ抜き出しとかしてもいいかもね。
https://www.tweeeety.blog/entry/20140121/1390275336
access_log を出す
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;
- https://kazeburo.hatenablog.com/entry/2014/10/14/170129
- ここら辺参考資料によってかなり違うので要検討
$ cat /etc/nginx/nginx.conf
worker_processes 1;
events {
worker_connections 10000;
}
http {
include mime.types;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
etag off;
; アプリケーションがUNIXドメインソケットであれば
upstream app {
server unix:/dev/shm/app.sock;
}
server {
location / {
proxy_pass http://app;
}
location ~ ^/(stylesheets|images)/ {
open_file_cache max=100;
root /home/isucon/webapp/public;
}
}
}
- https://diary.sorah.jp/2017/10/23/isucon7q によると
add_header Cache-Control "public, max-age=86400";
とかclient_max_body_size 20M;
とかもあっていいかも?worker_processes auto;
worker_rlimit_nofile 4096;
keepalive_timeout 120s;
とかもあるかも- https://qiita.com/ihsiek/items/11106ce7a13e09b61547 にはたくさんあるのでここら辺検討してもいい
sudo nginx -s reload
とかsudo service nginx restart
で再起動忘れずに!
[mysqld]
slow_query_log=1
slow_query_log_file=’/var/lib/mysql/slow.log’
long_query_time=0.1
もしくは
set global slow_query_log=1;
set global slow_query_log_file=’/var/lib/mysql/slow.log';
set global long_query_time=0.1;
log-queries-not-using-indexes
はなくていいと思う
$ cat /etc/my.cnf
innodb_buffer_pool_size = 1G
innodb_flush_log_at_trx_commit = 0
innodb_flush_method=O_DIRECT
sudo service mysqld restart
とかで再起動
SELECT table_name, engine, table_rows, avg_row_length, floor((data_length+index_length)/1024/1024) as allMB, floor((data_length)/1024/1024) as dMB, floor((index_length)/1024/1024) as iMB FROM information_schema.tables WHERE table_schema=database() ORDER BY (data_length+index_length) DESC;
$ cat /etc/sysctl.conf
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.ip_local_port_range = 10000 65000
net.core.somaxconn = 32768
net.core.netdev_max_backlog = 8192
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10
fs.file-max = 100000
もありかもcat /etc/sysctl.d/99-sysctl.conf
のパターンもあるsudo /sbin/sysctl -p
とかで反映
tcp-keepalive 60
save 900 1
save 300 10
save 120 20000
maxclients 10000
appendonly yes
appendfsync everysec
no-appendfsync-on-rewrite no
以下のようなスクリプトで再起動しつつスローログなど移動するの大事 設定ファイルの更新後再起動忘れがちなので注意
set -ex
if [ -f /var/lib/mysql/mysqld-slow.log ]; then
sudo mv /var/lib/mysql/mysqld-slow.log /var/lib/mysql/mysqld-slow.log.$(date "+%Y%m%d_%H%M%S")
fi
if [ -f /var/log/nginx/access.log ]; then
sudo mv /var/log/nginx/access.log /var/log/nginx/access.log.$(date "+%Y%m%d_%H%M%S")
fi
sudo systemctl restart mysql
# sudo service memcached restart
sudo systemctl restart nginx
http://naoberry.com/tech/slowquery/
- ロック待ちは
long_query_time
の算出時間に含まれない
[mysqld]
slow_query_log=1
slow_query_log_file=’/var/lib/mysql/slow.log’
long_query_time=0.1
long_query_time
は 0.1 くらいがいいのではないか(持論)
set global slow_query_log=1;
set global slow_query_log_file=’/var/lib/mysql/slow.log';
set global long_query_time=0.1;
- インストール方法など https://thinkit.co.jp/article/9617
pt-query-digest /var/log/mysql/mysql-slow.sql
でとりあえず OK
- 基本 pt-query-digest でいいが、使えなかった場合こっちでも代用できる
mysqldumpslow /var/log/mysql/mysql-slow.sql
でとりあえず OK
- インストール方法など
- いろんな情報の出し方(最も CPU を使っているプロセスなど)
- https://hirose31.hatenablog.jp/entry/20120229/1330501968
dstat --top-cpu --top-cputime
- 出力の見方
if [ -x /usr/bin/dstat ]; then
alias dstat-full='dstat -tclmdrn'
alias dstat-mem='dstat -tclm'
alias dstat-cpu='dstat -tclr'
alias dstat-net='dstat -tclnd'
alias dstat-disk='dstat -tcldr'
fi
dstat-full --output /home/hoge/dstat_
date "+%Y-%m-%d".csv
オプション | 説明 |
---|---|
t | 時間表示 |
T | epoch time 表示する |
c | CPU 使用率 |
l | ロードアベレージ |
m | メモリ使用量 |
r | IO 回数 |
n | ネットワーク IO(単位は B/s) |
d | Disk IO |
c | CPU 使用率 |
アクセスプロファイラ http://kazuki229.hatenablog.com/entry/2017/09/29/003314
cat /var/log/nginx/access.log | alp ltsv
アクセスプロファイラ。今回は alp でいいかなと思うが一応。 https://github.com/matsuu/kataribe
wget https://github.com/matsuu/kataribe/releases/download/v0.4.1/kataribe-v0.4.1_linux_amd64.zip -O kataribe.zip
unzip -o kataribe.zip
sudo mv kataribe /usr/local/bin/
sudo chmod +x /usr/local/bin/kataribe
rm kataribe.zip
kataribe -generate
import (
_ "net/http/pprof"
)
go func() {
log.Println(http.ListenAndServe("0.0.0.0:6060", nil))
}()
- png で結果を吐き出す
GO111MODULE=on go tool pprof -png -output pprof.png http://localhost:6060/debug/pprof/profile
- WebUI 情報量が多いので良さそう
GO111MODULE=on go tool pprof -http=":8888" http://localhost:6060/debug/pprof/profile
- すでに一回実行するとファイルが生成されるのでそれ指定してもいい
GO111MODULE=on go tool pprof -http=":8888" /Users/miyamura-koyo/pprof/pprof.samples.cpu.005.pb.gz
sudo yum install graphviz
しないと動かないかも
- すでに一回実行するとファイルが生成されるのでそれ指定してもいい
- go のプロファイラ pprof を利用してパフォーマンスを計測する (GAE + gin もあり)
- https://chidakiyo.hatenablog.com/entry/go-pprof-gae-and-gin
- webapp なので
_ "net/http/pprof"
を import するのがラクそう
- Go のプロファイラを使おう! その1
- http://tech.innovation.co.jp/2018/09/10/Go.html
- web app のようにシグナルで実行停止するやつだとこれではうまくいかなさそうなので上記の Web 版の方がいい
- 見方の参考に
- ISUCON9 過去問
- ISUCON9 予選問題の解説と講評 : ISUCON 公式 Blog http://isucon.net/archives/53789931.html
- ISUCON9 予選 1 日目で最高スコアを出しました https://to-hutohu.com/2019/09/09/isucon9-qual/#%E5%BD%93%E6%97%A5
- ISUCON8 本選出題記 あるいは ISUCON ベンチマーカー負荷調整の歴史 - 酒日記 はてな支店 https://sfujiwara.hatenablog.com/entry/2018/10/25/084543
- ISUCON8 予選問題の解説と講評 : ISUCON 公式 Blog http://isucon.net/archives/52520045.html
- 死闘の果てに ISUCON 8 予選を全体7位で突破した記録 https://qiita.com/najeira/items/527e1f54fa417fd20b65#measure
- https://github.com/najeira/measure
- ↑ ある範囲だけの関数呼び出しログだけ知りたいならこれでも良さそう
- Linux サーバにログインしたらいつもやっているオペレーション
- https://blog.yuuk.io/entry/linux-server-operations
- top コマンドの使い方とか全般で困ったことあれば
- 再起動試験忘れるのあるあるなので、最後はそれ
- HTTP/2 にする
- 問題によっては難しい場合もある
- 複数台構成
- DB サーバを分けるのが定番
- 変わり種としては重い API だけ特定のサーバに振り分けるとかもあるっぽい
- bcrypt みたいな特定の重い処理を緩和する
- コスト(ストレッチング回数) 減らしていいんなら減らす
- MySQL コネクションを使い回す
- N+1
- メモリにのせる