SQS
Q1. 週に1度、SQSキューからメッセージを取得して処理するバッチジョブを作成した。2週間後、メッセージが一部処理されていないことに気づいた。原因は何か?SQSの設定はデフォルト。
A1. メッセージが処理される前に削除されている
- SQSは一定期間後に自動でメッセージを削除している(Message Retention Period : Default 4 Daysで設定)
- キューイングされたメッセージが削除されるのは2パターン
- アプリケーションで明示的に削除
- Message Retention Period経過後に自動削除
- デフォルトは4日になっているので、バッチが週に1度しか動かないなら設定値を伸ばしましょう
Q2. SQSとEC2を用いたチケット予約システムで、キューのポーリングがループしすぎており、空のレスポンスに対するオペレーションのコストが高い。どうすれば良いか?
具体的にはReceiveMessageWaitTimeSecondsをどう設定すれば良いか。
A2. ReceiveMessageWaitTimeSeconds>0 にしてロングポーリングにする
- SQSはデフォルトでショートポーリングが設定されていて、サーバのサブセットのみを照会して(?)、レスポンスに含めることができるメッセージがあるか判断する
- ショートポーリングはhigher througputが必要な場合に有効
- コストを下げるためにはロングポーリングの設定が有効
- RMWTSの値でポーリングのshort/longを決定できる
- デフォルトはゼロ(=short polling)
- まとめると、LongPollingはSQSに対して、メッセージが利用可能になるまで待つことを許可することで、空のレスポンスを削減して、結果コストを下げる
Q3.あるアプリがfanoutメッセージパターンを利用している。アプリでの注文ごとにSNStopicにメッセージが送られ、並列化された非同期処理のために複製されたのちにSQSキューにプッシュされる。SpotEC2でSQSキューからメッセージを取得して処理している最中に、EC2が異常停止した。この場合、SQSメッセージはどのようになるか?
A3. message visibility timeout expiresした時、メッセージは他のEC2インスタンスから処理可能になる。
- SQSは分散システムのため(利用者(ここではEC2)がメッセージを取得したかどうかを保証せず)自動的にメッセージを削除しない。
- 利用者はメッセージを取得して処理した後に明示的に削除しなければならない。
- 他の利用者がメッセージを重複して処理することを防ぐために、SQSはvisibility timeoutを設定する。(デフォルト30秒、最大12時間)
Q4. ウェブオーダーシステムでSQSを使っている。ある日、注文が2回処理されているものが大量にあることに気づいた。今後、これが起こらないようにするにはどうすればよいか?
- SQSの代わりにAmazon Simple Workflowを利用する
- retention periodを設定する
- visibility timeoutを設定する
- message sizeを変更する
A5. 1
- SQSの問題と見せかけて、SWFの問題(SQS神話崩壊)
- SWFではタスクが一度処理されると複製されることはない
- 多数のワーカーが存在しても、SWFはひとつのタスクをひとつのワーカーに割り振る
- さらに、SWFは未解決の決定タスクを同時に最大ひとつのみ保持する
- retention periodはメッセージ削除までの時間を決定するに過ぎないので、保持期間中に再度処理されると結局、処理が重複する
- visibility timeoutは一度に複数のワーカーがメッセージを処理することを防ぐだけなので解決にならない
- メッセージサイズは今回は関係なし
SWF
Q1. 注文処理システムでSimple Workflowを利用している。ある日、いくつかの注文が4週間に渡って滞留していることに気づいた。原因は?
- workflowが15-day maximum workflow execution timeを超えて削除された
- workflowが14-day maximum workflow execution timeを超えて削除された
- SWFがactivity taskからの手動のインプットを待っていた
- SWFをリスタートする必要がある
A1. 3
- デフォルトではworkflowは最大1年間実行できる(よって1,2はNG)
- SWFを手動でリスタートすることは不可能