aws memo

AWS関連の備忘録 (※本ブログの内容は個人的見解であり、所属組織及び企業の意見を代弁するものではありません。1年以上古いエントリは疑ってかかってください)

訳:ELB:評価方法のベストプラクティス

Best Practices in Evaluating Elastic Load Balancing : Articles & Tutorials : Amazon Web Services

http://aws.amazon.com/articles/1636185810492479

====

概要

ELBを最もよく評価するには、ELBのアーキテクチャを理解する必要がある。本稿は、AWS ELBの機能と独特なアーキテクチャについて述べる。ベストプラクティスを提供することで、ELBをテスト・評価する際に一般的な落とし穴(pitfall)から避けられるようになる。このホワイトペーパーが対象としている読者は、ELBの経験が少ないが、過去にH/W,S/Wのロードバランサを使ったことがあるような開発者である。

ELBの概要

ELBは、複数のEC2インスタンスへ、自動的にトラフィックを分散する。単一のAvailabitilty Zone(AZ)や、複数の(AZ)にまたがって負荷分散するようにELBをセットアップできる。ELBによって、大きな耐障害性を可能にするだけでなく、トラフィックに応じてシームレスにロードバランサ性能を提供する。

複数のAZにEC2インスタンスを配置することで耐障害性のあるアプリケーションを構築出るが、手動で介在せずにより耐障害性を高めるために、ELBを使うことができる。ELBのバックエンドとしてEC2インスタンスを配備すると、ELBがトラフィックを自動的に複数のEC2インスタンスと複数のAZに振り分けるので、耐障害性を実現できる。また、正常なEC2インスタンスだけがトラフィックを受信することを保証する。

ELBはEC2インスタンスの死活も検知する。不具合のあるEC2インスタンスを検出すると、そこへはトラフィックを振り分けないようにし、残っている正常なEC2インスタンスに振り分ける。複数のAZにEC2インスタンスを配備していて、あるAZの全インスタンスに不具合が発生しても、ELBはこのゾーン以外の正常なインスタンスに振り分ける。不具合のあるEC2インスタンスが復旧すると、ELBはそのインスタンスへの振り分けを再開する。加えて、ELBはそれ自身が耐障害性が高く、相互監視している分散システムである。

ELBはオートスケールとも統合している。バックエンドの性能をトラフィック量に合わせる機能である。ELB配下の正常なEC2インスタンス数が2個以下でないことが条件としよう。この条件をオートスケールに設定でき、オートスケールがこの条件を検出した時には、必要数のEC2インスタンスを自動的にオートスケールグループに追加する。例えば、全インスタンスにて、15分間に4秒以上のレイテンシが1回でも発生すると、インスタンスを追加する、といったものだ。オートスケールはEC2インスタンスがELB配下にあっても、適切なアクションを行う。オートスケールはELBを使っていてもいなくても同じようにEC2インスタンスをスケールさせる。

ELBの利点のうち大きな一つが、ロードバランサの管理・維持・スケールという複雑さを抽象化することである。ELBは必要な容量を、操作無しで自動的に増減させるように設計されている。

ELBのアーキテクチャと、動作

ELBアーキテクチャには2つの論理コンポーネント(ロードバランサと、コントローラサービス)がある。ロードバランサは、インターネットから受信するトラフィックを監視しリクエストを処理する。コントローラサービスはロードバランサを監視し必要に応じて性能を増減させ、ロードバランサが正しく稼働しているか確認する。

Architecture of the Elastic Load Balancing Service

ELBをスケールさせる

ELBを作成すると、トラフィックを受け付けてEC2インスタンスに振りwけるように設定する必要がある。この設定パラメータはコントローラに保存され、コントローラは、全ロードバランサが正しい設定で動作することを保証する。コントローラはロードバランサの監視と、クライアントのリクエストを振り分ける性能の管理もしている。コントローラは、より大きな(高性能な)リソースを使うことやリソースを増やすことで容量を増やし、ロードバランサのDNSレコードに新しいリソースのIPアドレスを追加する。DNSレコードは60秒のTTLであり、クライアントは少なくとも60秒毎に再発見する。デフォルトでは、クライアントが名前解決をした際にELBは複数のIPアドレスをランダムの並びで返す。トラフィックの傾向が変わると、コントローラはより多いリクエストを扱うためにロードバランサを全AZで均等にスケールさせる。

