📝ノート💻テック

Meta Staff Engineerによるシステムデザイン面接のMessage Queue

Tony Duong

Tony Duong

5月 31, 20262

他の言語:🇫🇷🇬🇧
#system-design#message-queue#kafka#sqs#interview#distributed-systems
Meta Staff Engineerによるシステムデザイン面接のMessage Queue

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つのシグナル)

  1. 非同期作業 — ユーザーが結果を即座に必要としない(email、レポート、アップロード)
  2. バーストトラフィック — リクエストをドロップせずスパイクを吸収
  3. デカップリング — producerとconsumerのスケーリング/ハードウェア要件が異なる(軽量アップロードサーバー vs GPU重いworker)
  4. 信頼性 — 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による翻訳

Tony Duong

著者: Tony Duong

デジタル日記。思考、経験、そして人生についての考え。