AWS Transfer Family に複数ユーザーのアップロードが集中した状況を作れるか、Apache JMeter で試してみた

2022.06.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

いわさです。

AWS Transfer Family で SFTPサーバーを構成し、複数ユーザーの同時接続テストを想定したロードテスト行う機会がありました。
今回、Apache JMeterのSFTPサンプラーを使って実現したのですが、備忘録を兼ねて手順を残しておきたいと思います。

この記事では、macOS版の Apache JMeterをHomebrewでインストールした環境を使用しています。
また、この記事ではGUIを使ってJMeterの操作を行っていきます。

jmeter — Homebrew Formulae

Transfer Familyを用意する

SFTPを有効にしたサーバーを作成しておきます。

以下を参考に数ユーザー分のSSHキーを作成します。

キーの管理 - AWS Transfer Family

$ ssh-keygen -P "" -m PEM -f user1
$ ssh-keygen -P "" -m PEM -f user2
$ ssh-keygen -P "" -m PEM -f user3

$ ls -l
total 136
-rw-------  1 iwasa.takahito  staff   2459  6  1 08:16 user1
-rw-r--r--  1 iwasa.takahito  staff    582  6  1 08:16 user1.pub
-rw-------  1 iwasa.takahito  staff   2459  6  1 08:16 user2
-rw-r--r--  1 iwasa.takahito  staff    582  6  1 08:16 user2.pub
-rw-------  1 iwasa.takahito  staff   2459  6  1 08:16 user3
-rw-r--r--  1 iwasa.takahito  staff    582  6  1 08:16 user3.pub

生成された公開鍵をTransfer Familyのユーザー追加機能で登録します。
このタイミングでユーザー毎に紐づくS3バケットやIAMロールなども設定が必要ですが、割愛します。

Apache JMeterへSFTPサンプラーを追加する

macOS版JMeterのデフォルトではFTPサンプラーが存在しますが、SFTPの接続を行うことは出来ません。

JMeterではプラグインを追加することが出来ます。
そして、以下のSSHサンプラープラグインを追加すると、SSHコマンドに加えてSFTPサンプラーが追加されます。

SSH Protocol Supportを追加しましょう。

サンプラー一覧を確認してみると、"SSH SFTP"が追加されています。
本日はこちらを利用します。

SSH SFTPサンプラーを利用する

スレッドの設定は一旦無視してまずはサンプラーを作成します。
サンプラーの設定ですが、主に以下は環境毎に異なります。

  • Server - Hostname
  • Login - User Name
  • Client certificate - SSH Key File
  • File Transfer - 全般

ここでは、ログインパスワードと証明書パスフレーズは省略しています。

こちらの設定で一度テストを実行してみましょう。

テストの実行は正常終了し、ユーザーに割り当てられたS3バケットへはファイルがテスト用のファイルがアップロードされていると思います。

直列に増やす

デフォルトでは、JMeterサンプラーは順番に実行されます。
例えば、以下の順序でサンプラーを配置した場合はuser1, user2, user3と順に実行されます。

テスト自体は完了しファイルはアップロードされています。
テストレポートからサンプル開始時間を確認すると前のサンプルの実行が完了してから次のサンプルが実行されていると思います。

時間についてはCloudWatch Logsに出力されるTransfer Familyのログ日時からも確認が出来ます。
数秒間隔で実行されていますね。

1スレッドで複数のステップを順番に実行したい場合はこの使い方が適していそうです。

並列に増やす

先程まではスレッド数が1でしたが、こちらを3に変更すると、スレッドグループ内のサンプラーが3つのスレッドで実行されます。
必ずしも並列になるわけではないのですが、Ramp-up period (seconds)の時間をかけて3つのスレッドが実行される形になります。
JMeterがこの時間に均等にスレッドが割り振られるようにうまいことやってくれるので、3スレッド3秒にした場合は1秒に1スレッド実行される形となります。

そして、スレッドを増やす形となるので、サンプラーはここでは一つのみにしておきます。
その代わりにユーザーを動的に分ける必要があります。
ユーザーパラメーター機能を使うと、ユーザーの数やパラメータを定義することが出来ます。
ここでは、User1 ~ User3 を定義し、ログインユーザー名と証明書をパラメータ化してみました。

${変数名}でテスト上には設定を行います。

さて、実行してみましょう。
S3バケットには3ユーザー分のファイルがアップロードされています。

CloudWatch Logsの時間を確認してみると先程と異なり並列に実行されていることがわかりますね。

おまけ)3ユーザーパラメータを10スレッドで実行

最後に、先程User1 ~ User3をパラメータで定義し、3スレッド実行したところ、期待どおり3ユーザー分のPUT操作が1回づつされていました。
ここで、ユーザーパラメータは3つ分のままで、以下のようにスレッド数を10にしてみました。
というのも、大量のユーザーをTransfer Familyに作成するのはそれはそれで面倒だなと感じたからです。出来れば省力化したい。

結果としては、ユーザーパラメータはスレッド数に応じて使いまわしされます。
3ユーザーのパラメータで10スレッド実行した場合は、User1が4回、User2とUser3で3回づつ、PUTイベントが発生していました。

PUTの内容に関わらずシンプルに負荷をかけたいだけであれば、1ユーザー用意出来れば実施出来そうですね。

さいごに

本日はTransfer Familyに対して、JMeterで複数ユーザーの一括処理をシミュレートできるのか試してみました。
この記事で確認した結果からするとうまくいきそうです。

Transfer Familyのスケールをコントロール出来ないので何のために?という感じもすると思いますが、マネージドサービスにもスロットル制限などが存在します。
Transfer Familyにも実は一部存在していましてその際の挙動を確認したいと思っていました。そのあたりはおもしろい結果が得られたので次回記事にしたいと思います。

参考