Dev Study
AWSサービスの内部原理 コース

48. FIFOキューはなぜ遅いのか — メッセージグループIDが順序と並列性を分割する

FIFOキューの「順序保証」が実は何のスコープで効いているのか、そしてそのスコープがそのままスループットの上限になる仕組みを、上から下へ図で追っていきます。

① 順序のスコープはメッセージグループID

FIFOキュー1本のキュー
横並び=独立したスコープ
Group Aa1→a2→a3
この中は厳密順
Group Bb1→b2
この中は厳密順
Group Cc1→c2→c3
この中は厳密順
順序の境界同一ID内は順序保証 / A・B・C相互の順序は無保証
  • 「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は、順序を保証する範囲を区切る“境界線”だ。

② グループ内は直列化される

Group Aa1・a2・a3が順に待機
どちらかで解放
in-flight受信分がコンシューマで処理中(不可視)
この間、後続リクエストに Group A の続きは返されない
Group A の続きが配信可能に
DeleteMessage受信分を削除
可視性TO満了タイムアウトで再可視化
次の配信へ以降も「in-flight分が片付くまで次を出さない」を繰り返す
  • 「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のパーティションキーと同じ原理

MessageGroupId例: "item0"
出力値で振り分け
内部ハッシュ関数出力値でパーティションを選ぶ
DynamoDBのパーティションキーと同じ発想
同一グループは同じパーティションに集まる
Partition 1AZ跨ぎで複製
Partition 2AZ跨ぎで複製
Partition 3AZ跨ぎで複製
順序の保存先同じパーティションの中で順序が保たれる
  • 「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指紋

SendMessageプロデューサが送信
SQSが直近5分の dedup ID を照合
明示指定自分で冪等キーを渡す
content-based本文のSHA-256を自動採用
属性は含まない・本文のみ
初出キューに格納
5分以内に既出呼び出しは成功扱いのまま、キューには追加しない
  • 「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上限になる

標準キューほぼ無制限のAPI/秒
順序も重複排除も無いから調整コストが無い
引き上げ策は2つ
FIFOキュー上限は「APIリクエスト数」でカウントされる
密度を上げる/横に広げる
バッチ1 APIコールで最大10件を送受信・削除
高スループットグループIDを増やす→パーティションが増える
上限を押し上げ各パーティション: バッチ有り最大3,000 msg/s・非バッチ最大300 msg/s(supported regions)
  • 「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が順序と並列性の分割線

MessageGroupId1本の設計判断
IDの多様性が性能を決める
順序のスコープグループ内=直列
並列性の単位グループ数=並列度
+ 別軸の保証
全部同じID完全直列(最も遅い)
IDを多く高並列(パーティション分散でスケール)
重複排除MessageDeduplicationId が5分窓で冪等化

FIFOの性能は、たった一つの設計判断——MessageGroupIdをどれだけ多様にするか——でほぼ決まる。順序を守りたい単位でだけIDを共有し、それ以外は分ける。これがFIFOを「遅すぎず・順序を保つ」設計の勘所であり、DynamoDBのパーティションキー設計と同じ思考をそのまま使える。

公式ドキュメントで詳しく ↗