負荷試験入門公開資料 201611

Post on 18-Jan-2017

536 Views

Category:

Engineering

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

クラウドファーストにおけるWEBアプリケーション負荷試験実践入門

株式会社ゆめみ 仲川樽八

1. スライドの目的

• リリース前に負荷試験を行うことを当たり前にする

• 意味のある負荷試験を最短距離で行うための“段取り”を持ち帰って頂く

スライドの目的

2. 負荷試験の目的と心得

クラウドファーストの本質とは

スケールラブルなシステムが

容易かつ安価に構築できること

高負荷の時はスケールアウトする

Elastic Load Balancing

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

お金で解決する!

若干のメンテナンス時間さえ取れれば

スケールアップ出来る

RDS DB instancexlarge

RDS DB instance8xlarge

お金で解決する!

サービスの稼働状況に応じた

適切なリソースを金で買う時代!!

そう考えて負荷試験をしなかった、、、

CPU負荷 100%張り付き

LOCK WAIT TIMEOUT鳴り止まない電話

Load Ave. 900??

既に8XLARGE使ってます!!

終電って何?

媒体告知打っちゃったよ!!!

クラウドファーストにおける

負荷試験の目的は何でしょうか?

与えられた特定の条件下でのシステム

全体のスループットを最低保証すること。

例:「一時間で○○万人の応募を受け付けます!!」

という数字を保証すること。

クラウドファーストな負荷試験の目的

…ではありません。

最終的に必要であることはありますが、

最初にこれを目的にしようとするとまず失敗します。

クラウドファーストな負荷試験の目的

負荷試験で最低限担保できるのは、

・特定条件のベストエフォート時における処理能力

・対象システムがスケール対応しているかどうか

の2つです。

クラウドファーストな負荷試験の目的

クラウド時代における負荷試験とは、

システムの性能を担保する試験ではなく、

システムの機能を担保する試験

です。

負荷試験の心得

の前に、製品試験といえば、、、。

“よい数字が出るまで測定した”・・・

いいんです!

ここで、良い負荷試験の指標

良い負荷試験

•対象に充分な負荷がかかっている

•対象システムのリソースのいずれかが逼迫していること

•結果としてより高い性能が観測される

•結果のスループットがより高いこと

•結果のレイテンシが小さいこと(数十~数百Msec)

対象システムのリソースのいずれかが逼迫していること

負荷試験対象システムに対して充分な負荷がかかり、

対象システムのどこかのリソースが悲鳴を上げているのが良い負荷試験

です。

今何処に負荷がかかっているのかを

常に意識して下さい。 ここだよ!

(その結果として、)対象システムのスループットがより高いこと

スループット:単位時間あたりに処理可能なリクエスト数

これがユーザーの流入数より少なければレイテンシはどんどん増え

ていき、最終的にサービス提供が出来ない状態となります。

対象システムのレイテンシが小さいこと

レイテンシ:システム応答時間

負荷試験では、攻撃クライアント数を調整しながら、スループットが最

大で、レイテンシが充分小さい場所を探ります。

負荷試験とは、文字通り、

対象に負荷をかける試験です。

適切な負荷をかけ、その結果として、より高いスループットが計測されるように、負荷をかける事を邪魔する要因を排除

する事を繰り返します。

遠慮なく条件を変えながら、

“良い数字が出るまで測定”

を繰り返して下さい。

悪い負荷試験の例

悪い負荷試験の例

・SSL対応サイトなので、SSLを利用した負荷試験を行うべきだ

・ユーザーのユースケースを考慮して、海外のサーバから負荷試験を行おう

・完璧なユーザーシナリオを作り上げて試験を行おう(※複雑な判定の追加や、

実際に近いSleep処理の追加など)

・etc…

理由は後述します。

3. 負荷試験の段取り

やってはいけない

いきなり全体の負荷試験を行う

※「おお たるはち!しんでしまうとは ふがいない!

なぜしんだのかはわかってるのか?

負荷試験結果が芳しくない原因(例)

• 試験内容、方法に問題がある

