Y_Yamashitaのブログ

勉強したことのアウトプット・メモが中心。記事の内容は個人の見解であり、所属組織を代表するものではありません。

【Amazon SQS】FIFOキューのフライトメッセージ上限、密かに上がっている?

(2024年11月27日追記)本ブログを最初に執筆したのは2024年11月8日でしたが、その後AWS公式アナウンスで、メッセージ上限が120,000件まで上がったと発表されました。

aws.amazon.com

下記ブログについては、メッセージ上限の考え方と検証方法の備忘録として残しておこうと思います。

はじめにお断り

今回の内容は個人的に検証したものであり、AWSから公式アナウンスがあったわけではなく、サポートに確認したわけでもないので、正確性については保証できません。 2024年11月8日時点での検証結果であり、今後、仕様が変更される可能性もあります。あらかじめご了承ください。

(2024年11月8日現在)検証した結果、80,000件になっていると思われる

詳細は後述しますが、検証した結果、2024年11月8日現在、上限が20,000件から80,000件になっているように見えました。

(前提)SQS FIFOキューのフライトメッセージについて

Amazon SQS FIFOキューでは、フライトメッセージ(※)の上限は20,000件(上限緩和不可)となっています。 公式ドキュメントにも明記されており、また、マネジメントコンソールでのサービスクォータ画面でも確認できます。

(※)コンシューマが受信したがまだ削除していない、処理中のメッセージ

docs.aws.amazon.com

FIFOキューのフライトメッセージの上限は20,000件で、調整も不可となっている。

フライトメッセージが上限に達している状態で、コンシューマがメッセージを受信しようとすると、エラーは返らずに空の受信となります。

(経緯1)元々は、FIFOキューのフライトメッセージの仕様に関するブログを書くつもりだった

ただ、「処理中メッセージが最大20,000件」という説明は、実は表現が正確ではありません。実際には、以下ドキュメントで説明されている挙動になります。

repost.aws

このドキュメントの説明と例が一番わかりやすかったので、少々長いですが引用します。

FIFO キューは最初の 20,000 件のメッセージを調べ、使用可能なメッセージグループを判別します。最初の 20,000 メッセージのすべてのメッセージグループが、処理中のメッセージが理由でブロックされた場合、最初の 20,000 の後の他のグループからのメッセージは返されません。

例 A
FIFO キューに合計 20,001 件のメッセージがあります。最初の 20,000 件のメッセージはメッセージグループ 1 に属し、最後のメッセージはメッセージグループ 2 に属します。キューからメッセージを受信しようとすると、グループ 1 からのみメッセージが受信されます。連続した ReceiveMessage の API 呼び出しは、空の受信につながります。これは、FIFO がグループ 1 に属するメッセージのみを調べており、そのグループが現在の呼び出しによってブロックされているために発生します。

例 B
FIFO キューに合計 20,000 件のメッセージがあります。最初の 19,999 件のメッセージはメッセージグループ 1 に属し、最後のメッセージはメッセージグループ 2 に属します。キューからメッセージを受信しようとすると、最初の ReceiveMessage 呼び出しはグループ 1 に属するメッセージを取得します。2 回目の ReceiveMessage 呼び出しは、グループ 2 に属するメッセージを取得します。両方のグループが現在の呼び出しによってブロックされるようになったため、追加の ReceiveMessage 呼び出しは空の受信につながります。

図にすると下図のようになります。

例Aの状態


例Bの状態

つまり、処理中メッセージが1件でも、フライトメッセージの上限に達する可能性はある、 ということです。

(経緯2)検証してみたら、取れないはずのメッセージが取れてしまった

前置きが長くなりましたが、今回、上記の挙動を実際に確認してみようと、FIFOキューに合計20,001件のメッセージを格納しました。上述の例Aと同じ状態です。

ところが、実際にメッセージを受信してみたところ、取れないはずのグループ2のメッセージが取れてしまいました。

メッセージ数は20,001件。最初の20,000件にグループID「Group-1」のメッセージが入っている。

