ISCON本を読んだ
tags:2022-07-14
ToC
なにを学ぶか
- パフォーマンスチューニングの流れが、どの手順で行われることがあるのか説明できる
- nginxの設定の何を変更すべきかわかっている
- MySQLのindexをいつどういう基準で使えば良いかわかっている
1章メモ
- ボトルネックになりがちなのはCPU,メモリ、ディスクIO,ネットワークIO
- データの入出力の外側からみていくのが大事
2章メモ
- 負荷試験を行うClientは対象のサーバの外に出すこと
- なるべく本番のアーキテクチャに近づけるのが肝要
- プロファイルの解像度には適切な値がある。例えば5秒ごとにメトリクスを取ると、1秒で変化して1秒で戻るような現象をキャッチできない
- この足りていない状態は解像度が足りないとかいう
- 解像度を上げると負荷が上がるので調整が必要
- コードのどこで時間が掛かっているかを測定するものを「ラインプロファイラと呼ぶ」
3章メモ
実際にprivate-isuを動かすパート。構築された環境に学びがあるので書いていく(isucon関係ない内容もあるけど)
全体の内容としてはログなどからアプリの情報を集める工程について述べられている
- docker-php-ext-install は、installと有効化を行うコマンド
- peclで入れたものはdocker-php-ext-enableで有効化する必要がある
- composer install --no-devは本番環境向け(--devオプションもある)
- require-devにあるpackageのinstall及び、autoload-devをskipする
- nginxのlog_formatはjsonにした方が見やすくて良い
- escape=jsonを指定すると、ダブルクォーととかが登場した時に適切にescapeしてくれる
- access_log /var/log/nginx/access.log json;はserverの中に書かないとデフォルトのlogと重複して出力されていた
- alpというjsonやLTSV形式のファイルをパースできるツールがある。Go製
- alp jsonを叩くとデフォルトで、method,uri,status,body_bytes,response_timeを集計してくれる
- ab(Appach Bench)というコマンドがあるそうな。Macの場合はデフォルトで入ってる
- 負荷試験ごとにlogファイルを分けて、それぞれをalpで解析する流れが良いらしい。
- アクセスログのローテーションってやつ
- topのCPU表記は、%Cpu(s)が全CPUコアを100としたもので、%CPUは1コアを100としたもの
- MySQLのボトルネック解析
- my.cnfのlong_query_timeは、指定した秒数以上のqueryを出す。0にすると全部出る
- 長いのがダメかと思いきや、回数が多すぎてもダメなのでそういう意味でもパフォチューの時は全部出すんだとか
- mysqlのslowログは、mysqldumpslowコマンドを使うと、実行時間の長いクエリから順に表示してくれる
- 呼び出し回数も見れて良い
- SHOW CREATE TABLE {テーブル名}で、そのテーブルを作るのに必要なSQLが見れる
- indexのないcolumnをwhereの条件に入れるとfull scanが走る
- EXPLAinで
- keyがnull、indexなし
- rowsの数が対象の行数
- topで全体の負荷でどこが重いかわかるといいなぁ
- 並列度は、CPU数の倍ぐらいに設定して良いこともある
- これはidleになるprocessがいると勿体無いため。5倍ぐらいにした例もあるとか
4章メモ
- skip
5章メモ
- MySQLのqueryの最後を\Gにするか;にするかで、queryの結果の表示が縦と横で変わる
- ExtraにUsingFilesortとあると、sort処理が走っている
- post_idとcreated_atの複合indexを作ると、sortする処理が省ける
- backward scanと出る場合は、昇順indexを逆向きに読んでいるということなので、降順indexに変えると改善する
- index指定で
add index xxx(column DESC);
とすれば良いようだ
- index指定で
- Extraがnullになると余計な条件が減る
- セカンダリインデックスは、プライマリインデックス
- indexのイメージはsort済みのDB
- クラスターインデックス
- プライマリインデックスのツリー構造の先にデータがあ含まれている
- プライマリインデックス以外は全部セカンダリインデックスとよび、ツリー構造の先にプライマリキーが含まれている
- order by狙いのindexにしていると、日付の新しいものから探される。新しいものの方がアクセスされる可能性が高いので、読み込んだ行数が減ることが期待できる
- explainの結果、using indexとなっているとindexが参照される
- indexのアンチパターン
- 増やしすぎると更新が重くなる
- 全文検索のindex
- n-gramや形態素解析によるindexの作成が可能
- 通常LIKE検索では%や_の前しか見れない。前方一致じゃないとindexが効かないんじゃわ
- N+1はjoinや、非正規化で解消できる
- FORCE INDEXでどのindexを使うか指定することができる
- STRAIGHT JOINを使うとqueryの順番にindexが使われる
6章メモ
- リバプロの意義とnginxについて
- リバースプロキシは静的ファイルの配信を行なってApp鯖の負荷を軽減したり、TLS終端したりできる
- nginxの設定は複数のserverの設定を行うことができて、それはserver{}の中に書く
- locationにpathを書くことで静的ファイルが配信できる
- root $pathで対象のpathをfullpathで指定する
- expiresの指定でファイルをcacheするようだ
- proxy_set_header Host $host;とすることで、リバプロに来たヘッダを流せる
- gzipによる圧縮が行えるかは、リクエストのHTTPヘッダにAccept-Encoding: gzipがあるかどうからしい
- 最近のブラウザなら必ず入っているんだとか
- nginxにもモジュールがあり、ngx_http_gzip_static_moduleを使うと事前に圧縮したファイルを使えるようになるんですって
- application鯖で圧縮できるならその方が良い
- keepaliveの設定で、受け付ける最大のrequest数を指定できる
- try_filesは左から順に見ていってあれば使う
- query stringに毎回違う値を入れてcacheを破棄できる
- これはlaravel-mixとかがやってる
- 「jpegやpngは既に圧縮されているので二重圧縮しない」ように注意
語彙メモ
- 水平スケール・垂直スケール
- インスタンスのスペックを上げるのが垂直。数を増やすのが水平
振り返り
- パフォーマンスチューニングの流れが、どの手順で行われることがあるのか説明できる
- まずは計測
- その後ボトルネックを一つずつ潰していく
- 時間のかかっている箇所は、CPUの使用率の高いプロセスだったり、responseまでの時間だったりから見つける
- nginxの設定の何を変更すべきかわかっている
- gzip圧縮の有無、log_formatのjson化、staticファイルの配信について覚えた
- MySQLのindexをいつどういう基準で使えば良いかわかっている
- where句で指定するものにはindexを貼ると良い
- 貼りすぎると逆にinsert時の性能が低下する
- indexはsort済みのtableを作るようなもの、という例えがわかりやすかった
- created_atのような日付を指定するとorder byが高速になるほか、降順でindexしておくと最新のものほど早くアクセスされるので走査対象が減ることを覚えた
- where句で指定するものにはindexを貼ると良い