KUOLC ISUCON部
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # ISUCON10予選 [TOC] ## レギュレーション https://isucon.net/archives/54753430.html ## マニュアル https://gist.github.com/progfay/25edb2a9ede4ca478cb3e2422f1f12f6 ## スプレッドシート https://docs.google.com/spreadsheets/d/1RCrOuT6_eLdR11_adWrWJMCm7cozexnHPEG1nUb-ElU/edit?usp=sharing ## bench `./bench --target-url http://35.72.103.176` ## botを弾く /ISUCONbot(-Mobile)?/ /ISUCONbot-Image\// /Mediapartners-ISUCON/ /ISUCONCoffee/ /ISUCONFeedSeeker(Beta)?/ /crawler \(https:\/\/isucon\.invalid\/(support\/faq\/|help\/jp\/)/ /isubot/ /Isupider/ /Isupider(-image)?\+/ /(bot|crawler|spider)(?:[-_ .\/;@()]|$)/i ``` location / { if ($http_user_agent ~ \ISUCONbot(-Mobile)?\) { return 503; } proxy_pass http://app; } ``` ## 接続情報 ### ssh ``` Host isuutil HostName 13.230.129.93 User ubuntu IdentityFile ~/.ssh/isucon7q-sshkey.pem ServerAliveInterval 60 Host isubench HostName 13.113.185.7 User ubuntu IdentityFile ~/.ssh/isucon7q-sshkey.pem ServerAliveInterval 60 Host isucon1 HostName 35.72.103.176 User ubuntu IdentityFile ~/.ssh/isucon7q-sshkey.pem ServerAliveInterval 60 Host isucon2 HostName 35.73.89.21 User ubuntu IdentityFile ~/.ssh/isucon7q-sshkey.pem ServerAliveInterval 60 Host isucon3 HostName 35.76.49.129 User ubuntu IdentityFile ~/.ssh/isucon7q-sshkey.pem ServerAliveInterval 60 ``` ### 内部IP - isucon1: 172.31.6.74 - isucon2: 172.31.9.97 - isucon3: 172.31.10.52 ## 事前 - [ ] Elastic IPを登録しておく - [ ] AWSインスタンス作成時にダウンロードした鍵を共有しておく - isucon-sshkey.pemで~/.sshに保存 - chmod 600 ~/.ssh/isucon-sshkey.pem - [ ] ~/.ssh/configの設定 - [ ] 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 --> - [ ] 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): インストール - [x] fixture追加 競技中 - [ ] <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> - [x] GOMAXPROCS設定 - [x] measure仕込む - [x] pprofのハンドラー準備 - [x] mysqlの接続確立 - [x] sqlxの差し替え - [ ] 400/500のエラーが出た場合にログに出力するようにする 競技中 - [ ] スローログのダイジェストを見て遅い/多いクエリの分析、改善 - [ ] MySQLのパラメータチューニング 競技終了 - [ ] pprof削除 - [ ] measure削除 ### ryunosuke 競技開始 - [ ] 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 <appname> # 必要に応じて.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の権限設定) - [ ] 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に追加 ### 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

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully