# ISUCON11予選 [TOC] ## レギュレーション https://isucon.net/archives/55854734.html ## マニュアル 当日マニュアル https://gist.github.com/ockie1729/53589a0e8c979198b6231d8599153c70 アプリケーションマニュアル https://gist.github.com/ockie1729/fcb41ade9cb9d2166dd3f53e5179e8a9 ## スプレッドシート https://docs.google.com/spreadsheets/d/1Gj_ul5c92KPyKWNuYqQtDKNmRPCTgzOaDp1V0nPsdEY/edit?usp=sharing ## 接続情報 ### ssh ``` Host isuutil HostName 13.230.129.93 User ubuntu IdentityFile ~/.ssh/isucon7q-sshkey.pem ServerAliveInterval 60 Host isucon1 HostName 54.199.41.247 User ubuntu IdentityFile ~/.ssh/isucon7q-sshkey.pem ServerAliveInterval 60 Host isucon2 HostName 35.75.46.176 User ubuntu IdentityFile ~/.ssh/isucon7q-sshkey.pem ServerAliveInterval 60 Host isucon3 HostName 52.68.31.229 User ubuntu IdentityFile ~/.ssh/isucon7q-sshkey.pem ServerAliveInterval 60 ``` ### 内部IP - isucon1: 192.168.0.11 - isucon2: 192.168.0.12 - isucon3: 192.168.0.13 ## 事前 - [ ] Elastic IPを登録しておく - [x] AWSインスタンス作成時にダウンロードした鍵を共有しておく - isucon-sshkey.pemで~/.sshに保存 - chmod 600 ~/.ssh/isucon-sshkey.pem - [ ] ~/.ssh/configの設定 - [x] isucon[X]-qualifyレポジトリを空で作成しておく - `git@github.com:isucon-kuolc38th/isucon(X)-qualify.git` <!-- - テンプレート準備 - local - pprof - results - tools - .gitignore - docker-compose.yml - (各自)クローンし、ローカルで諸々のセッティングをしておく - VSCode - Github Desktop - (要検討)これらはサーバー内に用意されている方を踏襲したほうがよさそう? - mysql - nginx - env.sh --> - [x] isucon[X]-qualify-utilレポジトリを作成し、各自Pullして動作確認を済ませておく - `git@github.com:isucon-kuolc38th/isucon(X)-qualify-util.git` ## 初期構成 - isucon1 - Nginx - App - isucon2 - 何もなし - isucon3 - (Redis) - MySQL ## AWS - [ ] EC2でインスタンス作成→マシンイメージ選択で指定されたAMIを選択 - [ ] インスタンスタイプを選択 - [ ] ボリュームはSSDで16GB(インスタンスタイプによって変わるかも) - [ ] セキュリティグループの設定 - 「すべてのTCP」、ソースに「0.0.0.0/0」を指定 - 「すべてのICMP」、ソースに「0.0.0.0/0」を指定 - セキュリティグループはあらかじめ作成しておいたものを使うのが良い - [ ] キーペアにisucon-sshkeyを指定 - [ ] インスタンスが起動したら、Elastic IPのページからインスタンスに事前に用意したElastic IPを紐付け - [ ] それぞれの名前をつける ## タイムスケジュール |timetable|all|rkoike|cojiro|ryunosuke| |--|--|--|--|--| |00:00 競技開始||||| ||マニュアル確認<br>初期ベンチ回す(レコード数確認)<br>アプリ触ってみる<br>レポジトリPush・各自クローン|||| |00:20 作業開始||||| |||レポジトリPull<br>マシンセットアップ<br>Nginx(ログ含む)<br>MySQL(ログ含む)<br>App (GOインストール)<br>netdata|Appの初期設定|ALPのグルーピング<br>コードリーディング<br>仕様の整理<br>ボトルネックの洗い出し| ||(ここまでの目標)<br>スクリプトからデプロイできるようになっている<br>pprof, measure, ALPのデータが1回ずつ取れている<br>ボトルネックの洗い出し・タスク分割がある程度完了している|||| |01:30 改善開始||||| ||大幅な改修を行うかどうかの決定<br>仕様・ボトルネックの共有と把握<br>タスクの割り振り|||| |||Nginxの設定チューニング<br>Staticファイルのキャッシュ設定<br>ベンチマーク分析<br>インフラ最適化|MySQLの設定チューニング<br>インデックス作成<br>SQLクエリ改善|メインボトルネック解消<br>影響範囲の広いApp改善<br>変更のないデータのオンメモリ化| |05:00 メインボトルネック解消||||| |||ベンチマーク分析<br>インフラ最適化<br>時間のある時に再起動試験|影響範囲の狭いApp改善|使用頻度の高いデータのオンメモリ化| |07:00 提出準備||||| ||再起動試験|netdata無効化<br>MySQLログ無効化<br>Nginxログ無効化|measure無効化|安全な(?)App改善<br>ボーダーが遠い場合にワンチャンかける| - 仕様把握の上でmeasureのデータがいち早く欲しいので、GOへのアプリ切り替えとmeasureの仕込みが終わった時点ですぐベンチを回すこと - 役割分担 - rkoike: インフラ構成の変更に伴う実作業、netdataなどを用いたハード面の(CPU/メモリ/IO/ネットワーク)ボトムアップ分析を担当。カーネルチューニングや、余裕があればNginxのチューニングも行う - cojiro: SQLクエリの改善などボトムアップな改善を担当(ログの分析も含む) - ryunosuke: 大幅な改修を含むアプリのトップダウンな改善を担当 ## チェックリスト ### 全体 競技前 - [x] ベンチ準備 - [x] 空repo作成 - [x] util環境作成 - [x] repo - [x] インスタンス - [x] Remote Desktop - [x] スプレッドシート作成 - [x] Elastic IP作成 競技開始 - [ ] 初期ベンチ - [ ] ベンチ前のレコード数を記録 - [ ] ベンチ後のレコード数を記録 競技中 - [ ] メインベンチ - [ ] pprofファイル取得 - [ ] measureのstatsをスプレッドシートに記録 - [ ] ログ類をフェッチ 競技終了 - [ ] 再起動試験 - ベンチ実行 - 再起動 - ブラウザからアクセスしてアプリが正しく動くか - ベンチのデータが正しく保存されているか - もう一度ベンチ実行して同様のスコアが出るか ### rkoike 競技開始 - [ ] <a href="#Git">レポジトリへのコードプッシュ</a> - [ ] 初期構成のセットアップ - [ ] <a href="#セットアップ">nginx</a> (isucon1): インストール、ログの設定、appとの接続 - [ ] app (isucon1): Goの最新版インストール、PATH設定、appとの接続 - [ ] <a href="#セットアップ1">mysql</a> (isucon3): ログの設定 - [ ] netdata (isucon1): インストール 競技中 - [ ] <a href="#監視コマンド">ツールを用いたハード面のボトルネック分析</a> - netdata, netstat, vmstat, htop - [ ] カーネルチューニング - [ ] app, nginx, mysqlのファイル上限 - http://blog.father.gedow.net/2016/03/28/limits-of-systemd/ - [ ] tw_reuseなどのカーネルパラメータ設定 - [ ] (unix socket) - [ ] <a href="#設定のチューニング">nginxのパラメータチューニング</a> - [ ] 静的ファイル(キャッシュ, gzip_static) - [ ] proxy_cache - [ ] keepalive - [ ] 再起動試験 競技終了 - [ ] ログの切り替え - nginx - mysql - [ ] 不要なプロセス停止 - netdata ### cojiro 競技開始 <a href="#セットアップ2">セットアップ手順</a> - [ ] GOMAXPROCS設定 - [ ] measure仕込む - [ ] pprofのハンドラー準備 - [ ] mysqlの接続確立 - [ ] sqlxの差し替え - [ ] 400/500のエラーが出た場合にログに出力するようにする 競技中 - [ ] スローログのダイジェストを見て遅い/多いクエリの分析、改善 - [ ] MySQLのパラメータチューニング 競技終了 - [ ] pprof削除 - [ ] measure削除 ### ryunosuke 競技開始 - [ ] sql -> sqlx - [ ] ALPのグルーピング - [ ] スプレッドシートに仕様をまとめる - [ ] キーポイント - [ ] エンドポイント一覧 - [ ] SQLスキーマ - [ ] コードの読み込み 競技中 - [ ] 大幅なアプリの改修 - [ ] インメモリ化 競技終了 - [ ] 頑張る ## 作業マニュアル ### マニュアル確認 ### ベンチマーク ### Git #### SSH Key登録 ``` bash mkdir ~/.ssh cd ~/.ssh && ssh-keygen cat id_rsa.pub ``` - [ ] isucon[X]で名前をつける - [ ] Write権限にチェックを入れること #### 初回Push - [ ] SSH Key登録 ``` bash cd ~/<apphome> git config --global user.name "isucon[1-3]" git init git remote add origin git@github.com:isucon-kuolc38th/isucon[X]-qualify.git # 必要に応じて.gitignoreをいい感じに編集 git add . git commit -m "initial setup" git push origin master ``` #### 初回Pull - [ ] SSH Key登録 ``` bash cd ~ mv <apphome> <apphome>_backup git clone git@github.com:isucon-kuolc38th/isucon[X]-qualify.git git config --global user.name "isucon[1-3]" ``` フォルダをマージする場合 `rsync -av isucari_repo/ isucari/` ### Nginx #### インストール - [ ] `sudo apt install nginx` #### セットアップ - [ ] 設定をgit管理下にコピー ``` bash cd ~/<apphome> sudo mkdir /etc/nginx_backup sudo cp -r /etc/nginx /etc/nginx_backup mkdir -p ./isucon[1-3]/nginx/config sudo cp -r /etc/nginx/* ./isucon[1-3]/nginx/config ``` - [ ] 初期実装サービスの停止 ``` bash # Apache sudo apachectl stop sudo service httpd stop # h2o sudo systemctl stop h2o sudo systemctl disable h2o ``` - [ ] appのIPアドレス設定 ``` http { upstream app { server app:8080; } location / { proxy_set_header Host $http_host; proxy_pass http://app; } } ``` - [ ] ログの設定 - nginx.conf - (/var/log/nginxの権限設定) - sudo chmod -R 644 /var/log/nginx - sudo chmod 757 /var/log/nginx - [ ] Nginxサービスの`start`と`enable` #### 設定のチューニング http://nginx.org/en/docs/ https://qiita.com/iwai/items/1e29adbdd269380167d2#use-epoll デフォルトで設定するもの - worker_processes - sendfile, tcp_nopush, tcp_nodelay - keepalive_timeout too many file opensが出た時 - worker_rlimit_nofile - worker_connections ファイルの読み書きが多い場合 - open_file_cache 接続数が多い場合 - keepalive_requests - 接続数が多い時はある程度大きめの値にしておいて良い? - upstream.keepalive - location.proxy_http_version, location.proxy_set_headerも忘れずに設定する 静的ファイル - gzip_static - 同じディレクトリにあらかじめgzipファイルを作っておく - gzipはCPUを使うのでonにしないほうがいい? - クライアントキャッシュが効く場合 -> max-age - 効かない場合 -> proxy_cache ### MySQL #### インストール ``` bash sudo apt install mysql-server mysql-client ``` #### セットアップ - [ ] 設定をgit管理下にコピー ``` bash cd ~/<apphome> sudo mkdir /etc/mysql_backup sudo cp -r /etc/mysql /etc/mysql_backup mkdir -p ./isucon[1-3]/mysql/config sudo cp -r /etc/mysql/* ./isucon[1-3]/mysql/config ``` - [ ] ログの設定 - 設定が効いているか確認: `SHOW VARIABLES LIKE "general_log%";` - ログファイルの所有権変更 `sudo chown mysql:mysql /var/log/mysql` - ログファイルが作成された後、読み取り権を付与 `sudo chmod 777 /var/log/mysql/*` ``` my.cnf [mysqld] log_output=FILE general_log=1 general_log_file=/var/log/mysql/query.log slow_query_log=1 slow_query_log_file=/var/log/mysql/slow_query.log log_error=/var/log/mysql/error.log long_query_time=0.2 log_queries_not_using_indexes=1 ``` - [ ] MySQLサービスの`start`と`enable` ``` bash sudo systemctl start mysql [mariadb] sudo systemctl enable mysql [mariadb] ``` - [ ] (要検討)初期実装がmysql以外の時のスキーマやデータのコピー方法 #### データのdump ``` bash mysqldump -u user db > data.sql mysqldump -u user --no-data db > schema.sql sftp isucon[1-3] /home/isucon/data.sql ./ sftp isucon[1-3] /home/isucon/schema.sql ./ ``` #### 設定のチューニング MySQL5.6.8以降とそれまででデフォルト値が違うので注意 https://dev.mysql.com/doc/refman/5.6/ja/server-system-variables.html https://tetsuyai.hatenablog.com/entry/20111006/1317873012 https://qiita.com/mamy1326/items/9c5eaee3c986cff65a55 ##### 優先的に確認する項目 - max_connections, thread_cache_size - 接続数に応じてチューニング? - query_cache_type - 結果が変わらないクエリを何回も実行する時は効果があるが、それ以外では無効にする - innodb_buffer_pool_size - 物理メモリの8割に設定 - max_heap_table_size, key_buffer_size, innodb_log_file_size, innodb_log_buffer_size - メモリに合わせて設定? - innodb_buffer_pool_dump_at_shutdown, innodb_buffer_pool_load_at_startup - 設定しておくことで起動を速くできる ##### 設定項目一覧 ### Redis https://github.com/shirokanezoo/isucon4-qualifier-sorah/blob/master/redis.conf #### インデックス最適化 - WHERE ORはUNIONにする ```sql SELECT * FROM items WHERE seller_id = ? OR buyer_id = ? -------------------------------------------------- SELECT * FROM items WHERE seller_id = ? UNION SELECT * FROM items WHERE buyer_id = ? ``` ### systemd `/etc/systemd/*`を編集し,appで`<appdir>/isucon[1-3]/env.sh`を読むようにする ### App #### セットアップ - [ ] Go最新版に入れ替え ``` bash cd ~/local wget https://golang.org/dl/go1.16.5.linux-amd64.tar.gz rm -rf go tar -xzf go1.16.5.linux-amd64.tar.gz rm go1.16.5.linux-amd64.tar.gz ``` - [ ] PATHを通す - `export PATH=$PATH:$HOME/local/go/bin` - `vim ~/.bashrc`をして`PATH=`に`$HOME/local/go/bin`を追記 - [ ] `<apphome>/isucon[1-3]/env.sh`を読むように設定 ``` bash cd ~/<apphome> touch ./isucon[1-3]/env.sh sudo vim /etc/systemd/system/<service_name> # [Service] # EnvironmentFile=<apphome>/isucon[1-3]/env.sh ``` - [ ] 実装切り替え - 他の言語実装を`stop`と`disable` - Golang実装を`start`と`enable` - [ ] GOMAXPROCS - `runtime.GOMAXPROCS(runtime.NumCPU())`をinitに追加 - [ ] エラー出力 ``` e.Use(middleware.Recover()) e.HTTPErrorHandler = func(err error, c echo.Context) { log.Println(err) e.DefaultHTTPErrorHandler(err, c) } ``` - [ ] sqlをsqlxに差し替える - sqlx.DB -> sql.DB - sql.Open -> sqlx.Connect - [ ] DB接続確立 ``` go for { var err error db, err = sqlx.Connect("mysql", dsn) if err == nil && db.Ping() == nil { break } log.Println(err) time.Sleep(time.Second * 3) } ``` ### netdata ``` bash bash <(curl -Ss https://my-netdata.io/kickstart.sh) all --dont-wait ``` ### measure https://github.com/najeira/measure インストール ``` go get github.com/najeira/measure ``` 使い方 ```go import "github.com/najeira/measure" // 測定 func hoge() { defer measure.Start("hoge").Stop() } // リセット (initializeに書く) measure.Reset() // 結果取得用ハンドラ (echoの場合) e.GET("/stats", echo.WrapHandler(http.HandlerFunc(measure.HandleStats))) ``` `/stats`にアクセスし、結果を右クリック>stats.csvで保存 ### pprof 使い方 https://christina04.hatenablog.com/entry/golang-pprof-basic ```go import "net/http/pprof" // echo e.Group("/debug/pprof").Any("/cmdline", echo.WrapHandler(http.HandlerFunc(pprof.Cmdline))) e.Group("/debug/pprof").Any("/profile", echo.WrapHandler(http.HandlerFunc(pprof.Profile))) e.Group("/debug/pprof").Any("/symbol", echo.WrapHandler(http.HandlerFunc(pprof.Symbol))) e.Group("/debug/pprof").Any("/trace", echo.WrapHandler(http.HandlerFunc(pprof.Trace))) e.Group("/debug/pprof").Any("/*", echo.WrapHandler(http.HandlerFunc(pprof.Index))) // goji mux.HandleFunc(pat.Get("/debug/pprof/cmdline"), pprof.Cmdline) mux.HandleFunc(pat.Get("/debug/pprof/profile"), pprof.Profile) mux.HandleFunc(pat.Get("/debug/pprof/symbol"), pprof.Symbol) mux.HandleFunc(pat.Get("/debug/pprof/trace"), pprof.Trace) mux.HandleFunc(pat.Get("/debug/pprof/*"), pprof.Index) ``` ベンチマーク中に、稼働しているサーバーに対してローカルで次を実行 ``` bash // CPU curl -s http://<ip>/debug/pprof/profile?seconds=60 > cpu.pprof // メモリ curl -s http://<ip>/debug/pprof/heap?seconds=60 > memory.pprof ``` ローカルで結果表示 ``` bash go tool pprof -http=localhost:8080 *.pprof ``` Webでの閲覧にはgraphvizのインストールが必要 ``` bash brew install graphviz ``` <!-- ### ローカル環境 #### セットアップ - [ ] isucon-templateのdocker-compose.ymlのコメントアウトを編集 - [ ] appのフォルダ - [ ] DBの環境変数 - [ ] MySQLの変数 - [ ] local/publicにpublicをコピー - [ ] local/nginx/config/nginx.confを編集 - [ ] appのupstream - [ ] staticファイル - [ ] local/mysql/initの各SQLファイルを編集 - [ ] 00_setup.sqlにユーザー作成処理を書く - [ ] 01_schema.sqlにスキーマを書く --> ### キャッシュ ### ベンチマーク分析 #### pt-query-digest `pt-query-digest slow_query.log` ``` # 290ms user time, 20ms system time, 30.93M rss, 4.13G vsz # Current date: Sun Aug 8 13:38:02 2021 # Hostname: iwairyuunosukenoMacBook-Pro.local # Files: slow_query3.log # Overall: 749 total, 5 unique, 11.70 QPS, 1.77x concurrency _____________ # Time range: 2021-07-18 11:46:31 to 11:47:35 # Attribute total min max avg 95% stddev median # ============ ======= ======= ======= ======= ======= ======= ======= # Exec time 113s 63us 3s 151ms 672ms 310ms 119us # Lock time 4s 5us 2s 5ms 63us 82ms 23us # Rows sent 2.21M 0 187.74k 3.02k 28.75 22.97k 21.45 # Rows examine 51.66M 18 563.26k 70.62k 182.98k 105.89k 26.08 # Query size 53.27k 36 191 72.83 183.58 53.37 34.95 # Profile # Rank Query ID Response time Calls R/Call V/M # ==== =================================== ============= ===== ====== ==== # 1 0xC622688A0CBAF834501E39FDEB19B588 39.9824 35.2% 82 0.4876 0.06 SELECT reservations # 2 0x2B1DC7423E71BCFAC6BE997CA53B4627 39.3838 34.7% 82 0.4803 0.06 SELECT reservations sheets events # 3 0x6DDCECAE12499086677CFFB2A33F9691 22.7544 20.1% 12 1.8962 0.19 SELECT reservations events # 4 0xCB340AA6D46DFD09CF116CE1265D110C 11.1799 9.9% 82 0.1363 0.02 SELECT reservations # MISC 0xMISC 0.1547 0.1% 491 0.0003 0.0 <1 ITEMS> # Query 1: 1.39 QPS, 0.68x concurrency, ID 0xC622688A0CBAF834501E39FDEB19B588 at byte 31538 # This item is included in the report because it matches --limit. # Scores: V/M = 0.06 # Time range: 2021-07-18 11:46:32 to 11:47:31 # Attribute pct total min max avg 95% stddev median # ============ === ======= ======= ======= ======= ======= ======= ======= # Count 10 82 # Exec time 35 40s 187ms 877ms 488ms 740ms 171ms 501ms # Lock time 0 1ms 6us 42us 13us 27us 7us 11us # Rows sent 0 400 0 5 4.88 4.96 0.77 4.96 # Rows examine 29 15.02M 187.33k 187.75k 187.53k 182.98k 0 182.98k # Query size 19 10.56k 130 132 131.84 130.47 0.68 130.47 # String: # Databases torb # Hosts ip-172-31-16-197.ap-northeast-1.compute.inte... # Users isucon # Query_time distribution # 1us # 10us # 100us # 1ms # 10ms # 100ms ################################################################ # 1s # 10s+ # Tables # SHOW TABLE STATUS FROM `torb` LIKE 'reservations'\G # SHOW CREATE TABLE `torb`.`reservations`\G # EXPLAIN /*!50100 PARTITIONS*/ SELECT event_id FROM reservations WHERE user_id = 2209 GROUP BY event_id ORDER BY MAX(IFNULL(canceled_at, reserved_at)) DESC LIMIT 5\G ``` #### 監視コマンド https://qiita.com/aosho235/items/c4d6995743dd1dac16e1 |コマンド|用途|収録パッケージ| |--|--|--| |vmstat 2|システム全体の負荷を見るならこれ。2で2秒ごと|procps| |top|CPUやメモリを食っているプロセスを特定したいならこれ|procps| |sar|過去の負荷の履歴をみたいならこれ|sysstat| |mpstat -P ALL 1|CPUコアごとの負荷を見るならこれ|sysstat| |dstat -taf|標準ではインストールされていないが、一番便利なコマン|dstat| |free -m|メモリ。-mでメガバイト単位|procps| |iostat -dmxt 1|IO状況|sysstat| ##### sar https://qiita.com/muijp/items/956ac41c4cf6cf85ae12 sar -u CPU使用率 sar -q ロードアベレージ sar -r メモリ利用状況 sar -W スワップ発生状況 sar -n ネットワークトラフィック sar 1 1000 で1秒毎に1000回レポートする。 ##### htop ### 再起動試験対策 #### AppのDB接続 ``` go for { var err error db, err = sqlx.Connect("mysql", dsn) if err == nil && db.Ping() == nil { break } log.Println(err) time.Sleep(time.Second * 3) } ``` #### initialize ``` go func initialize() { ClearCache() // DBロード処理 } func getInitialize() { ... initialize() } func main() { ... initialize() } ``` ### 掃除 - [ ] MySQLログ無効化 - [ ] Nginxログ無効化 - [ ] Appログ無効化 - [ ] Redisログ無効化 - [ ] netdata無効化 - `systemctl stop & disble` - [ ] measure削除 - `github.com/najeira/measure`をインポートから外して関連コードを削除 - [ ] pprof削除 <!-- ## 以下未整理(項目ごとに上の作業マニュアルに入れていく) - [ ] 与えられたディレクトリ構成に合わせてこの資料を編集 - (要検討)3台で別々のamiインスタンスが渡された場合のテンプレ ## 当日やること(ツール類の整備) ### 計測ツール検討中 - [ ] AWS X-Ray ## その他のツールやコマンド ### alp ``` bash wget https://github.com/tkuchiki/alp/releases/download/v1.0.3/alp_linux_amd64.zip apt install unzip unzip alp_linux_amd64.zip sudo mv alp /usr/local/bin/ rm alp_linux_amd64.zip ``` ### 初期実装切り替え #### init.d ``` bash sudo chkconfig <service> on/off sudo service <service> start/stop ``` #### systemd ``` bash sudo systemctl enable/disable <service> sudo systemctl start/stop <service> ``` #### supervisord vim /etc/supervisord.conf ``` [<service>] ... autostart: true/false ``` ``` supervisorctl restart ``` ### 更新 & ベンチ ``` bash cd <apphome> git pull origin master ps -aux | grep app sudo kill <pid> cd app && make build make run & cd ~/webapp && ./tools/benchmark.sh # Running benchmark... vim results/initial_score # TODO: 自動化 git add * git commit -m "initial_score" git push origin master ``` --> ## Trouble Shooting ### Nginxで権限問題 - 迷ったら`nginx.conf`にはrootユーザーを書くのが無難 - 「13: Permission denied」[参考リンク](https://itips.krsw.biz/nginx-fail-port-forward-13-permission-denied/) ``` bash sudo setsebool httpd_can_network_connect on -P sudo chmod 701 /home/isucon sudo systemctl restart nginx ``` - 「SELinuxの無効化」[参考リンク](https://qiita.com/hanaita0102/items/5d3675e4dc1530b255ba) ``` bash # 一時的に無効化 setenforce 0 # 永続的に無効化(要サーバー再起動) # vi /etc/selinux/config SELINUX=enforcing ``` ### MySQLで権限問題 ``` bash sudo chmod 755 -R /var/log/mysql # git add できない sudo chmod 755 -R isucon3/mysql/config ``` ### MySQLで外部サーバーから接続できない #### ERROR 2003 (HY000): Can't connect to MySQL server on 'x.x.x.x' (111) https://ameblo.jp/mojeld/entry-12645669164.html ```my.cnf # bind-address = 127.0.0.1 bind-address = 0.0.0.0 ``` #### ERROR 1130 (HY000): Host x.x.x.x is not allowed to connect to this MySQL server https://fantasiabaetica.hatenablog.com/entry/2019/07/12/081848 ``` GRANT ALL PRIVILEGES ON *.* TO 'isucon'@'%' WITH GRANT OPTION; ``` ### Redisで権限問題 ``` sudo chown redis:adm -R /var/log/redis sudo chmod 755 /var/log/redis ``` ### サーバー間通信でno route to host - pingは通るがcurlは通らない ``` sudo systemctl stop firewalld sudo systemctl disable firewalld ``` ### worker_rlimit_nofileをあげてもtoo many open filesが解決しない ``` bash ulimit -Sn 4096 ps aux | grep nginx cat /proc/<pid>/limits ``` /etc/systemd/system/multi.target/nginx.service ``` [Service] LimitNOFILE=65536 ``` ### deploy.shでPermission Denied - `go build isucon-kuolc38th/isucon4-qualify: copying /tmp/go-build3899013241/b001/exe/a.out: open golang-webapp: permission denied` 実行ファイルに777 ```bash chmod 777 ./golang-webapp ``` - restart.shが実行できない restart.shに777 ```bash chmod 777 <apphome>/isucon[1-3]/restart.sh ``` ### Can't assign request address sudo sysctl -w net.ipv4.ip_local_port_range="10240 61000" # 32768 61000 sudo sysctl -w net.ipv4.tcp_tw_reuse="1" netstat -an |grep TIME_WAIT |wc ### unix socket https://kaneshin.hateblo.jp/entry/2016/05/29/020302 ### 書き込みのバックグラウンド実行 https://github.com/methane/isucon4q-go/blob/b09d45adb0c08616fe14d02acd801496befa3bd6/db.go#L89-L110 ## やる必要があるかもしれないこと - [ ] my.cnfの読み込み優先度が高いものが入ってないか確認 - [ ] ` mysql --help | grep .cnf`の場所にファイル実体があればそれも読み込まれることを意識 - mysqlコマンドで`defaults-extra-file`オプションがあればそれも入る - 候補は以下の通り 1. `/etc/my.cnf` (git管理済み) 1. `/etc/mysql/my.cnf` (git管理済み) 1. `SYSCONFDIR/my.cnf` 1. `$MYSQL_HOME/my.cnf` 1. `--defaults-extra-file=path` 1. `~/.my.cnf` 1. `~/.mylogin.cnf` ## Reference - Nginx+MySQL+カーネルチューニングレシピ https://kazeburo.hatenablog.com/entry/2014/10/14/170129