SQSとCloudWatchとAuto ScalingのようにSQSとAuto Scalingを使って、
複数インスタンスでクロールする仕組みを運用しています。
はじめは、SQSのキューのサイズをCloudWatchに登録のようにCloudWatchのカスタムメトリクスを使って、
SQSのキューのサイズ(メッセージ数)とAuto Scalingの連携を取っていたのですが、
CloudWatchでSQSのメトリクスが取得可能にのように、
SQSのメトリクス自体が標準でサポートされるようになりました。
上記より、現在はAuto Scalingのトリガーとなるメトリクスはカスタムメトリクスではなく、
標準のSQSのメトリクス(ApproximateNumberOfMessagesVisible)を利用するように変更しました。
現状、下記のような仕組みで処理をしています。
- SQSにクロールしたい対象ID一つを一つのメッセージとして一気に登録する。
- SQSのメッセージ数が0以上になると指定した数だけインスタンスが起動し
キューのメッセージを処理(該当IDでクロール)する。 - SQSのメッセージ数が0になったらすべてのインスタンスがターミネートする。
また、下記のようにSQSのメトリクスを監視し通知を受けることで、
クロール処理の状況をリアルタイムに把握できるようにもしています。
○ApproximateNumberOfMessagesVisible
値が0以上になったらクロール処理開始、0にもどったらクロール処理終了として
通知するようにしています。
○NumberOfMessageReceived
値が0以上になったらクロール処理開始、0にもどったらクロール処理が停止(正常もしくは異常)
として通知するようにしています。
詳細はSQSのキューのメッセージが処理されなくなったら通知(CloudWatch)で紹介しています。
以上の内容でもAWSの機能を多数利用した、定時でのバッチ処理システムですが、
さらにやりたいことがあります。
現在SQSへのメッセージ登録は、常時起動しているEC2からcronにて行っているのですが、
Auto Scalingで指定時刻にEC2インスタンスを起動で紹介したようにAuto Scalingを利用すれば、
指定した時刻にインスタンスを立ち上げることができるので、
起動と同時にSQSにメッセージを登録し、登録が終了したらインスタンスを
ターミネートするようにできるのでは、と考えています。
上記のことが可能であれば、定時のバッチ処理を行う時だけ起動するので、サーバが遊ぶこと無く
実施することができるはずです。さらに、サーバの稼動時間がかなり限定される形になるので、
コストも大幅に下げることができると思います。