48. FIFOキューはなぜ遅いのか — メッセージグループIDが順序と並列性を分割する
FIFOキューの「順序保証」が実は何のスコープで効いているのか、そしてそのスコープがそのままスループットの上限になる仕組みを、上から下へ図で追っていきます。
① 順序のスコープはメッセージグループID
- 「Within a message group ID, all messages are sent and received in strict order. Messages with different message group IDs may arrive or be processed out of order relative to one another.」(FIFO-queues-understanding-logic.html)
- MessageGroupIdはFIFOでは必須。付けずに送るとアクションが失敗する。(quotas-messages.html / understanding-logic.html)
- グループIDの数に上限はない。「There is no quota to the number of message groups within a FIFO queue.」(sqs-fifo-queues.html)
FIFOの順序は「キュー」ではなく「グループID」というスコープで守られる。グループIDは、順序を保証する範囲を区切る“境界線”だ。
② グループ内は直列化される
- 「No additional messages from the same message group ID are returned until the first message is deleted or becomes visible again.」(understanding-logic.html, Handling visibility timeout)
- 1回のバッチでは同グループ複数件を受け取れるが、後続リクエストはブロックされる。「You may receive multiple messages from the same message group ID in one batch (up to 10 messages in a single call using the MaxNumberOfMessages parameter). However, you can't receive additional messages from the same message group ID in subsequent requests until: The currently received messages are deleted, or They become visible again.」(understanding-logic.html, Receiving messages)
- 別グループは並行処理できる。「FIFO queues allow parallel processing of messages across different message group IDs.」(understanding-logic.html)
- 単一グループなら完全直列。「For strict sequential processing of all messages in a FIFO queue, use a single message group ID for all messages in the queue.」(understanding-logic.html)
グループ内は「in-flight分が片付くまで次を出さない」直列パイプ(1回のバッチでまとめて取ることはできるが、追い越しは決して起きない)。だから並列にさばける数はグループIDの数で決まり、全メッセージを同じグループIDにすれば完全に1本の直列処理になる。
③ DynamoDBのパーティションキーと同じ原理
- 「Amazon SQS uses the value of each message's message group ID as input to an internal hash function. The output value from the hash function determines which partition stores the message.」(high-throughput-fifo.html)
- パーティションはAZ跨ぎで自動複製・自動管理。利用者は管理しない。(high-throughput-fifo.html, Partitions and data distribution)
- 均等分散のため「message group IDs that can have a large number of distinct values」を推奨。(high-throughput-fifo.html)— DynamoDBで「カーディナリティの高いパーティションキーを選べ」と言うのと同じ理由。
グループID=「順序のスコープを区切るキー」であり、同時に「物理パーティションを選ぶハッシュ入力」でもある。DynamoDB編のパーティションキーと同じで、値の種類が少ないと分散が偏り、性能が頭打ちになる。
④ 重複排除 — 5分窓とSHA-256指紋
- 「If you retry the SendMessage action within the 5-minute deduplication interval, Amazon SQS doesn't introduce any duplicates into the queue.」(FIFO-queues-exactly-once-processing.html)
- 重複時もAPIはエラーにならない。「any messages sent with the same MessageDeduplicationId are accepted successfully but aren't delivered during the 5-minute deduplication interval.」(SendMessage APIリファレンス)— 受理はされるが配信されない。プロデューサ側は再送を特別扱いしなくてよい、という冪等化の設計。
- content-based:「use a SHA-256 hash to generate the message deduplication ID using the body of the message—but not the attributes of the message.」(exactly-once-processing.html)
- プロデューサ再送の冪等化:「As long as the producer receives at least one acknowledgment before the deduplication interval expires, retries do not introduce duplicate messages.」(understanding-logic.html)
- 窓の限界:ackを一度も受け取れないまま5分の窓を過ぎて再送すると、SQSは重複を検出できない。「If a message is sent successfully but the acknowledgement is lost and the message is resent with the same MessageDeduplicationId after the deduplication interval, Amazon SQS can't detect duplicate messages.」(SendMessage APIリファレンス)
MessageDeduplicationIdは「冪等キー」の実装そのもの。content-based deduplicationは本文のSHA-256ハッシュ(=内容の指紋)を自動的にその冪等キーに使う。判定は5分の窓の中だけで効く——窓を越えた再送までは守ってくれない。
⑤ 調整コストがTPS上限になる
- 「Amazon SQS FIFO limits are based on the number of API requests, not message limits.」(quotas-messages.html)
- バッチは1リクエスト最大10件。「send, receive, or delete up to 10 messages in a single API request … maximizing throughput while staying within the transaction limits (TPS) for the region」(quotas-messages.html)
- パーティション単位の上限:「Each partition supports up to 3,000 messages per second with batching, or up to 300 messages per second for send, receive, and delete operations in supported regions.」(high-throughput-fifo.html)※具体TPSはリージョン依存。
- 高スループット化の指針:「To enhance request capacity in high throughput FIFO queues, increasing the number of message groups is recommended.」(high-throughput-fifo.html)
- 非高スループットの通常FIFOの基準TPSはリージョンにより異なるため、現行のサービスクォータ表(general/latest/gr/sqs-service)でリージョン別に確認すること。本稿は上限が「APIリクエスト数」で決まり「グループID数(=パーティション数)」でスケールするという構造の説明にとどめる。
FIFOが遅いのは欠陥ではなく、順序と重複排除という保証を支払うための必然的なコスト。上限は「APIリクエスト数」で測られ、バッチ(1回10件)で密度を上げ、グループIDを増やして(=パーティションを増やして)横に広げることで押し上げる。
⑥ グループIDが順序と並列性の分割線
FIFOの性能は、たった一つの設計判断——MessageGroupIdをどれだけ多様にするか——でほぼ決まる。順序を守りたい単位でだけIDを共有し、それ以外は分ける。これがFIFOを「遅すぎず・順序を保つ」設計の勘所であり、DynamoDBのパーティションキー設計と同じ思考をそのまま使える。