• インフラに問題がある

• LBに問題がある

• ネットワークに問題がある

• ミドルウエア設定、カーネルパラメータ設定に問題がある

• アプリケーションに問題がある

• フレームワークに問題がある

• キャッシュ設計に問題がある

• ロジックに問題がある

• DBに問題がある

• 参照に問題がある

• 更新に問題がある

試験結果を元にあたりをつけてリファクタリングをしても、

その部分がボトルネックではなかった場合、そのリファクタリング結果

は負荷試験結果に反映されない。

リファクタリング前 リファクタリング後

部品A 部品B 部品C Total 部品A 部品B 部品C Total

部品Cにバグが有ったので、リファクタリングで部品Cの能力を3倍に!

全体のスループットは変わらない

例え最初の試験で目標値をクリアしていたとしても、その計測結果が

妥当かどうかがわからない。

部品A 部品B 部品C Total

目標スループット

試験結果スループット

攻撃サーバ能力

負荷試験

考えられる要因が沢山ありすぎて一つづつ潰すのは大変。

切り分けして原因を潰していける順序で負荷試験を行う。

→段取りが重要

4. 段取りに沿った負荷試験1ウォーミングアップ編

今回の負荷試験対象システム

負荷試験対象システム全体像

クラウド上でスケール可能なシステムを構成

Elastic Load Balancing

Availability Zone Availability Zone

RDS DB instance

RDS DB instance standby

(Multi-AZ)

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

• LAMP構成のシステム

• WEBアプリケーションサーバはLBの後ろに設

置されている

• 全てAZ(データセンター)をまたいだ形で設置

し、単一障害点はない

• キャッシュを利用

• DBはスケールアップで対応

ElastiCache

ElastiCache

Step.1 負荷試験ツールの試験を行う

Step.2 フレームワークに負荷をかける

Step.3 参照系システムに負荷をかける

Step.4 更新系システムに負荷をかける

段取りに沿った負荷試験

ウオーミングアップ編

つまり、負荷をかける対象を意識する

まず、どこまでの負荷をかける事ができるツールなのかを検証します。

Elastic Load Balancing

Availability Zone Availability Zone

RDS DB instance

RDS DB instance standby

(Multi-AZ)

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

ElastiCache

ElastiCache

Step1 負荷試験ツールの試験を行う

攻撃サーバ = 攻撃されるサーバ

Webサーバ1台だけ静的リソースファイルへのアクセス

※この時Localhostへの攻撃をするようにします。

EC2 instance

web appserver

Index.html

.html

Step.1 負荷試験ツールの試験を行う

静的ファイルに対する負荷試験をかける

リソースも逼迫していないのに結果が遅い時には負荷をかける方法がおかしいので、十分なスルー

プット(数千~数万rps)が出るまで調整する。

(※攻撃サーバがネットワーク的に遠い場合や攻撃ツールが最適化されていない場合などがありま

す。また、攻撃サーバのローカルポートが不足した時もエラーとして観測されます。)

負荷試験結果が芳しくない原因(例)

• 試験内容、方法に問題がある

• インフラに問題がある

• LBに問題がある

• ネットワークに問題がある

• ミドルウエア設定、カーネルパラメータ設定に問題がある

• アプリケーションに問題がある

• フレームワークに問題がある

• キャッシュ設計に問題がある

• ロジックに問題がある

• DBに問題がある

• 参照に問題がある

• 更新に問題がある

Step.2 フレームワークに負荷をかける

Elastic Load Balancing

Availability Zone Availability Zone

RDS DB instance

RDS DB instance standby

(Multi-AZ)

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

ElastiCache

ElastiCache

攻撃サーバ = 攻撃されるサーバ

EC2 instance

web appserver Webサーバ1台だけ

フレームワークの機能を利用した上で最低限のHellowWorldでの試験を行う

この時にまだ外部のリソースを利用しない

HellowWorld.php

.php

• 理論上の最速値が得られます

• 例えば

• LV1静的ファイルで10000RPS、HELLOWORLDで300RPS とかになった場合、

