Amazon Web Services負荷試験入門の読書記録

# はじめに

<img width="150" alt="Amazon Web Services負荷試験入門" src="https://image.gihyo.co.jp/assets/images/cover/2017/9784774192628.jpg">

[Amazon Web Services負荷試験入門](https://gihyo.jp/book/2017/978-4-7741-9262-8)

こちらの本はAWS（クラウド）環境での負荷試験のやり方や評価の仕方、またその際の選択肢となるツールの紹介まで一通りまとめてくれています。これ一冊読めば、負荷試験をやったことがない人でもある程度の作業イメージが付くのではないかと思います。
私自身も、今まで負荷試験自体を実施した経験はなかったのだが、一度読み終えたあとはイメージすることができるくらいにはなったと感じます。本来はもう一周くらいしたい気持ちではあるが、ひとまず現段階での備忘録を下記にまとめておこうと思います。

# 備忘録

## はじめの用語系

- 荷試験は可用性を担保する手段の一つ
- 可用性
    - システムがサービスを正常に提供できる状態のこと
    - 常にサービスを利用できるシステムを可用性の高いシステムという
- 堅牢性とは別の概念
    - 堅牢性：データの欠損が発生しないことを示す数値
- 可用性の高いシステムに必要なこと
    - システムを冗長化する
    - システムをスケール対応する
- システムの冗長化
    - 冗長化：単一障害点をなくすこと

## 負荷試験の基礎知識
オンプレ時代に行っていた負荷試験では、「目的性能を提供するための必要なハードウェア選定」という側面もあった。しかし、クラウド時代では、リソース調達が容易になったため、その目的も薄れてきており、少し変わって来ている。

- クラウド時代の負荷試験
    - システムがスケール性を持つことを確認する
    - システムのスケール特性を把握する
        - スケール特性とは、どこの部分を増強すれば性能が向上するか
    - スケール特性を把握するときに具体的に把握しておくこと

把握しておくべきスケール特性として重要だと感じたポイントは下記。
- スループットを2倍にしたいときに、どうすべきかを把握
- 半分にしたいときは何を削減すればよいのか
- webサーバーだけで良いのか、DBも増強するのか
- サービスを停止せずに構成の変更ができるか？
- どれくらい時間がかかるか、など

基礎知識としてシステム速度についての定義もまとめておく。
- システム速度
    - スループット
        - 例：単位時間あたりに目的地に到着する車の数
        - ネットワーク帯域：ネットワーク上のデータ転送速度
        - ネットワーク帯域幅：最大スループット
    - レイテンシ
        - 例：目的地までの所要時間
        - 応答時間のこと
            - レイテンシは観測者によって変わってくるので、どの観測者から見たものかを意識する必要がある
            - ユーザーから見た観測時間と、システムからみた観測時間
                - ユーザーはネットワーク時間を含む
- システム性能改善とは
    - システム全体のスループットを向上させてレイテンシを低下

## 負荷試験ツール
- 紹介されていたツールは下記
    - Apache Bench
    - Apache JMeter
    - Locut
    - Tsung

上記のツールのうち、「Apache Bench」以外は複数台のサーバーから攻撃可能とのこと。より高密度な負荷をかけたい場合には、複数台のサーバーに対応したツールを選ぶとよいかと思う。

- 負荷試験の注意（本番環境との違い）
    - 攻撃側のネットワーク帯域が食って、本番想定の負荷にならない
    - DNSがキャッシュしてしまい、本番の動きと差異が発生
    - 長時間の負荷をかける耐久試験ではツール側の確認が必要

特に攻撃ツール側の確認は大事だと感じた。性能が低く見ていたが、実際は攻撃ツール側が要件を満たせていない、攻撃側のネットワークで詰まっていて実際はほとんど負荷が掛けられていない、というケースが発生する簡単に想像が付く…

## モニタリングやプロファイリング
モニタリングツールやプロファイリングツールを導入すると、それ自体が負荷になる可能性がある。そのため、ツールの有無を切り替えて両方のパターンで結果を比較することが必要。

- モニタリングツールの紹介（コマンドもあり）
    - top, netstatコマンド
    - AWS管理コンソール
    - Xhprof
    - New Relic

下記は、それらのモニタリングツールを使用するときにモニタリングしたい項目。

- モニタリングしたい項目
    - ネットワーク（転送量）
    - ハードウェアやOS（CPU, メモリ, プロセス数、SWAP, Load Average）
    - TCP（外部へのコネクション状況：ESTABLISHやFIN, WAIT）
    - ディスク（IOPS、R/W転送データ量）        
    - サーバーミドルウェア（コネクション数）
    - アプリケーション（プロファイラーの監視）
    - Mysql（Slow Query、Process List）

サービス単位での項目は下記のようなものが挙げられていた。
- ELB：RequestCount、レイテンシ    
- AutoScalingGroup：CPUUtilization
- EC2：CPUUtilization、Network I/O、DiscRriteOps
- RDS：CPUUtilization、Freeable Memory、ReadLatency/WriteLatency、SwapUsage、BurstBalance

## 負荷試験の計画

- 負荷試験の目的
    - ユースケースに応じたシステム応答性能を推測する
    - ハードウェアをあらかじめ選定する
- 前提条件の整理
    - 重要：想定数値と、確定した数値を明確にわけておく
    - 品質を保証する範囲を明確にしておく
    - 試験時にストレージに格納しておくデータ件数やサイズを決める
    - 最終的な目標値に対してどれくらいの期間を維持する必要があるか
    - どこのネットワークから負荷をかけるか
    - サーバーに同居する別システムの影響が発生する可能性の洗い出し
    - 本番環境と試験環境の差異による影響の確認
    - スループットの目標値
        - 下記がわかれば概算可能
            - A：1日の利用者数
            - B：1人あたりの1日の平均アクセス数
            - C：1日の平均アクセス数に対する最大ピーク時の倍率

## 負荷試験の実施
ボトルネックの洗い出しと原因の推測を行う。ボトルネック部分を特定できている状態を継続すべきである。システムの構成要素が増えるほどボトルネックの切り分けが困難になることは頭においておく。基本的には小さなステップのPDCAサイクルを繰り返すことを意識する。

クラウド時代では、ボトルネックの箇所をスケールアウトしながら、次のボトルネックを探す。システム性能がスケールアウトやスケールアップに追従して、改善することを確認していく。そして、今まで負荷がかかっていなかったシステムに対して負荷をかけて、それぞれをチューニングしていく。

ボトルネックだと思ったら実は他の場所がボトルネックだったというケースもあるので、注意が必要。また、ミドルウェアやカーネルパラメータの設定に問題があるケースもあるので、そちらもあわせて確認する。

最終的に確認したいことは下記の項目。
- 将来のリソース増強のためのマイルストーンを見積もる
- 試験結果が目標値をクリアしているか
- より高負荷になってもシステムがスケール性を持つか

途中で負荷がうまく掛からないなどの問題の場合は下記をチェック。
- ELBのウォームアップが完了しているか？
- 攻撃サーバーにグローバルIPが割り当てられずにNAT経由で攻撃している
- SSLを利用した負荷テストになっている    
- 攻撃ツールのアクセス数が少ないor多すぎる、レポートが詳細すぎる
- フレームワークの設定が想定外（Debug/Development）
- DB接続方法が適切でない
- SQLの質が悪い
- DBの問題（更新クエリが同じ行に集中している、ディスクI/Oのボトルネック）
- アプリケーションに問題（キャッシュ設計に問題がある、ログの転送先が詰まっている）

## 負荷試験レポートの作成
まずは下記の４つの確認を行い、最後に「目標値と前提条件をクリアしたか」を確認する。
- 試験対象システムに負荷が集中したか
- ボトルネック部分を特定できたか
- システムは正常にスケールしたか
- スケール特性を把握できたか

目標値に対する適正な構成を選定する。推奨インフラ構成は、下記２点の突き合わせで
- システムの目標性能を達成するため
- インフラコストを最適化するため

過不足のない最適なパターンを提案する。
- できるだけ、単一障害点を持たず、可用性を確保していること
- 当面想定される負荷に耐えうる構成であること
- 急激な負荷ピークにおける対策が示されていること
- 将来想定される負荷に退位して拡張方針が示されていること
- システムごとにある程度の余裕を取っていること

作成する負荷試験レポートは下記を意識すると良さそう。レポートに必要なことは「わかりやすさ」が大事だと述べられていた。
- 前提条件
- 試験目的
- 目標値
- 試験対象システムの概要
- 試験結果
    - 目標値をクリアするための構成
- システム性能評価
    - 目標の性能を出せるのか
    - 想定以上のリクエストが来たときにどうなるのか
    - 予想される今後の負荷増大に対するサーバーリソース増強ロードマップ
- システムの課題
- 付録：試験時の各リソースの利用状況など
    - 注意：膨大すぎてどれを見ればよいのかわからない


# 所感
負荷試験というと、頭の中ではどうしても大きいタスクとして考えてしまっていました。
確かに全体を俯瞰すると大きいタスクかもしれないですが、本書にかかれていたように、ポイントに絞って小さいタスクとしてPDCAを回すことを意識することが大事に感じました。

また、ボトルネックが存在する状態というのは、どうしてもマイナスなイメージではあったが、負荷試験の最中においてはボトルネックを見つけることはプラスなことで、ボトルネックを見つけて改善、そして次のボトルネックを見つけるという流れは負荷試験を進める上で、間違えていないという道標になるようにも感じた。ということで、前向きにボトルネックを探していきたいと思いました。