Meta Staff Engineerによるシステムデザイン面接のMessage Queue
Tony Duong
5月 31, 2026 ・ 2 分

Evan(元Meta staff engineer、Hello Interview)によるシステムデザイン面接におけるメッセージキューのメモ — いつ使うか、内部の仕組み、ホワイトボードに描いた後に面接官が掘り下げるトピック。
動機づけの例:写真アップロードアプリ
Instagram風のアップロードで、リサイズ・フィルター・コンテンツモデレーションが必要 — 各ステップに数秒かかると想像する。
同期アーキテクチャの問題:
- レイテンシ — ユーザーがスピナーを6秒以上見続ける
- 脆弱性 — フィルターサービスが処理中にクラッシュすると、アップロード全体が失敗し、これまでの作業も失われる
- バーストトラフィック — 50から5,000 uploads/secへの急増が~200/sec上限のサーバーを圧倒し、リクエストがタイムアウトまたは失敗する
キューによる解決: サーバーがファイルを保存し、メッセージ(「photo 456 needs processing」)をキューに書き込み、即座にクライアントに応答。worker consumerのプールがメッセージをpullして並列処理する。
- アップロードが高速化(保存 + enqueueのみ)
- 障害が隔離される(メッセージが別workerに再配信)
- トラフィックスパイクはキューが深くなるだけで作業をドロップしない — 最悪の場合、処理が遅延する
メッセージキューとは?
producerとconsumerの間のバッファ:
- Producer が作業を生成(アップロードサーバー)
- Consumer が作業を実行(workerプール)
- Producerはメッセージを送って次へ;consumerは自分のペースでpullする
重要な性質:デカップリング — producerとconsumerは互いを知らない。各側を独立してスケールできる。
厨房の比喩: ウェイターが注文をレールに置き、シェフが準備できたら取る。レールがフロントとバックをデカップリングする。
内部の仕組み
Acknowledgements(ack)
consumerがメッセージをpullしても、キューは即座に削除しない。完了時にackを送る必要がある。workerがack前にクラッシュすると、メッセージは再配信される — 何も失われない。
重複処理の防止
workerが処理中(ack前)、メッセージはまだ「キュー内」にある。システムごとに可視性の扱いが異なる:
- SQS: メッセージが設定可能なウィンドウ(例:30秒)他のconsumerから不可視になる
- Kafka: 各パーティションをグループ内のconsumerに1つだけ割り当て
- RabbitMQ: チャネルレベルのprefetch制限とackタイムアウト
配信保証
| 保証 | 意味 | いつ使うか |
|---|---|---|
| At least once(最も一般的) | 各メッセージが≥1回配信;重複の可能性あり | 面接のデフォルト回答 — consumerを冪等にする |
| At most once | Fire-and-forget;取得時に削除 | 数件のイベント損失が許容されるanalytics/メトリクス |
| Exactly once | 正確に1回処理 | 分散システムでは困難;メカニズムを説明できない限り約束しない |
冪等性の例: 「user 123のプロフィール写真をphoto 5に設定」は2回実行しても安全。「post countを1増やす」は安全でない — 「post countを54に設定」を使う。
キューを使うタイミング(4つのシグナル)
- 非同期作業 — ユーザーが結果を即座に必要としない(email、レポート、アップロード)
- バーストトラフィック — リクエストをドロップせずスパイクを吸収
- デカップリング — producerとconsumerのスケーリング/ハードウェア要件が異なる(軽量アップロードサーバー vs GPU重いworker)
- 信頼性 — downstreamが一時的にダウン;キューが復旧までメッセージを保持
落とし穴: 厳しいレイテンシSLA(例:sub-500ms)の同期ワークロードにキューを追加しない。キューは複雑さを増やし、レイテンシ制約を破る。
面接官が好む深掘り
パーティションによるスケーリング
単一キューにはスループット上限がある。パーティションで独立したサブキューに分割し、異なるworkerが並列処理する。
パーティションキーのトレードオフ: user_idでキーするとユーザーごとの順序は保てるが、有名人のパーティションがhotになる。ride_idでキーすると均等分散だがユーザーごとの順序は失う。パーティションキーの選択は意図的な設計判断。
バックプレッシャー
producerがconsumerを上回ると、キューは無限に成長する — キューは容量問題を遅延させるだけで解決しない。300 msg/s in、200 msg/s outなら、永遠に100/sずつ遅れる。
対応:
- キュー深度に基づいてconsumerをオートスケール
- バックプレッシャーを適用 — producerを拒否または減速(「1分後に再試行してください」)
- キュー深度をモニタリング・アラート
Poison messageとdead letter queue(DLQ)
常に失敗する破損画像はpoison messageになる — 永遠にリトライするとconsumerをブロックする。
修正: 最大リトライ回数を設定(例:5回)。使い果たしたら**dead letter queue(DLQ)**へ移動して検査。メインキューは動き続ける。DLQを先に言及するとシニアリティを示せる。
耐久性とフォールトトレランス
モダンなキュー(特にKafka)はメッセージをディスクに永続化し、broker間でレプリケーションする。1つのbrokerがダウンしてもレプリカがデータを保持 — データベースのread replicaと同じ概念。
Kafkaは設定可能なウィンドウ(日、週、永久)でメッセージを保持し、replayを可能にする — consumerが壊れていたりofflineだった場合、1時間前から再処理できる。
一般的な技術
| システム | 最適な用途 |
|---|---|
| Kafka | 高スループット、耐久性、パーティション、replay、consumer group — 面接のデフォルト選択 |
| SQS | AWS fully managed、シンプル — standard(高スループット、best-effort順序)またはFIFO(厳密順序、低スループット);visibility timeout |
| RabbitMQ | exchanges/bindingsによる複雑ルーティングの従来型broker — システムデザイン面接ではあまり見ない |
要点
- メッセージキューはproducerとconsumerをデカップリングし、バーストトラフィックをバッファし、workerプールに作業を分散する
- デフォルトは冪等なconsumerによるat least once delivery
- 面接前にack、可視性/不可視性、パーティション、バックプレッシャー、poison message、DLQを押さえる
- 同期の低レイテンシパスにキューを導入しない
- 1つだけ深く知るなら:Kafka
🌐 Claudeによる翻訳