• 今後DBに接続した処理などが 400RPSとかには絶対にならないです。

• この時点でスループットが遅かったらフレームワークやミドルウエア、利用

ライブラリ等の見直しが必要になります。

Step.2 フレームワークに負荷をかける

負荷試験結果が芳しくない原因(例)

• 試験内容、方法に問題がある

• インフラに問題がある

• LBに問題がある

• ネットワークに問題がある

• ミドルウエア設定、カーネルパラメータ設定に問題がある

• アプリケーションに問題がある

• フレームワークに問題がある

• キャッシュ設計に問題がある

• ロジックに問題がある

• DBに問題がある

• 参照に問題がある

• 更新に問題がある

Step.3 参照系のシステムに負荷をかける

Elastic Load Balancing

Availability Zone Availability Zone

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

攻撃サーバ = 攻撃されるサーバ

EC2 instance

web appserver

.php

RDS DB instance

RDS DB instance standby

(Multi-AZ)

ElastiCache

ElastiCache

参照.php

Webサーバ1台だけ

DBに対して参照のみ行われるケースの試験

更新系のページの計測を行う前にこの計測を行うことで、更新ロックによるリソース競合が発生しにく

い状況での負荷試験を行えます。

このため、遅かった場合でも純粋なSlowQuery等の調査が行い易いです。

ここで参照系SQLの最適化やDBインデクスの見直し、キャッシュ利用ポリシーの見直しなどが行うこと

ができます。

※ここではまだDBに十分な負荷をかける事はできないかもしれませんが、この段階では大丈夫です。

後にまた充分な負荷がかかった状態の試験を行ないます。

Step.3 参照系のシステムに負荷をかける

負荷試験結果が芳しくない原因(例)

• 試験内容、方法に問題がある

• インフラに問題がある

• LBに問題がある

• ネットワークに問題がある

• ミドルウエア設定、カーネルパラメータ設定に問題がある

• アプリケーションに問題がある

• フレームワークに問題がある

• ロジックに問題がある

• キャッシュ設計に問題がある

• DBに問題がある

• 参照に問題がある

• 更新に問題がある

Webサーバ1台だけ

DBに対して参照、更新の両方が行われるケースの試験

Elastic Load Balancing

Availability Zone Availability Zone

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

攻撃サーバ = 攻撃されるサーバ

EC2 instance

web appserver

.php

RDS DB instance

RDS DB instance standby

(Multi-AZ)

ElastiCache

ElastiCache

更新.php

Step.4 更新系のシステムに負荷をかける

参照系ページでは発生しなかった、ロック競合などのリソース競合などが新たに

発生する可能性がありますが、それらを切り分けて調査しやすくなります。

Step.4 更新系のシステムに負荷をかける

負荷試験結果が芳しくない原因(例)

• 試験内容、方法に問題がある

• インフラに問題がある

• LBに問題がある

• ネットワークに問題がある

• ミドルウエア設定、カーネルパラメータ設定に問題がある

• アプリケーションに問題がある

• フレームワークに問題がある

• ロジックに問題がある

• キャッシュ設計に問題がある

• DBに問題がある

• 参照に問題がある

• 更新に問題がある

5. 段取りに沿った負荷試験実践編

Step.1 負荷試験シナリオを利用する

Step.2 スケールアップ・スケールアウト可能なシステムであることを確認する

Step.3 (必要に応じて)複数の攻撃サーバから同時攻撃をする

実践編

Step.1 負荷試験シナリオを利用する

Jmeter等のシナリオ記述可能なツールで実際のユーザーの行動を想定したシナ

リオを組んで試験を行ないます。

シナリオの組み方

• 典型的なユーザーの導線を“適当に”考えて“適当に”組んでいきます。

• ユーザーの導線の完璧なモデルケースは作れない

※作り上げた結果、攻撃ツール側がボトルネックとなることもあります。

• より“重要そう”で、“負荷が高そう”で“問題になりそう”なシナリオで十分

負荷試験の目的は、システムのスケール性能を担保すること!!