Group-1の最初のメッセージを受信。次にメッセージの受信を試みると、応答がないはず。

グループID「Group-2」のメッセージが取れてしまった。

CLIの全体ログは以下です。

CLI全体ログ(クリックまたはタップで詳細表示)

# 最初のメッセージ数は20,001件
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs get-queue-attributes \
> --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo \
> --attribute-names ApproximateNumberOfMessages
{
    "Attributes": {
        "ApproximateNumberOfMessages": "20001"
    }
}

# メッセージを1件受信。Group-1の先頭のメッセージを受信。
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs receive-message \
> --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo \
> --attribute-names All
{
    "Messages": [
        {
            "MessageId": "1c7ed2db-0f04-4df1-ab48-6c8751dbaa19",
            "ReceiptHandle": "AQEBXrV2qtIk325NCvZq2I5Vv1QC8seBR+zF6xtRsdBObXGsiBKMCgtf1VarnW/rvQVPtexbcOghQ53tgR00JTECKH8rFP4R4idCWTa3qhHb8tHIruoQNbw9XEiloXQA6wyjMmOrh+JuvmcK0SjF2sYhETW+Aj4QrYEcTQ0BA8OhQoYWnqBCYfnzcFmpp2+f3JSr2s0cKEc6e2FZKKDtWtA3fht3/g/H81zxCgl88Nt50nfHU21eL0EH8HW64A8q2pCk8C16qHijrXIzGFIiiKpzjZKlBBPgMn+ZjzNl98cJYfgBSIAMz2DFBtaw8LS4ZxQ2",
            "MD5OfBody": "400d5dbb7ad4724862112d5ac3c90127",
            "Body": "{\"no\": 1, \"GroupId\": \"Group-1\"}",
            "Attributes": {
                "SenderId": "AROATO53NFKUERF2JUVY2:sqs_send_message",
                "ApproximateFirstReceiveTimestamp": "1731063743898",
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1731062627765",
                "SequenceNumber": "18889896106417391616",
                "MessageDeduplicationId": "Group-1-1",
                "MessageGroupId": "Group-1",
                "AWSTraceHeader": "Root=1-672deb63-1369059929cd0bc634c96191;Parent=3d25a6765d6e651a;Sampled=0;Lineage=1:5ef77726:0"
            }
        }
    ]
}

# 続けてもう1件受信。Group-2の先頭のメッセージを受信しており、上限に達していないことが分かる。
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs receive-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo --attribute-names All
{
    "Messages": [
        {
            "MessageId": "dac5cb65-1918-439a-8f8a-d9b412f7c6ac",
            "ReceiptHandle": "AQEB14wKCyR5/mNyZ7rG1PfnKf751G5c0lz4kHZyYiStz3e493VaxJJN1AXlP5bs3oGgmPgMlKbDPpo/3YZxrMX3fuB2Fkc/dKV2SrGzWmHjwlsxDyIm+Om+NtEguQ6cENuYJje8ri8OlSA3BMU3u61xJgbM11f/Wj3bdgvihT/nQVzdbNMKt2iWC+N8I5T3N4wx3I6O0pdC602oC37HIbqzFfDD6e1NnMsjv442BBzgTMqq3/H9eh13KjlIcrZfEVxakc+n1PvgU7rFWq4DarvwmI0yA8K3y9LAaS6ABT6CJIFK/8eVkqFMpUWn07PestFa",
            "MD5OfBody": "755a13cc170cce61f2b1e069fe153ebe",
            "Body": "{\"no\": 1, \"GroupId\": \"Group-2\"}",
            "Attributes": {
                "SenderId": "AROATO53NFKUERF2JUVY2:sqs_send_message",
                "ApproximateFirstReceiveTimestamp": "1731063778941",
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1731063060439",
                "SequenceNumber": "18889896217181935616",
                "MessageDeduplicationId": "Group-2-1",
                "MessageGroupId": "Group-2",
                "AWSTraceHeader": "Root=1-672ded14-6892692449fed08e53cfdcd5;Parent=19d34b5cbbddfa64;Sampled=0;Lineage=1:5ef77726:0"
            }
        }
    ]
}