ロードバランサはELBに登録されたEC2インスタンスのヘルスチェックも行なっている。インスタンスのサービスが正常であることのチェックが、ELBをの設定で定義された成功回数に達している必要がある。

例えば、ELBに登録された全インスタンスに対して、ヘルスチェック間隔を20秒、ヘルスチェック成功回数10回を設定していると、ELBがトラフィックを割り振るまで最低200秒かかる。ヘルスチェックはまた障害の閾値を定義している。例えば、チェック間隔20秒、障害閾値4に設定すると、インスタンスがリクエストの応答をしなくなった時、最低80秒は障害(Out of Service)として扱うまでに時間を要する。あるインスタンスが終了(terminate)すると、そのインスタンストラフィックは割り振られなくなるが、ロードバランサがインスタンス終了を検出するまで遅延がある。そのため、インスタンスを終了させる前にELBから登録解除することで短時間でELBから切り離せる。

負荷試験シナリオの計画する

多くの開発者は、VPSや物理ハードウェア環境で負荷テストツールを使っており、ロードバランサの挙動を評価する方法も理解している。以下のような評定を作ってロードバランサを評価している。

  1. 様々なトラフィックレベルをサポートするために何台のアプリサーバが必要か?
  2. レスポンスタイムを減らすこと無く負荷分散を行うために何台のロードバランサが必要か?
  3. H/WやN/W障害時にアプリケーションが動作し続けるか?

どれも重要な質問だが、アプリケーションの設定に依存しており、1と2はEC2環境では重要でない。オートスケールを使っていれば、必要に応じてアプリサーバを増減するので、前もって(up front)台数を決めなくてよい。ELBを使っていれば、ELBを実行する時間と扱ったデータ量に対して支払うだけで、アプリケーションに必要な性能に対して支払いは無いので、質問2を気にしなくてよい。

ELBの目的はアプリケーションの要求に応じてスケールすることである。これはDNSレコードの更新によって行われるので、ELBの機能のいくつかがテストシナリオに及ぼす影響を気にする必要がある。

DNS名前解決

様々な負荷テストツールがあり、多くのツールが、サーバが扱えるトラフィック量に応じて用意すべきサーバ台数を決めるための設計になっている。この状況でテストを行うために、サーバが限界に達した時を決めるためにトラフィック量をすぐに増やすことは論理的であり、限界点に影響する要素を決めるためにリクエストサイズとレスポンスサイズに基づいてテストを繰り返す。

ELBを作った場合、デフォルトの性能レベルが配備・設定される。トラフィックの傾向変換を検知し、ELBはスケールを増減させる。ELBがスケールするのに1~7分必要とする。ELBがスケールすると、DNSレコードに新しいIPアドレスが追加される。クライアントが性能増強の恩恵をうけるために、ELBはDNSのTTLを60秒に設定している。DNSレコードが変わることをテストに盛り込むことが重要である。DNSの再解決や複数のテストクライアントを使うことを確実にしてないと、ELBが実際には多くのIPアドレスを用意しても、テストは単一のIPアドレスに対して行い続けるだろう。全エンドユーザがその単一のIPアドレスを解決するわけではないので、そのテストは、実世界のサンプルになりえない。

スティッキーセッション

ELBはcookieを使ったスティッキーセッション機能(session affinityと呼んでいる)をサポートしている。デフォルトではこの機能は無効になっており、有効にするのは簡単である。使用できるスティッキーポリシーは2種類あるが、ネットの影響は同じである。ELBがスティッキーセッションを有効にしていると、ユーザがアプリケーションにアクセスし続ける間同じバックエンドインスタンスにリクエストを振り分ける。スティッキーセッションを使って負荷テストを行う場合、この機能をどう使うか決めることが重要である。負荷テストでも実世界でもスティッキーセッションをどうするか考えることは問題になる。

例えば、通常4台で運用しているアプリケーションを考える。各ユーザは、ELBがどのバックエンドに振り分けるかが書かれている10分間有効のcookieを受け取る。トラフィック傾向が大きく変わると、アクセスするユーザが3倍に増え、新しいユーザは4台のバックエンドサーバのいずれかに振り分けられるcookieを受け取る。cookieの有効期間が切れるまで、バックエンドがどのくらいのキャパシティか関係なく、大量のユーザが既存の4台のサーバにリクエストを投げる。

