SQSとCloudWatchとAuto ScalingのようにSQSとAuto Scalingを使って、
複数インスタンスでクロールする仕組みを運用しています。

はじめは、SQSのキューのサイズをCloudWatchに登録のようにCloudWatchのカスタムメトリクスを使って、
SQSのキューのサイズ(メッセージ数)とAuto Scalingの連携を取っていたのですが、
CloudWatchでSQSのメトリクスが取得可能にのように、
SQSのメトリクス自体が標準でサポートされるようになりました。

上記より、現在はAuto Scalingのトリガーとなるメトリクスはカスタムメトリクスではなく、
標準のSQSのメトリクス(ApproximateNumberOfMessagesVisible)を利用するように変更しました。

現状、下記のような仕組みで処理をしています。

  1. SQSにクロールしたい対象ID一つを一つのメッセージとして一気に登録する。
  2. SQSのメッセージ数が0以上になると指定した数だけインスタンスが起動し
    キューのメッセージを処理(該当IDでクロール)する。
  3. SQSのメッセージ数が0になったらすべてのインスタンスがターミネートする。

また、下記のようにSQSのメトリクスを監視し通知を受けることで、
クロール処理の状況をリアルタイムに把握できるようにもしています。

○ApproximateNumberOfMessagesVisible

値が0以上になったらクロール処理開始、0にもどったらクロール処理終了として
通知するようにしています。

○NumberOfMessageReceived

値が0以上になったらクロール処理開始、0にもどったらクロール処理が停止(正常もしくは異常)
として通知するようにしています。
詳細はSQSのキューのメッセージが処理されなくなったら通知(CloudWatch)で紹介しています。

以上の内容でもAWSの機能を多数利用した、定時でのバッチ処理システムですが、
さらにやりたいことがあります。

現在SQSへのメッセージ登録は、常時起動しているEC2からcronにて行っているのですが、
Auto Scalingで指定時刻にEC2インスタンスを起動で紹介したようにAuto Scalingを利用すれば、
指定した時刻にインスタンスを立ち上げることができるので、
起動と同時にSQSにメッセージを登録し、登録が終了したらインスタンスを
ターミネートするようにできるのでは、と考えています。

上記のことが可能であれば、定時のバッチ処理を行う時だけ起動するので、サーバが遊ぶこと無く
実施することができるはずです。さらに、サーバの稼動時間がかなり限定される形になるので、
コストも大幅に下げることができると思います。

こちらの記事はなかの人(suz-lab)監修のもと掲載しています。
元記事は、こちら