# この時点で2件処理中のため、利用可能メッセージ数は19,999件となる。
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs get-queue-attributes --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo --attribute-names ApproximateNumberOfMessages
{
    "Attributes": {
        "ApproximateNumberOfMessages": "19999"
    }
}
[cloudshell-user@ip-10-132-67-76 ~]$ 


この時点でアップデートの情報はありませんでしたが、密かに上限が上がっているのかもしれないと思い、とりあえずどこまでいけるか確認してみることにしました。

(検証結果)80,001件で取れなくなった

確認した結果は最初に書いた通りですが、80,001件の時にグループ2のデータが取れなくなり、80,000件の時はグループ1、2のデータが取れました。そのため、FIFOキューのフライトメッセージ数上限は80,000件に上がっている(=FIFOキューは、先頭から80,000件のメッセージを調べる)と思われます。

CLI全体ログ(クリックまたはタップで詳細表示)

# 利用可能なメッセージ数は80,001件
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs get-queue-attributes \
> --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo \
> --attribute-names ApproximateNumberOfMessages
{
    "Attributes": {
        "ApproximateNumberOfMessages": "80001"
    }
}

# Group-1 の先頭のメッセージを受信。
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs receive-message \
> --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo \
> --attribute-names All
{
    "Messages": [
        {
            "MessageId": "e1243dc6-b256-4ceb-9fd5-72fe1cb9dcfb",
            "ReceiptHandle": "AQEBKNT+XQTvmmw3SXa9Gm9a4f7FQGs4swz8PYMeH7fkqmAZuS3ZMnagaWBAExcAIYgG+2ITJrqH3zlVbfRJ2oceOeMoHCc6I2hkePAswIOC3qOkmrLkKBzW91tP5OvEqcOrbK5wPw0yFWYyre/gZBK8aH5HlsaVz0D19wlshvExpwKVluUuHBqQEJFtO3Gu29WNcyiZf7NtNpkzOiMfb/2ZFdnPT1fKdTDQkBSbL26wiagLntaQWk4pLe34fMq/5641bZ7vj6X95jog5FhshY4V6HgBvE6Qjgtw1bow2acpaiLlIp1/okmcqt4EkXLm6Li8",
            "MD5OfBody": "2f5aed1c7b905366c62aa5a3f4c806f1",
            "Body": "{\"no\": 2, \"GroupId\": \"Group-1\"}",
            "Attributes": {
                "SenderId": "AROATO53NFKUERF2JUVY2:sqs_send_message",
                "ApproximateFirstReceiveTimestamp": "1731067066944",
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1731062627776",
                "SequenceNumber": "18889896106420207616",
                "MessageDeduplicationId": "Group-1-2",
                "MessageGroupId": "Group-1",
                "AWSTraceHeader": "Root=1-672deb63-1369059929cd0bc634c96191;Parent=3d25a6765d6e651a;Sampled=0;Lineage=1:5ef77726:0"
            }
        }
    ]
}

# 続けてメッセージの受信を試みると、Group-2のメッセージは取れず、空の応答が返ってきた。
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs receive-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo --attribute-names All
[cloudshell-user@ip-10-132-67-76 ~]$ 
[cloudshell-user@ip-10-132-67-76 ~]$ 

# この時点で利用可能メッセージ数は80,000件(加えて、処理中が1件あり)
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs get-queue-attributes \
> --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo \
> --attribute-names ApproximateNumberOfMessages
{
    "Attributes": {
        "ApproximateNumberOfMessages": "80000"
    }
}

# ここで、先ほど受信したGroup-1の先頭メッセージを削除
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs delete-message \
> --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo \
> --receipt-handle AQEBKNT+XQTvmmw3SXa9Gm9a4f7FQGs4swz8PYMeH7fkqmAZuS3ZMnagaWBAExcAIYgG+2ITJrqH3zlVbfRJ2oceOeMoHCc6I2hkePAswIOC3qOkmrLkKBzW91tP5OvEqcOrbK5wPw0yFWYyre/gZBK8aH5HlsaVz0D19wlshvExpwKVluUuHBqQEJFtO3Gu29WNcyiZf7NtNpkzOiMfb/2ZFdnPT1fKdTDQkBSbL26wiagLntaQWk4pLe34fMq/5641bZ7vj6X95jog5FhshY4V6HgBvE6Qjgtw1bow2acpaiLlIp1/okmcqt4EkXLm6Li8