スティッキーセッションは強力な機能だが、あなたのアーキテクチャにフィットさせる方法と、テストシナリオに適したソリューションかどうかを考えることが重要である。

ヘルスチェック

ELBはバックエンドインスタンスに対して、ユーザが設定した内容でヘルスチェックを行う。ELBにあるインスタンスが追加されると、正常と判定するまで必要な回数だけヘルスチェックを行う。ヘルスチェック失敗回数が上限に達した時は、インスタンスがプールから削除される(ただし、まだELBには登録されている)。インスタンスがELBに登録されている間、ELBはインスタンスのヘルスチェックを続ける。ヘルスチェック間隔を長く設定する、もしくは高い閾値を設定すると、ELBからトラフィックを受信開始するのにより多くの時間を要する。オートスケールのような自動化でアプリケーションプールのキャパシティを増やす場合、このことは特に重要になる。

アーキテクチャの負荷テストを考える時、ヘルスチェックをどう行うかを決めることは重要である。軽い(静的)ページを高頻度に確認してWebサーバが生きているかを確認するか、重い(動的)ページを低頻度に確認してアプリケーションの全パーツが正常であることを確認するかを考える。ELBからインスタンスへのヘルスチェックリクエストのすべてがAmazon CloudWatchのメトリクスから除外されるが、アプリケーションのログには出現する。設定したヘルスチェックに加えて、ELBはインスタンスとコネクションをオープンできるかというチェックを高頻度に行う。このチェックは、インスタンスのヘルス状態を決めるために使うのではなく、インスタンスが終了したことを確実に検出するために使っている。

バックエンド認証

バックエンドとの通信にSSLを使っている場合、バックエンドの認証を有効にすることができる。この認証を設定すると、設定された公開鍵のホワイトリストに認証公開鍵がある時だけ、ELBはバックエンドインスタンスと通信する。この強力な機能は寄り高い防御性とセキュリティを提供するが、リクエストスループットは明らかに低くなる。レスポンスタイムの期待値に応じて、この機能が適切な場合と不適切な場合がありうる。

テストフレームワークを選ぶ

テストのセットアップ詳細に不注意(regardless of the details of the test setup)で、負荷テストを実行するためにソフトウェアやフレームワークが必要になる。負荷テストの設定は、時間と共にリクエスト数を増やす必要がある。また、複数のクライアントやエージェントからリクエストを送信剃る必要があるかもしれない。多くの負荷テストツールは分離された負荷生成クライアントの生成をサポートし、他の負荷テストツールはテスト実装の微調整が必要になるかもしれない。テストで使われる一般的な3つのシナリオを次節で述べる。

単一クライアントのテスト

 単一クライアントのテストでは、負荷生成を同一のクライアントから行う。多くの場合、テスト開始後にクライアントはNDSの再解決をしない。この種のテストの良い例は、Apache Bench(ab)である。この種のテストツールを使うなら、2つの選択肢がある。

  1.  サンプルサイズと並行数に応じた独立したテストを書き、テストの集合として開始し、各テストを独立して呼び出すことで、クライアントはDNSの再解決を行う(OSや他の要素で強制的に再解決を行うこともある)
  2. 複数のクライアントインスタンスを起動し、ほぼ同時にテストを開始する。AWS CloudFormationは負荷テストスクリプトを作成し複数のクライアントを起動することを容易にでき、単純にリモートSSHコマンドでテストを起動することができる。オートスケールのルールに基づいて、より多くの負荷生成クライアントを用意したいだろう。(例えば、他の深クライアントのCPU平均があるレベルに達すると、負荷生成クライアントを追加する、等)

しかし、生成しようとする負荷に依存し、クライアントのリクエスト能力にテストが引きづられる可能性がある。その場合、分散テストを考慮する必要がある。

組み込み複数クライアントのテスト