Webサーバ1台だけ

予め記載されたシナリオに沿った試験を行う

入会シナリオ・投稿シナリオなど

Elastic Load Balancing

Availability Zone Availability Zone

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

攻撃サーバ = 攻撃されるサーバ

EC2 instance

web appserver

RDS DB instance

RDS DB instance standby

(Multi-AZ)

ElastiCache

ElastiCache

Step.1 負荷試験シナリオを利用する

負荷試験結果が芳しくない原因(例)

• 試験内容、方法に問題がある

• インフラに問題がある

• LBに問題がある

• ネットワークに問題がある

• ミドルウエア設定、カーネルパラメータ設定に問題がある

• アプリケーションに問題がある

• フレームワークに問題がある

• ロジックに問題がある(シナリオが流れる範囲で新たに担保できる)

• キャッシュ設計に問題がある

• DBに問題がある

• 参照に問題がある

• 更新に問題がある

Step.2 スケールアップ・スケールアウト可能なシステムであることを確認する

リソースが逼迫したサーバに関して

・スケールアップ・スケールアウト

を行うことでスループットが改善することを確認することを繰り返します。

この試験では、負荷が集中するボトルネックが次々と移動しますので、今までは現れなかった挙動が出てきます。

そのため、今まで行った試験をPDCAで回して修正を加えます。

※先ほど試験できなかった、DBへの高負荷試験などが可能になります。

Step.2 スケールアップ・スケールアウト可能なシステムであることを確認する

Availability Zone

Availability Zone

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

RDS DB instance

RDS DB instance standby

(Multi-AZ)

ElastiCache

ElastiCache

軽い☺

重い(*_*) 負荷のかかっているリソースを増強する※殆どの場合WebサーバCPUリソース

軽い☺

スループット500req/sec

Elastic Load Balancing

Step.2 スケールアップ・スケールアウト可能なシステムであることを確認する

Availability Zone

Availability Zone

EC2 instance

web appserver

EC2 instance

web appserver

EC2 instance

web appserver

RDS DB instance

RDS DB instance standby

(Multi-AZ)

ElastiCache

ElastiCache

負荷のかかっているリソースを増強する

軽い☺

スループット1000req/sec

Elastic Load Balancing

EC2 instance

web appserver

普通☺

重い(*_*)

Step.2 スケールアップ・スケールアウト可能なシステムであることを確認する

Availability Zone

Availability Zone

EC2 instance

web appserver

RDS DB instance

RDS DB instance standby

(Multi-AZ)

ElastiCache

ElastiCache

負荷のかかっているリソースを増強する2倍づつが良い。

軽い☺

スループット1500req/sec

Elastic Load Balancing

EC2 instance

web appserver

重い(*_*)

2000req/secにならないぞ?

EC2 instance

web appserver

web appserver

EC2 instance

普通☺

Step.2 スケールアップ・スケールアウト可能なシステムであることを確認する

Availability Zone

Availability Zone

EC2 instance

web appserver

RDS DB instance

RDS DB instance standby

(Multi-AZ)

ElastiCache

ElastiCache

普通☺

DBをスケールアップ

軽い☺

スループット2000req/sec

Elastic Load Balancing

EC2 instance

web appserver

EC2 instance EC2 instance

web appserver

web appserver

重い(*_*)

リソースを増強する度に、スループットが上昇するとともに、逼迫するリソースが移動していけばOK

リファクタリングを逼迫したリソース部分を中心に行うことが出来る。

どこにもリソース逼迫が観測されないのにスループットが上昇しない場合は負荷試験のかけ方がおかしいまたはシステムの限界性能がそこまでということ。

Step.2 スケールアップ・スケールアウト可能なシステムであることを確認する

スケールアウトやスケールアップをしてもシステムが追従しないことは良くある。

スケールアップで性能が実際に追従するかどうかはやってみないとわからない。

特に、RDSで既に十分大きめのインスタンスを使っていた場合にスケールアップでスループットが改善しないことも多いことに注意する。