# この時点でメッセージ数は80,000件。処理中メッセージはゼロ。
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs get-queue-attributes --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo --attribute-names ApproximateNumberOfMessages{
    "Attributes": {
        "ApproximateNumberOfMessages": "80000"
    }
}

# 改めてメッセージを受信。まずGroup-1の、この時点での先頭メッセージを受信。
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs receive-message \
> --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo \
> --attribute-names All
{
    "Messages": [
        {
            "MessageId": "9ea61c66-2790-4274-ad06-0161bd8176c8",
            "ReceiptHandle": "AQEBbLwz49k9OcgL5JnS669kDHXQnkN3zTl0PMn826K5hMBv8yArV96BAnP7mIJqarO5sqaZgTa4vE/CyjPWqhZR2HsDR9xbGyeZQGjhPnVw/gueEt+4dL049Ww3dDAzdzNs91vxzdAGkBiCUrnkAO5eV3ZzVep1IQU46KNCH3WcW87rf08hKhp8sTC3qeyBQVYxP67M7bUSbbxqQYuFEgeCIBkY+RQFA+UwvCM8sfJrIEcuhoQbltWxqCGr1AO6GorG/O7P1GvHDpWrtiYJZXdbg77XpLNLNzOZjihcqqCReo3ttJcaa9U+lCWgW1Ytw1rA",
            "MD5OfBody": "1ced907ec8402eb02fdf04798d044aa4",
            "Body": "{\"no\": 3, \"GroupId\": \"Group-1\"}",
            "Attributes": {
                "SenderId": "AROATO53NFKUERF2JUVY2:sqs_send_message",
                "ApproximateFirstReceiveTimestamp": "1731067276748",
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1731062627788",
                "SequenceNumber": "18889896106423279616",
                "MessageDeduplicationId": "Group-1-3",
                "MessageGroupId": "Group-1",
                "AWSTraceHeader": "Root=1-672deb63-1369059929cd0bc634c96191;Parent=3d25a6765d6e651a;Sampled=0;Lineage=1:5ef77726:0"
            }
        }
    ]
}

# この時点で利用可能メッセージ数は79,999件(加えて、処理中が1件あり)
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs get-queue-attributes --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo --attribute-names ApproximateNumberOfMessages
{
    "Attributes": {
        "ApproximateNumberOfMessages": "79999"
    }
}

# 続けてメッセージを受信すると、Group-2の先頭のメッセージを受信しており、上限に達していないことが分かる。
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs receive-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo --attribute-names All
{
    "Messages": [
        {
            "MessageId": "074b08e4-c827-4dd9-85fe-2f097cb229f8",
            "ReceiptHandle": "AQEBetprwV0P3Hiv/YwxQiU9XJiX6l0yqhU/FpceH0dS/Y2k7+rum6bD5wtTtasps3/m5+kSAq4EkJRXHGiD6rjQckgApL3ay7SeQ0NX7zZC4m9nKzqFDAa0QW+ekJrC3Msbc/6T185AFhZDzDD6+uifT2JwPXnt9xcToAIVUjjpQNFN0BmySS/vQrn/l75g7OLoLtcqpYaQZflqanSGMeA2pX8IE5ZDoryL79R3BRQ5CXa3DhJjPgrjzAASGBOKhhDEvLQvdKa3OWoaCIYZd+zqwL6jWoIpo9HcfTFI+GX3Ogfbbjop8tFM50S/UteyB8AK",
            "MD5OfBody": "755a13cc170cce61f2b1e069fe153ebe",
            "Body": "{\"no\": 1, \"GroupId\": \"Group-2\"}",
            "Attributes": {
                "SenderId": "AROATO53NFKUERF2JUVY2:sqs_send_message",
                "ApproximateFirstReceiveTimestamp": "1731067332192",
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1731067016288",
                "SequenceNumber": "18889897229879279616",
                "MessageDeduplicationId": "Group-2-1",
                "MessageGroupId": "Group-2",
                "AWSTraceHeader": "Root=1-672dfc88-315f37d33795c47624493165;Parent=12854939ef3ced84;Sampled=0;Lineage=1:5ef77726:0"
            }
        }
    ]
}