あるテストフレームワークはテスト実行用に複数のクライアントを生成する。例えば、curl-loaderというOSS性能テストツールがある。各クライアントが独立したプロセスとして実行するので、各々がDNS再解決する。単一クライアントのテストと同様、クライアントが生成できる負荷よりも負荷テストが大きい場合は、分散テストを考慮する必要がある。

分散テスト

多くのクライアントを使ってELBをテストするには、webサイトテスト用のツールを使って自動テストを行うサービスプロバイダがある。アプリケーションによっては、最も簡単で最も効果的な方法かもしれない。この種のサービスがうまく動作しないなら、分散テスト用ツールを考える。Bees with Machine Gunsと呼ばれる興味深いアプローチを組み合わせているOSSの Fabic framework がある。これは、テストを実行して結果をテストコントローラにレポートするテストクライアントを起動するのにEC2環境を使う。分散テストの要望に対するアプローチには多くの方法があるが、多くの場合(特に高負荷)、分散テストフレームワークが、実環境のトラフィックをシミュレートするのに最も効果的なアプローチである。

推奨するテストアプローチ

いくつか特殊なアプローチがある。

There are some specific approaches and considerations that you should account for in your Elastic Load Balancing test plan. It is critical that you test not only the saturation and breaking points but also the "normal" traffic profile you expect. If your site receives a consistent flow of traffic during normal business hours, then you should simulate the steady states of low and high traffic; you should also simulate the time frame in the mornings and evenings in which the traffic profile transitions from low to high or vice versa. If you expect to receive significant changes in traffic in short periods of time, then you should test this. If your application is an internal intranet site, then it is probably unlikely that traffic will go from 1000 users to 100,000 users in five minutes, but if you are building an application that is likely to have flash traffic, then you should test in this environment so that you understand not only how Elastic Load Balancing will behave, but also how your application and any components in your application will behave.

負荷を増やしながらテストする

テストツールを設置したら、負荷の増加率を定義する。5分毎に50%以下の負荷増加率を推奨する。負荷生成のステップパターンと、線形パターンの両方が、ELBとうまく動作する。ランダム負荷生成を使うなら、スパイクのcelingを設定しておくことが重要である。そうすることで、ELBがスケールするまでの間リクエストを扱える負荷を超えられない。( Pre-Warming the ELB を参照のこと)

ロードバランサによるセッションアフィニティを取り込んだアプリケーションアーキテクチャの場合、いくつか追加の設定ステップが必要になる。いかに示す。

セッションアフィニティで負荷テストする

セッションアフィニティの機能を使う場合、複数クライアントを使って負荷生成することが重要である。そうすることで、ELBは現実と同じ振る舞いができる。これらの調整をしないなら、ELBはリクエストを常に同じバックエンドサーバに転送し、ELBがスケールすべき負荷に達する前にバックエンドサーバが音を上げる(potentially overwhelming)。シナリオでテストするために、複数クライアントで負荷生成する負荷テストソリューションを使う必要がある。

環境を監視する

ELBの利点の一つはAmazon CloudWatchを通じて多くのメトリクスが提供されていることである。負荷テスト中には、3つの重要なモニターがある。ロードバランサー、負荷生成クライアント、ELBに登録されたアプリケーションインスタンスである。

ELBを監視する

