# 15. Performance Design and Test ________________________________________ サーバ構築の実際がわかる Apache[実践]運用/管理 http://gihyo.jp/book/2012/978-4-7741-5036-9 Amazon Web Services負荷試験入門 クラウドの性能の引き出し方がわかる https://gihyo.jp/book/2017/978-4-7741-9262-8 バックアップと障害復旧から考えるOracle Database, MySQL, PostgreSQLの違い https://cosol.jp/techdb/2020/05/backup_oracle_mysql_postgresql/ ________________________________________ ## 1. Performance Design ________________________________________ ### 1.1. スパイクとI/O限界 負荷想定計算式 ```text 平坦なアクセスが予想されるサービスの場合の初期設定 1日当たりのアクセス数 / 86400秒 * ピーク係数3 * 余力2 集中するタイミングがある程度わかっている場合:10分 そのタイミングのアクセス母数 / 600秒 * ピーク係数3 * 余力2 * 要約すると、推定平均の6倍を見込んで初期設定しておく * 稼働後は実際にピークを確認し、調整していく ``` Random QD1 MB/s |Storage|MB/s for 4KiB rr|MB/s for 4KiB rw |-------|----------------|---------------- |HDD | 0.5- 2.0 | 0.5- 2.0 |SSD |30.0-50.0 | 60.0-140.0 |SSD M.2|35.0-60.0 |150.0-170.0 - ストレージ自体(HDD、SSD共通)の特性 ```text - シーケンシャルリードに関しては、先読み(該当部分の後続も予め読んでキャッシュする)機能がある - ランダムリードの場合、先読みしても意味がないので、先読みを有効にしてもIOは改善しない ``` ストレージとDBの現実 ```text 1. トランザクションログはコミットに同期し、ファイルを常にフラッシュするとする 2. Hdd読み取り&書き込みが以下の仮定の元だと250回/s。4ms - 回数が4KiBで最小単位(=4Kセクタ)等速 - 速度が1MiB/s 3. 同様の計算をssdの場合40MiB/sと仮定すると、40倍、10000回/s、0.1ms 4. DBのトランザクションログ(redoログ)はコミットのたびに1~2度書き込まれる(SELECTはFOR UPDATEしてなければ対象外) - Oracle : REDOログへ1度 - Mariadb : InnoDBログ、binログへ1度ずつ - Postgres : REDOログへ1度 - トランザクションログ、レプリケーション、一貫性/非一貫性バックアップの詳細は、製品ごとに考え方や戦略が異なるため、各製品を熟知すること - 例:Mariadbは非一貫性バックアップが可能だが、それを復旧する手段がない。また、リカバリポイントを検証する仕組みもない ``` 典型的な処理性能補足 ```text B1msの典型的なopecacheされたphp7のappサーバは40rpsぐらい出る(処理なしで80~140rpsぐらい) ・1sql=1トランザクションログ(mariadbは2回)書き込み ・PHPは、処理によっては一切ファイルIO・ネットワークIOなしになりうる ・RDBは、最終的にREDOログのようなファイル書き込みがネックになる ``` 典型的なボトルネック ```text ・同期処理の別サービスへのネットワークレイテンシ ・WANレイテンシ > HDDストレージIO >> VMのLANレイテンシ・SSDストレージIO > その他 ``` ________________________________________ ### 1.2. レイテンシ item |time -----------------------------|----------------- 東京ソウル光速往復 | 7.6ms 1/60s |16.7ms 関東内平均https初回確立 |40.0ms ~ 120.0ms 関東内平均RTT |20.0ms 動的ページ推奨処理総和(※) |50.0ms (※)keep alive時の動的ページTTFB-静的ページTTFBで算出可能 ________________________________________ ### 1.3. forループとCPU ```text CPU :Core i5-4590 3.30GHz(4コア) exe :C# 1G 空forループ 結果:約40秒。単コアしか使われないため使用率は25% ``` ________________________________________ ### 1.4. RDBとパフォーマンスの裏側 1. 同期コミットにおけるlog書き込み速度上限(ストレージ速度上限) 2. メモリサイズとデータキャッシュ(メモリバッファ上限) 3. レプリケーション(リードレプリカ) 3. 垂直分割と水平分割 #### 1.4.1. 同期コミットにおけるlog書き込み速度上限(ストレージ速度上限) ```text 前述の通り。同期コミットの場合の限界速度はHDDでは250回/秒を目安か なおWeb+DB vol.41(2007年)の実測サンプルでは、MySQL5は400回/秒程度は出るらしい またSSDなら理論値で40倍、様々なネットの情報を見比べるとCPUの頭打ちがなければ15倍~20倍は出るとのこと ``` #### 1.4.2. メモリサイズとデータキャッシュ(メモリバッファ上限) https://yakst.com/ja/posts/3983 ```text 潤沢なメモリがない環境下では、クエリで参照するデータがメモリに展開できる量を超えてしまうため、バッファの恩恵を受けられない 2007年当時は物理メモリも小さかったため100万行程度のデータでもストレージからの再ロードが発生してしまう問題があったが、2024現在は潤沢であるためこの問題は出にくい 上記URLの例では、16GB物理メモリーでinnodb_flush_method=O_DIRECT、innodb_buffer_pool_size=12GB これならば1行100Byte*1000万行=1GBなので丸ごと10個は乗る ``` #### 1.4.3. レプリケーション(リードレプリカ) ```text 読み取りが問題な場合は、リードレプリカを用意すれば解決可能 ``` #### 1.4.4. 垂直分割と水平分割 https://engineering.linecorp.com/ja/blog/line-manga-database ```text 最終的に書き込み限界が来た場合、垂直分割や水平分割を考える 垂直分割は、単に関連のないテーブル同士を別DBにして別統治することである 水平分割は、同じテーブルを特定の期間や分類によって保存先を分けてしまうことである(別名:シャーディング) 現在の主要なRDBは、単純なシャーディングをPartition機能で対応できる。ID範囲でシャーディングする、日付基準でシャーディングするなど ``` ________________________________________ ## 2. Load Test Supplement ________________________________________ Throughput ```text RPS : Request per second. TPS : Transaction per second. PV/s : PV per second. ``` Response speed ```text Latency : One way. RTT : Round trip time. Server processing time + two way TAT : Turn around time. Client processing time + rtt ``` Point for good performance ```text Network & disk i/o is low. Memory is not empty. Cpu is high. ``` top -d2 ```text top - <現在時刻> <ログイン中のユーザ数> <1分平均負荷> <5分平均負荷> <15分平均負荷> Tasks:<総数> <実行中> <予約・休眠中> <停止> <ゾンビ> %CPU(s):<ユーザー> <システム> <ユーザー(優先度明示)> <完全未使用> <ハードウェア割り込み> <ソフトウェア割り込み> KiB Mem : <総数> <使用中> <未使用> <予約・キャッシュ等> KiB Swap: <総数> <使用中> <未使用> <予約・キャッシュ等> 平均負荷 = TASK_RUNNINGだが未実行 + TASK_UNINTERRUPTIBLE = 処理したいができないタスク数 ``` チェックシート ```text 1. 基本的な想定は算出できているか - ユーザー数 - ユーザー数と用途から導かれる瞬間風速 - 1日の平均転送データ量 - スパイク(ニュース・広告・キャンペーン起因の超アクセス) 2. 負荷試験攻撃側は十分か - 負荷試験中にPCのCPUやメモリに余力があるか - 負荷試験中にブラウザを開いていつも通りに開けるか - 過剰な負荷を掛けると、Googleやプロバイダに弾かれます 3. 負荷試験される側の環境は本番と同じか - 同じCluod上の同じプランを利用しているか 4. 負荷試験の負荷の掛け方は適切か - 適切な同時アクセスを行えているか - 適切にリクエストを行い、レスポンス内容は正しいか 5. 負荷試験対象を細分化したか - ノード単体に対して負荷試験を行なったか - SSLなしで負荷試験を行ったか - SSLありで負荷試験を行ったか - 静的ファイル(htmlなど)で負荷確認を行ったか - 単純な動的処理(hello world)の負荷試験を行ったか - 外部連携がなくDB更新のない動的ページ(php)の負荷試験を行ったか - 外部連携がなくDB更新のある動的ページ(php)の負荷試験を行ったか - 外部連携部分の動的ページ(php)の負荷試験を行ったか - DBに対して負荷試験を行ったか - バランサ全体に対して負荷試験を行ったか ```