# この時点で2件処理中のため、利用可能メッセージ数は79,998件となる。
[cloudshell-user@ip-10-132-67-76 ~]$ aws sqs get-queue-attributes --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo --attribute-names ApproximateNumberOfMessages
{
    "Attributes": {
        "ApproximateNumberOfMessages": "79998"
    }
}
[cloudshell-user@ip-10-132-67-76 ~]$ 

(オマケ1)今回の検証方法

オマケとして、今回の検証でのメッセージ送信方法、受信方法についてご紹介します。

メッセージの送信はLambdaで実施

メッセージの送信はLambdaで行いました。コードは以下です。

import os
import boto3
import json
import logging

logger = logging.getLogger()
logger.setLevel("INFO")
queue_url = os.environ["SQS_QUEUE_URL"] #Lambdaの環境変数にSQSのURLを設定
SQSClient = boto3.client("sqs")

def send_message(no: int, groupid: str):
    result = SQSClient.send_message(
        QueueUrl=queue_url,
        MessageGroupId=groupid,
        MessageDeduplicationId=f"{groupid}-{no}",
        MessageBody=json.dumps({"no": no, "GroupId": groupid}),
    )
    logger.info("Sent message: no:%s\tGroupId:%s\tMsgId:%s", no, groupid, result['MessageId'])

def lambda_handler(event, context):
    frequency = event["frequency"] #メッセージを送る回数
    groupid = event["groupid"] #メッセージに付与するグループID
    start_no = event["start_no"] #メッセージに付与する番号の最初の数字
    logger.info("Start to put SQS messages.")

    for n in range(frequency):
        send_message(no=start_no+n, groupid=groupid)

    logger.info("End to put SQS messages.")

Lambdaに渡すイベントJSONのサンプルは以下です。

{
  "frequency": 20000,
  "groupid": "Group-1",
  "start_no": 1
}

上記のJSONの場合、Group-1 というグループIDのメッセージを、番号1から始めて20,000件送信します。

メッセージの受信・削除はCloudShellで実施

メッセージの受信は、CloudShell上でAWS CLIコマンドで実施しました。

# 利用可能なメッセージ数の表示
aws sqs get-queue-attributes \
--queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo \
--attribute-names ApproximateNumberOfMessages

# メッセージの受信
aws sqs receive-message \
--queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo \
--attribute-names All

# メッセージの削除
aws sqs delete-message \
--queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/yamashita-test-queue.fifo \
--receipt-handle <receipt-handleの値>

(オマケ2)今回の検証にあたり参考にさせていただいたサイト

最後にもう一つオマケとして、今回の検証にあたり参考にさせていただいたサイトのリンクをご紹介します。

tech.unifa-e.com

こちらのサイトのおかげで、メッセージ上限の仕様についての理解が間違っているわけではないと確信できましたし、検証の具体的な方法についてもかなり参考にさせていただきました。大変助かりました。

まとめ

というわけで、FIFOキューのフライトメッセージ上限が上がっているっぽい、というブログでした。
上限が拡大したなら、少し待てば公式アナウンスが出るはずなので、おとなしくそれを待てば良いのですが、ちょうどSQSの検証している最中で気になったので思わず調べてしまいました。おかげでSQSの知見が増えたので、良しとします。

繰り返しになりますが、公式のアナウンスが出るまでにまた仕様が変わるかもしれないため、その点はご認識いただければ幸いです。

今回のブログは以上です。少しでも参考になることがあれば幸いです。