ELBはCloudWatchを通じて次のメトリクスを提供している。(これらのメトリクスの詳細はこのドキュメントを参照のこと http://aws.amazon.com/documentation/cloudwatch/ )

  • レイテンシ(Latancy)
  • リクエスト数(Request count)
  • 正常ホスト数(Healthy hosts)
  • 異常ホスト数(Unhealthy hosts)
  • バックエンド 2xx-5xx レスポンス数(Backend 2xx-5xx response count)
  • ELB 4xx,5xxレスポンスカウント

アプリケーションをテストする際、これらすべてのメトリクスを見ることが重要である。特に注意するアイテムは、ELB 5xxレスポンス数、バックエンド5xxレスポンス数、レイテンシである。

負荷生成クライアントを監視する

負荷生成している前クライアントを監視することは、負荷テストがきちんとレスポンスを送受信しているか確認するために重要である。EC2上で単一テストクライアントを使う場合、負荷を扱うためにスケールできるようにしておくこと。高負荷時、クライアントがN/W帯域の制限にあたり、テスト結果に影響を及ぼす可能性があるので、複数クライアントを使う必要がある。

アプリケーションインスタンスを監視する

どんなテストをする際も、アプリケーションインスタンスを監視することを推奨する。Linux用のtop, Windows用のAnalysis of Logs(PAL)といった典型的なモニタリングツールも適しているが、インスタンス用のAmazon CloudWatchメトリクスを使うこともできる。(CloudWatchのドキュメントについてはこちらを参照のこと http://aws.amazon.com/documentation/cloudwatch/)詳細情報を取得したい場合、1分間隔のメトリクスを使うことで、テスト中のより可視化された振る舞いを得ることができる。

ELBをテストする際の一般的な落とし穴

ELBの性能上限に達した時

ELBは本当の性能上限に達することは殆ど無いが、メトリクスに基づいてスケールするまでは、それ以上リクエストを処理できないときに HTTP503を返す期間があり得る。ロードバランサーはリクエストをキューに入れないので、性能上限に達しているときは、追加のリクエストは失敗する。トラフィックが順調に増えると、ELBは正常に機能するが、突然のスパイクやとあるテストシナリオにおいては、ELBがスケールする性能上限よりも速いトラフィック増のレートになる。この状況では、以下の2つの選択肢がある。

ロードバランサーをPre-Warmingする

リクエストに応じて、ELBは想定されるトラフィックを基に最小限のスケールを行うように設定されている。これは、トラフィックが計画的な場合、DDOS攻撃を受けた場合、次第にトラフィックを増やす設定にできない負荷テストの際に必要とされる。もしアプリケーションの通常の負荷でないような極端な負荷時の振る舞いを評価するために負荷テストをするつもりなら、プレミアムサポートに加入して、サポート経由で、ELBのPre-Warmを申請することを推奨する。テストの開始日と終了日、想定される毎秒のリクエストレート、テストで使うリクエスト/レスポンスサイズの総計を聞かれる。

負荷テストパラメータを制御する

負荷テストを設定して、5分間に50%以上トラフィックが増えないようにすることを推奨する。段階的にトラフィックを引き上げるか徐々に引き上げてテストすることは用意なはずだ。期間内に大きなボリュームの負荷が増えるように設定すれば、ELBは必要に応じてスケールする。

DNS名前解決

クライアントが最低1分間毎にDNSの名前解決を行わないと、新しくDNSに追加されたELBリソースがクライアントから使われない。これは、ELB全体では負荷が低いにもかかわらず、クライアントがごく一部のELBリソースを飲み込む(overwhelm)ことを意味する。これは、実際のシナリオでは起こりえない問題であるが、負荷テストでよくある問題である。

スティッキーセッションとユニーククライアント

スティッキーセッションが有効の場合、リクエストごとにクライアントを生成するよりも、負荷テストフレームワークがコネクションとクライアントを際利用しないことが問題である。もししていない場合、クライアントは常に同一のELBリソースにトラフィックを送信し、同一のバックエンドインスタンスに転送され、ELB全体のリソースのごく一部が酷使されることになる。

初期性能

ELBは起動初期の性能が設定されており、トラフィックに応じてスケールを増減させる。ELBの初期性能で扱える量よりも多いトラフィックですぐに負荷テストをはじめる場合がある。あるいは、ELBを作成して数時間使わない場合、ELBはスケールダウンする。

コネクションタイムアウト

ELBに登録するインスタンスを設定する際、インスタンスのアイドルタイムアウトを、しっかりと最低60秒に設定しておくことが重要である。ELBは60秒後にアイドルコネクションをクローズするので、バックエンドインスタンスのタイムアウトは60秒(ELBのタイムアウト値)以上にすることを期待する。タイムアウトの調整に失敗すると、ELBはインスタンスが不具合を起こしたと間違って判定し、そのインスタンスへのトラフィックの割り当てを止めてしまう。

追加の情報

ELBページ

CloudWatchページ

Auto Scalingページ

分散テストソリューション

NeoTys: http://aws.amazon.com/solutions/solution-providers/neotys/

SOASTA: http://aws.amazon.com/solutions/solution-providers/soasta/

Apica: http://aws.amazon.com/solutions/solution-providers/apicasystems/

Eviware: http://aws.amazon.com/solutions/solution-providers/eviware/