お手軽JMeterクラスター 〜 フルボッコ編|アドカレ2013 : CFn #1
よく訓練されたアップル信者、都元です。12月ですね! 全国のエンジニアの皆様! いよいよこの季節がやってまいりました。そう、アドベントカレンダーです。
今年のDevelopers.IOでは、複数テーマのアドベントカレンダーが同時進行していくようですが、これは「クラスメソッドAWSチーム」によるアドベントカレンダーです。これからクリスマス・イブまでの毎日、1つずつエントリーを投下していきます。
CloudFormationビッグバンテンプレート
クラスメソッドAWSチームのアドベントカレンダー2013は、題して「CloudFormationビッグバンテンプレート」です。
AWS公式ページの中にAWS CloudFormation サンプルテンプレートというページがあります。多くのテンプレートはその名の通り「サンプル」なのですが、中にはWordpressやRedmineサーバを構築するテンプレート等、実用的なものが含まれています。
本アドベントカレンダーでは、実用的なテンプレートを毎日1つずつ、計24本お届けするという企画です。ではこれより、1日目のテンプレート「JMeterクラスター 〜 ブルボッコ編」をお送りしま〜す。
JMeterクラスター 〜 フルボッコ(fullbok)
負荷テストってやりますよね。構築したシステムがどの程度の負荷に耐えられるのか、スループットはどの程度出るのか。このような目的で負荷試験を行うような仕組みは、ab (apache bench)のようなクライアントアプリから、LoadImpactのようなWebサービス、LoadRunnerのような商用製品まで、実に多くの選択肢があります。
その中で今回は、Apache JMeterを取り上げます。JMeterは古くからある振る舞い・パフォーマンスのテストを目的としたツールです。特徴的なのが、複数のサーバを協調させ、クラスタを組んで一斉に負荷テストができる、という機能です。
例えばabを使う場合、多くの場合は開発者のローカルマシンから実行するでしょう。その場合、掛けられる負荷の上限が、開発機のスペックやそのマシンが利用するネットワーク性能で決まってしまいます。開発機1台では到底再現できないような大量アクセスをシミュレートするためには、このようなクラスタリング機能が必須となります。
という仕組みを詳しく解説したのがSpotInstanceとJMeterを使って400万req/minの負荷試験を行うですね。
ただし、JMeterクラスタには「MasterとSlaveは同じサブネットに属していなければならない」「Master及びSlaveは相互にインバウンドの接続ができなければならない」という制約があり、上でご紹介したエントリの構成ではJMeterのGUIが使えません。SSHトンネリング等をかましてローカルマシンをMasterにするような構成も試してみましたが、結局上手く動かすことができませんでした。
このような制約の中、JMeterクラスタのMasterはGUIで操作したい、EC2でクラスタを組みたい、となると結構な設定コストが掛かります。これを解決するべく、EC2を利用したJMeterクラスタを組み上げるCloudFormationテンプレートが「フルボッコ(fullbok)」です。
まずは fullbok-demo から
とりあえずいきなり負荷テストの本番に使う人もいないでしょうから、まずはデモからですよね。
ここでは以上のような構成を構築します。向かって左側が、サンドバッグ役のシステム(JMeterTargetと呼びます)です。ELB配下にMulti-AZで2台のサーバを配備しています。どうせデモですのでt1.microです。中では一応PHPが動いてます。何れも大したモンじゃありません。厳密に見ればXSS脆弱性がありますが、短時間しか利用しないのデモ環境ですので、気にしないことにします。
/var/www/html/index.html
<html><head><title>Hello</title></head><body>Hello, target!</body></html>
/var/www/html/info.php
<?php phpinfo();
/var/www/html/wait.php
<?php usleep($_GET['time']); echo \"wait complete.\".$_GET['time'];
向かって右側がfullbok本体です。JMeterMaster(Windowsなのでm1.medium)と、JMeterSlave(複数のLinux:m1.small)から成っています。
というわけでこれを起動してみましょう。
1ページ目では特に記述変更する必要はありませんので、Continueで次にどうぞ。
パラメータは以下のとおりです。
- KeyName: ECのキーペア名。Target/SlaveへのSSH接続、MasterのRDPパスワード復元に使うやつです。
- TargetCapacity: 殴られ役(JMeterTarget)の数です。まぁデモですので2つ程度で。
- MasterInstanceAMI: JMeterMasterのAMI IDです。下記注意書き参照。(v1.1より)
- SlaveCapacity: 殴り役(JMeterSlave)の数です。まぁデモですので2つ程度で。
- SlaveSpotPrice: 殴り役のスポットインスタンスビッド価格です。0だとOnDemandで起動します。(v1.1より)
- Sub-Stackを利用するため「I acknowledge that this template may create IAM resources」にチェックを入れてください。
最新バージョンのAMI IDは、awscliを使って下記のようなコマンドで探すか、この辺りのページを参照してください。
$ aws ec2 describe-images --filters "Name=platform,Values=windows" --owners amazon | \ jq ".Images[] | select(.Name | contains(\"Windows_Server-2012\") and contains(\"-64Bit-Base-\")) | {\"ImageId\":.ImageId, \"Name\":.Name, \"Description\":.Description}"
参考までに、2013-12-17時点での「Microsoft Windows Server 2012 RTM 64-bit Locale English Base AMI provided by Amazon」のAMIは下記に示しておきますが、数カ月後には利用できなくなっていますのでご注意ください。
Region | ID |
---|---|
US East (Virginia) | ami-7527031c |
US West (Oregon) | ami-b652c986 |
US West (Northern California) | ami-0285b347 |
EU West (Ireland) | ami-3937da4e |
Asia Pacific (Singapore) | ami-dccc998e |
Asia Pacific (Sydney) | ami-9d3fa3a7 |
Asia Pacific (Tokyo) | ami-b1492eb0 |
South America (Sao Paulo) | ami-9b3a9c86 |
あとはデフォルトのままでContinueボタン連打で構いません。
スタック作成の所要時間はだいたい30分強ってとこでしょうか。スタックが完成(CREATE_COMPLETE)したら、出来上がったELB *1にアクセスしてみてください。Hello, target!ページが表示できたでしょうか。その他、info.phpやwait.php?time=5000000等で挙動を確認してみてください。
次に、EC2のManagement Consoleに行き、インスタンスを確認します。JMeterTargetがサンドバッグ、JmeterSlaveが凶悪なボクサー、JMeterMasterが主犯です。で、JMeterMasterだけがWindowsインスタンスとなっています。
そこで、このWindowsインスタンスのパスワードを取得します。JMeterMasterインスタンスを選択し、Actionsメニューから「Get Windows Password」を選択します。
出てきたポップアップに、キーペアの秘密鍵を入力することで、WindowsサーバのAdministratorパスワードを取得できます。
上記の情報を使って、RDPでJMeterMasterサーバに接続しましょう。
デスクトップはこんな感じ。
デスクトップにはJMeterの起動ショートカットがあります。
こちらからJMeterを起動し、あとは普通にシナリオを作るなり、どこかで作っておいたシナリオをダウンロードするなり。ここではサンドバックをボコボコにするシナリオを書くと良いでしょう。
シナリオを書き終わったら、ひとまずシナリオを保存し、Remote Start All ボタンをクリックすることによって負荷試験が始まります。
結果は以下のとおり。WindowsベースのGUIですので、グラフ表示で即座に結果が見られる、というのがいいですね。
こころゆくまで殴ったら、stackを撤収しておきましょう。
本番利用のためのフルボッコ(fullbok)
さて、以上はあくまでもデモ環境。本気で使うなら下のリンクからどうぞ。本番利用であれば、ターゲットはすでに居るはずですので、こちらではサンドバッグ役は作りません。また、JMeterMaster及びJMeterSlaveのインスタンスタイプをコントロールできるようになっています。テストしたい規模に応じてパラメータを調整してください。
1ページ目ではデモの時と同様に特に記述変更する必要はありませんので、Continueで次にどうぞ。
パラメータは以下のとおりです。
- KeyName: ECのキーペア名。Target
- AvailabilityZone: fullbokシステムを展開するAZを指定します。
- SSHFrom: JMeterMasterへのRDPや、JMeterSlaveへのSSH *2を許可するIPアドレスブロックをCIDRで指定できます。
- MasterInstanceAMI: JMeterMasterのAMI IDです。(v1.1より)
- MasterInstanceType: JMeterMasterサーバのインスタンスタイプ *3です。
- SlaveInstanceType: JMeterSlaveのインスタンスタイプです。規模要件に応じて。
- SlaveCapacity: JMeterSlaveの数です。規模要件に応じて。わざわざクラスタを立てるわけですから、最低でも4台くらいは必要じゃないかと思います。
- SlaveSpotPrice: JMeterSlaveのスポットインスタンスビッド価格です。0だとOnDemandで起動します。(v1.1より)
Githubに公開中!
本アドベントカレンダーでご紹介するテンプレートは、GitHub上にOSSとして公開します。改善アイデアやバグフィックス等ありましたら、お気軽にpull-requestにてご連絡頂ければ幸いでーす。
以上、CloudFormationビッグバンテンプレート第一弾「フルボッコ(fullbok)」でした。明日はどんなテンプレートが登場するでしょうか、乞うご期待!
バージョンアップ履歴
v1.0
- 初回リリース
v1.1
- improvement: JMeterSlaveクラスターのスポットインスタンス対応。
- bugfix: JMeterMasterのAMIが登録抹消されて利用できなくなっていたので、AMI IDをパラメータとして受け取るように変更。
v1.2
- improvement: JMeter slaveのチューニング(OS / JVM)
v1.3
- bugfix: JMeterのダウンロードURLを変更 (cf. issue#3)
v1.4 - 2014/06/20
- improvement: パラメータ上のインスタンスタイプを自由に設定できるように変更。
v1.5 - 2014/11/06
- improvement: DNSキャッシュの問題修正
- bugfix: Oracle JDKのダウンロード処理変更に追従