Step.2 スケールアップ・スケールアウト可能なシステムであることを確認する

Step.3 複数の攻撃サーバから同時攻撃をする

クラウドを使えば比較的簡単にJmeter攻撃サーバクラスタを組んだ上でDDOS攻

撃をかけることが出来ます。必要に応じて検討して下さい。

http://dev.classmethod.jp/cloud/apache-jmeter-master-slave-100mil-req-min/

攻撃側が1台で負荷を十分にかけることが出来ない場合は、攻撃サーバを複数起動し

てから攻撃をかけます。

経験上、Jmeterの場合、スケールアップより、スケールアウトが効果的です。

Step.3 複数の攻撃サーバから同時攻撃をする

c4.large(2コア8ECU)の攻撃サーバも、

時給14円(※1)で1時間から利用できる時代。

→100台構成でも1,400円!!

※1 AWS 2016/10/21現在の価格、レート

6. ツールの紹介

ツール

•負荷試験ツール

• Apachebench

• Jemeter

• Locust / tsung / Gatling / Etc…

• その他、Webサービス

色々有りますが、複数のツールを使えるようになっておく

と良いです。

ツール

• モニタリングツール・プロファイリングツール

• Cloud watch

• XHProf

• New Relic

• Etc…

ApacheBench

ApacheBench

• 簡単にかけることが出来る、POST/PUTの試験も可能

• リクエストごとにパラメータを変更する事ができない

• DELETEはできない

• シナリオ記載ができない

時間がなかったら、これでもいいから負荷試験をかける。

多くの場合はカバーできる

Apache Jmeter

Apache Jmeter• GUIで利用

• 各種のmethodが利用可能

• シナリオの記載が可能

• リクエストごとにパラメータの変更が可能

• 攻撃サーバを増やして高負荷をかけることが可能

• 結果の可視化が可能

Jmeterは何回かシナリオを書いたら慣れてくるので意外と簡単になります。

怖くない。

シナリオ記載可能な高機能負荷試験ツールとしては他にもLocust/Tsung/Gatlingなどがあります。

参考:Jmeterで負荷をかけられなくなるリスナーの例

【結果をツリーで表示】リクエスト結果がわかり便利だが、

これが有効になっていると恐らくネットワーク遅延が原因でまともな負荷をかけられなくなる。

ログエラーのみにチェックを入れていても同じなので、試験の前に無効化する必要あり

その他、IFコントローラーで攻撃負荷が激減するなど、注意が必要

Cloud watch

多くの場合、Cloud Watchで充分。

ただし、EC2のモニタリングはデフォルトだと、5分間隔でしか出来ない(※)ことに注意が必要。オ

プションで1分間隔にしておいて下さい。

例えば、ELBのメトリクス監視でこれを使うことにより、複数のサーバから連動して攻撃できない

ツールでも結果を残しておくことが出来るので意外と便利。

※5分間隔だと、一回の試験を15分以上続けないと正確なグラフの値がプロットされない。

XHProf

XHProf

HTTP://PHP.NET/MANUAL/JA/BOOK.XHPROF.PHP

インストール・利用が非常に簡単なプロファイリングツール

Graphvizをインストールすることで実行時間が長い箇所を可視化してくれる

※全てのプロファイリングツールに共通の問題として、利用後は機能をOFFにしておくこと

XHProf (wordpress index.php)

この例では、リクエストパラメータのuse_xhprofを見て、プロファイリングを行うかどうかを決定している。

負荷がかかった状態でのプロファイル結果をみるべきだが、負荷をかけるための攻撃ではプロファイリングを無効にして、同時に別のリクエストでプロファイリングを行うことが重要。

XHProfサンプル1

XHProfサンプル2

Graphvizをインストールするとプロファイリング結果の可視化も可能

XHProfサンプル3

実行時間のかかっているメソッドや、実行回数が多すぎるメソッドなどを追うことが出来る。

7. 負荷試験でやってはいけない集

開発工程の一番最後に負荷試験する。

やってはいけない

製造

単体試験

結合試験

商用環境構築 負荷試験

