Amazon SQS に基づくスケーリング
重要
以下の情報とステップは、CloudWatch にカスタムメトリクスとして公開する前に ApproximateNumberOfMessages
キュー属性を使用してインスタンスごとの Amazon SQS キューバックログを計算する方法を示しています。ただし、Metric Math を使用することで、独自のメトリクスを公開するコストと労力を節約できるようになりました。詳細については、「Metric Math を使用する、Amazon EC2 Auto Scaling のターゲット追跡スケーリングポリシーを作成する」を参照してください。
このセクションでは、Amazon Simple Queue Service (Amazon SQS) キュー内のシステムロードの変化に応じて Auto Scaling グループをスケーリングする方法について説明します。Amazon SQS の使用方法の詳細については、「Amazon Simple Queue Service 開発者ガイド」をご参照ください。
Amazon SQS キューのアクティビティに応じたスケーリングを検討するシナリオはいくつかあります。例えば、ユーザーがイメージをアップロードしてオンラインで使用できるウェブアプリがあるとします。このシナリオでは、各イメージはサイズ変更されエンコードされてから公開されます。このアプリケーションは、標準的なアップロード速度を処理するように設定された Auto Scaling グループ内の EC2 インスタンスで実行されます。異常なインスタンスは終了され置き換えられて、常に現在のインスタンスレベルが維持されます。このアプリは処理のためイメージの raw ビットマップデータを SQS キューに配置します。イメージが処理され、処理されたイメージはユーザーから確認できる場所に発行されます。このシナリオのアーキテクチャは、イメージのアップロード数が時間の経過とともに変化しない場合に有効です。ただし、アップロード数が時間の経過とともに変化する場合は、動的スケーリングを使用して Auto Scaling グループのキャパシティーを拡張することを検討してください。
適切なメトリクスを用いたターゲット追跡を使用する
カスタム Amazon SQS キューメトリクスに基づくターゲット追跡スケーリングポリシーを使用する場合、動的スケーリングはアプリケーションの需要曲線に合わせてより効果的に調整できます。ターゲット追跡のメトリクスの選択の詳細については、「メトリクスを選択する」を参照してください。
ターゲット追跡に ApproximateNumberOfMessagesVisible
のような CloudWatch Amazon SQS メトリクスを使用する場合の問題は、キュー内のメッセージの数が、キューからのメッセージを処理する Auto Scaling グループのサイズに比例して変化しない可能性があることです。これは SQS キューにあるメッセージの数のみでは、必要なインスタンスの数は定義されないためです。Auto Scaling グループ内のインスタンスの数は複数の要因によって決まります。例えば、メッセージを処理するためにかかる時間や、許容されるレイテンシー (キュー遅延) の量などです。
解決策は、インスタンスあたりのバックログのメトリクスを使用して、ターゲット値を維持するインスタンスあたりの適正バックログにすることです。これらの数は以下のように計算できます。
-
インスタンスあたりのバックログ: インスタンスあたりのバックログを計算するには、まず
ApproximateNumberOfMessages
キュー属性を使用して SQS キューの長さ (このキューから取得できるメッセージ数) を決定します。その数をフリートの実行キャパシティーで割ります。Auto Scaling グループの場合、これはInService
状態にあるインスタンスの数です。これでインスタンスあたりのバックログを得ることができます。 -
インスタンスあたりの適正バックログ: ターゲット値を計算するには、まずレイテンシーの点でアプリケーションが受け付けることができる数を決定します。次に、適切なレイテンシー値を取ってそれを EC2 インスタンスがメッセージを処理する平均所要時間で割ります。
例として、現在、10 個のインスタンスを持つ Auto Scaling グループがあり、キュー (ApproximateNumberOfMessages
) にある可視メッセージの数が 1,500 であるとします。メッセージあたりの平均処理時間が 0.1 秒で、最長許容レイテンシーが 10 秒の場合、インスタンスあたりの許容バックログは 10/0.1、つまり 100 メッセージとなります。つまり、100 がターゲット追跡ポリシーのターゲット値です。インスタンスあたりのバックログがターゲット値に達すると、スケールアウトイベントが発生します。インスタンスあたりのバックログが既に 150 メッセージ (1,500 メッセージ/10 インスタンス) あるため、グループは、ターゲット値との比例を維持するために 5 インスタンス分スケールアウトします。
次の手順は、カスタムメトリクスを公開し、これらの計算に基づいてスケーリングするように Auto Scaling グループを設定するターゲット追跡スケーリングポリシーを作成する方法を示しています。
重要
コストを削減するには、必ず代わりに Metric Math を使用してください。詳細については、「Metric Math を使用する、Amazon EC2 Auto Scaling のターゲット追跡スケーリングポリシーを作成する」を参照してください。
この設定は 3 つの主要な部分で構成されます。
-
SQS キューからのメッセージを処理するために EC2 インスタンスを管理する Auto Scaling グループ。
-
Amazon CloudWatch に送信するカスタムメトリクス。Auto Scaling グループの EC2 インスタンスごとにキュー内のメッセージの数を測定します。
-
ターゲット追跡ポリシー。カスタムメトリクスと一連のターゲット値に基づいて Auto Scaling グループをスケールするように設定します。CloudWatch アラームでスケーリングポリシーを呼び出します。
次の図は、この設定のアーキテクチャを示しています。

