はじめに
Amazon SQSの標準キューの順序について、公式の説明では以下のように記載されています。
スタンダードキューでは、できる限りメッセージの順序を保持しますが、複数のメッセージのコピーが順不同で配信される場合があります。
この”できる限り”が気になってみたので動きを見てみました。
得られた知見
- 最初は、順序の初めのほうがとられやすい傾向がある
- 何度も(今回は3度)取得されると、しばらく取得されなくなり、別のメッセージが取得されるようになる
- しばらくたつと、また取得されるようになる
やったこと
検証設定と予想
- 設定
- 標準キュー
- 可視性タイムアウトは3秒
- 1秒ずつ、1つのメッセージを取得
- 標準キュー
- 予想
- 標準キューの順序の保持が強ければ強いほど、最初のメッセージばかり取得される
- 仮に最も強く順序が保持されるならば、(可視性タイムアウトが3秒なので)最初の3つのメッセージのみ取得される、はず
- 標準キューの順序の保持が強ければ強いほど、最初のメッセージばかり取得される
検証準備
SQS作成
標準キューの可視性タイムアウトが3秒であれば、あとは簡易な構成で作成しました。何度も再取得するので、デッドレターキューは設定しないです。
メッセージ登録
0から99までの数値をメッセージとして登録します。以下のコマンドはCloudShellのpython3
で実行しました。(0.5秒のスリープは気持ちの問題です)
import boto3
import time
sqs = boto3.resource('sqs')
queue = sqs.get_queue_by_name(QueueName='test20230130-standard')
for num in range(100):
print(num)
queue.send_message( MessageBody=str(num) )
time.sleep(0.5)
メッセージ取得
1秒ごとにメッセージを1つ取得するのを1000回繰り返し、ファイルに出力しています。実行中がわかるように標準出力にも出しています。
import boto3
import time
sqs = boto3.resource('sqs')
queue = sqs.get_queue_by_name(QueueName='test20230130-standard')
with open('outs.txt', 'w') as f:
for num in range(1000):
for eachMsg in queue.receive_messages(MaxNumberOfMessages=1):
print(eachMsg.body)
f.write("%s\n"%(eachMsg.body) )
print("-----")
time.sleep(1)
なんとなく、先頭のほうがとられている傾向があるかも、と感じます。
QuickSightに取り込み
グラフ化するためファイルを少し加工して、QuickSightのデータセットとしました。
- 1列目に、何回目のメッセージ取得だったか、を付与
- 1から1000
- 3列目に、カウント用の列を付与。
- すべて1にすることで、合計値 = 取得できた回数 になる
- ファイルの先頭に、「0回目の取得」として、「0-99の数値で、カウント列が0」の行を追加
- グラフにした際、X軸にすべての値を出しておきたかったため
- 「何回目のメッセージ取得だったか」について、10刻み、50刻み、100刻みの列を追加
以下のようなデータになります。
グラフにて可視化
全体
まずは全体を見てみます。
全体的にそこそこ取られています。この時点で予想は外れました。
3の倍数の取得が多いようなので、試しに件数でソートしてみます。
かなりきれいな階段状になっています。
0からN(Nを10刻みで50まで)
早々に3回取得されたメッセージはそれ以上取得されず、他のメッセージが取得され始めたことが見て取れます。
0からN(Nを100刻みで500まで)
100刻みでみると、さらに顕著に見えてきました。
Small Multiplesで可視化
少し前に追加されたSmall Multiplesという機能で、10ずつ,50ずつ,100ずつで、どのようになっているか見てみました。
Small Multiplesについては、以下で紹介されています。
10ずつ
最初の200回を、10ずつに見ていくと、徐々に取得されるメッセージが後ろのほうにずれていっているのがわかります。
50ずつ
50ずつで見ると、「最初のほうで3回取得されたものはしばらく取得されなくなり、また取得され始める」というのが見えてきた気がします。
100ずつ
100回ずつでみると、「どの100回においても、3回以上は取得されていない」ということが見えてきました。
おわりに
一文が気になったことを切欠に見ていったら、興味深い傾向が見えました。
若干の優先度が見て取れますし、再取得時も1回程度であれば優先度がそのままのようでしたので、「多数の並列処理で、高めの優先度のメッセージから処理してほしい」などのケースには使えるかな、と思います。
今回の設定でたびたび見えてきた「3の上限」が、「可視性タイムアウトが3秒」と関係があるかは不明です。なので、追跡して調査される方大歓迎です。