FLINTERS Engineer's Blog

FLINTERSのエンジニアによる技術ブログ

Amazon SQSを使ってみた①

こんにちは@toshikimiyagawaです。
梅雨が明け、セミの鳴き声が聞こえ始めて来て、いよいよ夏本番といった感じですね。
今年の夏はいかがお過ごしでしょうか?
私はテニスにジムにいつになく活動的な夏を送っております。

今回はAmazon Simple Queue Service(Amazon SQS)の紹介をして行きたいと思います。

f:id:no_sugiyama:20150722162929p:plain
AmazonSQSは文字通りキューの管理をしてくれるサービスです。
S3同様キューを複数箇所に保存しているので、高い耐障害性を持っています。


使い方

AmazonSQSを利用するためにはSQS以外にclient(ジョブを登録する側)とworker(ジョブを読み込んで処理する側)のふたつが必要です。もちろん一台のサーバに両方の役割を持たせることも可能です。
f:id:no_sugiyama:20150722162939p:plain
SQSからworkerにプッシュで通知が送られるのではなく、workerがキューにジョブが溜まっていないか確認する必要があるというのが特徴です。

workerの処理フロー

f:id:no_sugiyama:20150722162945p:plain
workerの処理フローは左図のようになります。
このプログラムをcronで回したり、daemonとしてバックグラウンドでループを利用して走らせ続けることで、worker側で定期的にジョブの問い合わせを行います。
正常終了しなかった場合はジョブが削除されず残ったままなので、あとで再度該当のジョブを実行することになります。
それじゃあ、「ジョブが削除されず残ったままだと複数のworkerが同じジョブを実行してしまうのではないか?」って疑問が出てくるのではないでしょうか。
これに対する解としてSQSにはVisibility timeoutという概念があります。

Visibility timeout

ジョブの問い合わせをして、ジョブがあった場合workerはメッセージを受け取ります。一方、SQSはそのジョブを一定時間Visibility timeoutというステータスにします。
このステータスの間は他のworkerからジョブの問い合わせがあっても該当ジョブは再度配信されるということがありません。
このステータスの間に処理が完了して該当ジョブを削除すれば、このジョブは再度配信されません。

例えばキューを利用しているバッチ処理が5分くらいかかる場合、Visibility timeoutを10分に設定しておきます。
10分間は再度配信されないので、5分で処理が完了してジョブを削除出来れば、そのジョブは再度配信されることがありません。一方異常終了等でジョブが削除できなかった場合は10分後にVisibility timeoutのステータスが解除され、その後のジョブの問い合わせで再度配信されることになります。

注意点

こんな便利なSQSですが、利用の際にはいくつか注意点があります。

clientがジョブ作成しても、すぐに受け取れるとは限らない
ジョブをSQSに登録するのにタイムラグがあります。ただ、workerが定期的にジョブの問い合わせを続ければ問題ありません。

順序性が保証されない
ジョブの作成リクエストから実際に登録されるまでタイムラグがあるので、作成リクエストの順番通りにジョブが登録されるとは限りません。

ジョブが複数回届く時がある
処理に時間がかかってしまった場合、Visibility timeoutのステータスが解除されて、同一のジョブが複数回届く可能性があります。そうでない場合も稀に複数回届くことがあるそうです。
複数回処理をしても問題ない作りにするか、なんかしらのフラグを持つことで、複数回実行されないような処理にする必要があります。

まとめ

以上のようにSQSはお手軽にジョブキューシステムを作れる、便利なサービスになります。いくつか注意点はあるもののかなりお手軽に使うことができるので、AWSでキューイングしたい方は是非利用してみてはいかがでしょうか。
次回はSQSを利用したサンプルコードの紹介をしたいと思います。