ISUCONの過去問で毎回毎回セットアップをするのはめんどくさいのでまとめてみた。ISUCONは初心者なので色々わかり次第追記していく。
参考: https://github.com/isucon/isucon7-qualify
AMIを自前で準備
# ubuntu@16.04 LSTで作成 sshでログイン
# nginxとmysql(RootUserで実行)
sudo su
apt-get update
apt-get install mysql-server nginx # Password設定するの勧めてくるけど全部OK
# Apllicationを設定
sudo adduser isucon
gpasswd -a isucon sudo
sudo su - isucon
cd ~
git clone https://github.com/isucon/isucon7-qualify.git isubata
# xbuild関連をInstall
sudo apt install -y git curl libreadline-dev pkg-config autoconf automake build-essential libmysqlclient-dev libssl-dev python3 python3-dev python3-venv openjdk-8-jdk-headless libxml2-dev libcurl4-openssl-dev libxslt1-dev re2c bison libbz2-dev libreadline-dev libssl-dev gettext libgettextpo-dev libicu-dev libmhash-dev libmcrypt-dev libgd-dev libtidy-dev
git clone https://github.com/tagomoris/xbuild.git
# GolangのインストールとPath設定
mkdir local
xbuild/go-install -f 1.9 /home/isucon/local/go
mkdir go
echo 'export GOROOT=/home/isucon/local/go' >> ~/.bashrc
echo 'export GOPATH=/home/isucon/go' >> ~/.bashrc
echo 'export PATH=/home/isucon/local/go/bin:$PATH' >> ~/.bashrc
echo 'export PATH=/home/isucon/go/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
# ベンチマーカーのBuild
go get github.com/constabulary/gb/...
cd /home/isucon/isubata/bench
gb vendor restore
make
# 初期データを準備
cd /home/isucon/isubata/bench
./bin/gen-initial-dataset
# DBのセットアップ
sudo /home/isucon/isubata/db/init.sh
sudo mysql
# mysqlの内部
CREATE USER isucon@'%' IDENTIFIED BY 'isucon';
GRANT ALL on *.* TO isucon@'%';
CREATE USER isucon@'localhost' IDENTIFIED BY 'isucon';
GRANT ALL on *.* TO isucon@'localhost';
exit;
# データの投入
zcat /home/isucon/isubata/bench/isucon7q-initial-dataset.sql.gz | sudo mysql isubata
# nginx設定
sudo cp /home/isucon/isubata/files/app/nginx.* /etc/nginx/sites-available
cd /etc/nginx/sites-enabled
sudo unlink default
sudo ln -s ../sites-available/nginx.conf
sudo systemctl restart nginx
# ApplicationのBuildと設定
sudo cp /home/isucon/isubata/files/app/*.service /etc/systemd/system
sudo vim /home/isucon/isubata/files/app/env.sh #DBのHostをlocalhostに書き換える
sudo cp /home/isucon/isubata/files/app/env.sh /home/isucon/
cd /home/isucon/isubata/webapp/go
make
sudo systemctl enable isubata.golang
sudo systemctl enable nginx
セットアップ
初期設定
SSH設定
メンバーの分のSSHを設定する。
/home/isucon/.ssh/authorized_keys
にPublicKeyを追記。
pbcopy < ~/.ssh/id_rsa.pub
mkdir /home/isucon/.ssh
touch /home/isucon/.ssh/authorized_keys
echo '[PUBLIC_KEY]' >> /home/isucon/.ssh/authorized_keys
Processの確認
ps auxwf # | grep Nginx
Github
GithubにPrivate Repositoryを作成してPushしておく。ついでにDeployスクリプトも作成しておく。
cd /home/isucon/isubata
rm -fr .git
git init
git add .
git commit -m "first commit"
git remote add origin [git repository]
git push -u origin master
# ブランチを最新に
git checkout master
git fetch
git pull origin master
# build
cd /home/isucon/isubata/webapp/go
make
# confファイルと環境変数を更新
cp /home/isucon/isubata/files/app/env.sh /home/isucon/
cp /home/isucon/isubata/files/app/nginx.* /etc/nginx/sites-available
cp /home/isucon/isubata/files/db/mysqld.cnf /etc/mysql/my.cnf
#/home/isucon/isubata/files/db/mysqld.cnfのlog_slow_queriesは間違いなので気をつける。
# 参考: https://dev.mysql.com/doc/refman/5.6/ja/server-system-variables.html
# ログを削除
rm -fr /var/log/nginx/access.log
rm -fr /var/log/mysql/access.log
# Restart
systemctl restart mysql
systemctl restart nginx
systemctl restart isubata.golang
chmod 777 /home/isucon/isubata/deploy.sh
/home/isucon/isubata/deploy.sh
監視系ツール
ボトルネックを特定するために必須。全ての参加者が導入していると思われるので、サクッとやりたい。大きく分けて3種類。
CPリソース監視系
CPU, RAMなどの使用量を監視するもの。
htop
sudo apt-get install htop
Nginx監視系
Nginxなどのログを監視する。特定のPathに対して負荷がかかってい他場合の特定に役に立つ。
alp
# nginx設定の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;
wget https://github.com/tkuchiki/alp/releases/download/v0.3.1/alp_linux_amd64.zip
apt install unzip
unzip alp_linux_amd64.zip
mv alp /usr/local/bin/
alp -f /var/log/nginx/access.log
Application監視系
pt-query-digest
参考: https://www.percona.com/doc/percona-toolkit/LATEST/pt-query-digest.html
wget https://www.percona.com/downloads/percona-toolkit/3.0.13/binary/debian/xenial/x86_64/percona-toolkit_3.0.13-1.xenial_amd64.deb
sudo dpkg -i percona-toolkit_3.0.13-1.xenial_amd64.deb
sudo dpkg -s pt-query-digest
# Pattern1
tcpdump -s 65535 -x -nn -q -tttt -i any -c 10000 port 3306 > mysql.tcp.txt
pt-query-digest --type tcpdump mysql.tcp.txt >> query-report.txt
# Pattern2
mysql
# mysqlの内部
SHOW VARIABLES;
SET GLOBAL slow_query_log_file='/var/log/mysql/access.log';
SET GLOBAL slow_query_log=1;
SET GLOBAL log-queries-not-using-indexes=1;
exit;
pt-query-digest --type genlog /var/log/mysql/access.log
slow_query_log_file = /var/log/mysql/mysql-slow.log
slow_query_log
# long_query_time = 2
log-queries-not-using-indexes
pprof
import (
_ "net/http/pprof"
"net/http"
)
func main() {
// DefaultはCPU計測
go http.ListenAndServe(":3000", nil)
...
}
sudo apt-get install graphviz gv
# ./bin/main = 実行ファイル cpu.pprof = pprofファイル
go tool pprof -png ./bin/main cpu.pprof > out.png
ISUCONでやれそうなこと
ブログなどの情報を見ながらこれなら自分にもできそうと思ったものをまとめてみる。
N+1問題
基本形。どれだけ早く特定できるかが鍵。見つけるだけでなく、多く叩かれているところを優先的に潰す。重いQueryなども発見して潰せるようなら潰していきたい。
DB周り
Index(複合Indexまで視野に入れて)などを貼ってみる。
Nginx設定
静的ファイルをCacheするなど。他にもConnectionsやWorkerの数を増やすなど。色々いじれる。
Redis導入/オンメモリ化
重いQueryなどをメモリに載せたい。
複数台構成
Nginxをロードバランサーとして用いて複数台構成にする。複数にすることで発生する問題もあるので行う場合には慎重にやりたい。
DBの非正規化
これも多少ハードルが高い。時間の短いisuconであれば、難しいかも。サマーインターンのもので時間があるものであれば試そうかと思う。
参考
ISUCON7 予選
https://blog.bitjourney.com/entry/2017/11/09/101740