リリース日

全部が揃ってなくても、環境が整ってなくても試験をしておかないと、修正期間が取れません。

製造

単体試験

結合試験

負荷試験

リリース日

修正期間

商用環境構築

一つのツールにこだわる

やってはいけない

ツール毎に特性があります。より高負荷をかけた試験を行いたい場合は

それに適したツールを利用します。

また、複数のツールを使うことで、そのツールで計測した値が適切なものであることの担保も出来ます。

遠くのネットワークから攻撃する

やってはいけない

EC2 instance

web appserver

EC2 instance

web appserver

攻撃元が遠いとダメ(失敗例)

Elastic Load Balancing

RDS DB instance

RDS DB instance standby

(Multi-AZ)

ElastiCache

ElastiCache

攻撃されるサーバ

EC2 instance

web appserver

EC2 instance

web appserver

攻撃サーバ

AZをまたいでの負荷試験はほぼ無意味

スループットは上がらないのに、リソースが余るという状況が発生する。

ネットワークの試験になるだけでなく、一部の遅いプロセスが全部終わるまで試験が終わらないために、攻撃対象サーバに負荷が

かからない。

Availability Zone Availability Zone

負荷試験をかけることが出来るWEBサービスも同じ理由で使わないほうが良いです。

ちなみに、あまりにも時間がなさすぎて、社内ネットワークから負荷試験をかけてみた

「2時間後に芸能人呼んでプレスリリース打つんだけど、このサイトの負荷試験しておいてよ。」

「負荷試験シナリオ?ないよ。TOPページから適当にお願い。」

社内にウイルス感染したPCがあるとの疑惑で怒られた。

SSLを利用した負荷試験

やってはいけない

SSLアクセラレータ(※)を利用して、システムに負荷がかかっていない場合であってもスループットは激減する

これは負荷試験環境だからこそ発生する問題

(※ELBで終端させた場合など)

なんか負荷試験やりにくかったので今回はパス!!

やってはいけない

負荷試験実施が難しいケース1

•外部システムとの結合がある

• スタブを用意する

•パラメータを動的に変更しなければならないケース

• シナリオ記述できる負荷試験ツールを使う

• プログラムの一部改変をする

• 最悪、一部の機能を殺してでも試験は行う

負荷試験実施が難しいケース2

•負荷試験環境が存在しない

• クラウドだったら頑張って構築する

• オンプレミスで稼働中のシステムだったら、クラウドに類似システムを構築す

• 同規模の環境の構築が難しければ、小さなインスタンスと台数で構築して、N

倍して考える(※不確定要素が増えて難易度が跳ね上がるので余りおすす

めしませんが、、、)

ELBやCloudfrontなどのベンダーの提供する既存サービスに対して負荷試験を行う

やってもいみない

静的コンテンツはサービス利用前提とすると負荷試験も行わないでよい。

S3での配信+リバースプロクシを立てる

リバースプロクシとしてnginxやsquidとか

いろいろ有りますが、、、

冗長化やスケール性を考えるとAkamai

やCloudFrontなどのCDN立てるのが一

番エンジニアが楽できます。

Amazon S3

CloudFront

補足

システムが遅い時のあたりの付け方

• (既存/自作)FWが重い(CPU負荷が高い、メモリ使用量が多い)

• DBの応答が遅い(Slow query logを見る)

• SQLが悪い(ORMのせいかも)

• INDEXが不適切

• ロックが発生している(INNODB_LOCKSやログ監視など)

• 無駄なSQLが発行されている

• DB設計が悪い

• リソース不足

• 不要なループ・冗長なコード・内部リソースの使い回しがされていない

• Cacheが適切に設定されていない

システムがスケールしない時のあたりの付け方

Webサーバの外の外部リソースとの接続部分を中心に調査をします。

• DBボトルネックである場合

• 外部リソースとの接続オーバーヘッドが大きい

• 各種コネクションプーリングしていない(DB/Memcached/Http session)

• 外部サーバへのログ転送を非同期にしていない

• NAT能力不足

top related