制限事項と前提条件
この設定を使用するには、次の制限事項に注意する必要があります。
-
カスタムメトリクスを CloudWatch に発行するには、AWS CLI または SDK を使用する必要があります。その後、AWS Management Console を使用してメトリクスを監視できます。
-
Amazon EC2 Auto Scaling コンソールには、カスタムメトリックスを使用するターゲット追跡スケーリングポリシーはありません。スケーリングポリシーのカスタムメトリックスを指定するには、AWS CLI または SDK を使用する必要があります。
次のセクションでは、実行する必要があるタスクに AWS CLI を使用するよう指示しています。例えば、キューの現在の使用状況を反映するメトリックスデータを取得するには、SQS get-queue-attributes コマンドを使用します。CLI がインストールされ、設定されていることを確認します。
開始する前に、使用する Amazon SQS キューが必要です。以下のセクションは、キュー (標準または FIFO)、Auto Scaling グループ、キューを使用するアプリケーションを実行している EC2 インスタンスがあることを前提としています。Amazon SQS の詳細については、「Amazon Simple Queue Service Developer Guide」を参照してください。
Amazon SQS に基づくスケーリングを設定
ステップ 1: CloudWatch カスタムメトリクスを作成する
カスタムメトリックスは、選択したメトリックス名と名前空間を使用して定義されます。カスタムメトリクスの名前空間を AWS/
で始めることはできません。カスタムメトリクスの発行に関する詳細については、Amazon CloudWatch ユーザーガイドのトピック「カスタムメトリクスをパブリッシュする」を参照してください。
以下の手順に従って、AWS アカウントの情報を最初に読み込んでカスタムメトリクスを作成します。次に、前のセクションで推奨されたようにインスタンスメトリクスごとにバックログを計算します。最後に、この数字を CloudWatch に 1 分間隔で発行します。可能な限り、システム負荷の変化に迅速に対応できるように、メトリクスを 1 分単位でスケーリングすることを強くお勧めします。
CloudWatch カスタムメトリクスを作成するには (AWS CLI)
-
SQS get-queue-attributes コマンドを使用して、キューで待機しているメッセージ数を取得します (
ApproximateNumberOfMessages
)。aws sqs get-queue-attributes --queue-url
https://sqs.region.amazonaws.com/123456789/MyQueue
\ --attribute-names ApproximateNumberOfMessages -
describe-auto-scaling-groups コマンドを使用して、グループの実行キャパシティーを取得します。これは
InService
ライフサイクル状態にあるインスタンスの数です。このコマンドは、Auto Scaling グループのインスタンスとそのライフサイクル状態を返します。aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names
my-asg
-
キューからの取得に使用できるメッセージの概数をグループの実行キャパシティで除算して、インスタンスあたりのバックログを算出します。
-
1 分ごとに実行してインスタンスあたりのバックログの値を取得し、それを CloudWatch カスタムメトリクスに公開するスクリプトを作成します。カスタムメトリクスを公開する際は、そのメトリクスの名前、名前空間、単位、値、および 0 以上のディメンションを指定します。ディメンションには、そのディメンションの名前と値を含みます。
カスタムメトリクスを公開するには、
斜体
で示されたプレースホルダーの値を好みのメトリクス名、メトリクスの値、名前空間 (「AWS
」で開始することはできません)、ディメンション (オプション) に置き換えてから、次の put-metric-data コマンドを実行します。aws cloudwatch put-metric-data --metric-name
MyBacklogPerInstance
--namespaceMyNamespace
\ --unit None --value20
--dimensionsMyOptionalMetricDimensionName=MyOptionalMetricDimensionValue
アプリケーションが希望するメトリクスを出力すると、データが CloudWatch に送信されます。メトリクスは CloudWatch コンソールで表示できます。メトリクスにアクセスするには、AWS Management Console にログインして CloudWatch ページに移動します。その後、メトリクスを表示するには、メトリクスページに移動するか、検索ボックスを使用してメトリクスを検索します。メトリクスの表示の詳細については、Amazon CloudWatch ユーザーガイドの「使用可能なメトリクスの表示」を参照してください。
ステップ 2: ターゲット追跡スケーリングポリシーを作成する
この時点で、作成したメトリクスをターゲット追跡スケーリングポリシーに追加できるようになっています。
ターゲット追跡スケーリングポリシーを作成するには (AWS CLI)
-
以下の
cat
コマンドを使用して、スケーリングポリシーのターゲット値と、カスタムメトリクスの仕様を指定する JSON ファイル (名前:config.json
) をホームディレクトリに保存します。斜体
で示されたプレースホルダは、実際の値に置き換えます。TargetValue
には、インスタンスあたりの適正バックログメトリックスを計算して、それを入力します。この数を計算するには、上記のセクションで説明しているとおり、標準のレイテンシー値を決定し、その値をメッセージの処理にかかる平均時間で割ります。ステップ 1 で作成したメトリクスにディメンションを指定しなかった場合は、カスタムメトリクスの仕様にディメンションを含めないでください。
$ cat ~/config.json { "TargetValue":
100
, "CustomizedMetricSpecification":{ "MetricName":"MyBacklogPerInstance
", "Namespace":"MyNamespace
", "Dimensions":[ { "Name":"MyOptionalMetricDimensionName
", "Value":"MyOptionalMetricDimensionValue
" } ], "Statistic":"Average", "Unit":"None" } } -
ut-scaling-policy コマンドを使用して、前のステップで作成した
config.json
と共に、スケーリングポリシーを作成します。aws autoscaling put-scaling-policy --policy-name
sqs100-target-tracking-scaling-policy
\ --auto-scaling-group-namemy-asg
--policy-type TargetTrackingScaling \ --target-tracking-configurationfile://~/config.json
これにより、2 つのアラーム (スケールアウトとスケールイン) が作成されます。これにより、CloudWatch に登録されたポリシーの Amazon リソースネーム (ARN) も返されます。CloudWatch はこれを使用して、メトリクスのしきい値が超過するたびにスケーリングを呼び出します。
ステップ 3: スケーリングポリシーをテストする
設定が完了したら、スケーリングポリシーが機能していることを確認します。SQS キュー内のメッセージ数を増やし、Auto Scalingグループが追加の EC2 インスタンスを起動したことを確認することによってテストできます。SQS キュー内のメッセージ数を減らし、Auto Scaling グループが EC2 インスタンスを終了したことを確認することによってもテストできます。
スケールアウト機能をテストするには
-
「キューへのメッセージの送信 (コンソール)」の手順に従って、キューにメッセージを追加します。インスタンスあたりのバックログメトリックスがターゲット値を超えるようにキュー内のメッセージ数を増やしたことを確認します。
この変更により、アラームの呼び出しに数分かかる場合があります。
-
describe-auto-scaling-groups コマンドを使用して、グループがインスタンスを起動したことを確認します。
aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name
my-asg
スケールイン機能をテストするには
-
「メッセージの受信と削除 (コンソール)」の手順に従い、キューからメッセージを削除ます。インスタンスあたりのバックログメトリックスがターゲット値を下回るようにキュー内のメッセージ数を減らしたことを確認します。
この変更により、アラームの呼び出しに数分かかる場合があります。
-
describe-auto-scaling-groups コマンドを使用して、グループがインスタンスを終了したことを確認します。
aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name
my-asg
Amazon SQS とインスタンスのスケールイン保護
インスタンスの削除時に処理されていなかったメッセージは、SQS キューに戻され、まだ実行中である別のインスタンスで処理されます。長時間実行されるタスクが実行されるアプリケーションでは、オプションでインスタンススケールイン保護を使用して、Auto Scaling グループのスケールイン時に終了するキューワーカーを制御できます。
次の擬似コードは、長時間実行されるキュー駆動のワーカープロセスをスケールイン終了から保護する方法の 1 つを示しています。
while (true) { SetInstanceProtection(False); Work = GetNextWorkUnit(); SetInstanceProtection(True); ProcessWorkUnit(Work); SetInstanceProtection(False); }
詳細については、「インスタンスの終了を正常に処理するために、Amazon EC2 Auto Scaling でアプリケーションを設計する」を参照してください。