メインコンテンツへ移動
JA
ホーム / 技術ブログ / 高負荷に耐えるキュー:公平性と復旧をどう設計するか
2026年6月22日 · Z-SOFT Admin · 読了目安 5 分

高負荷に耐えるキュー:公平性と復旧をどう設計するか

キューを有限な処理能力として設計し、一社の大量処理が他社を止めないようにします。

記事一覧へ戻る

要点: キューが吸収できるのは短い負荷の波だけです。無制限に受け入れれば、過負荷が長い待ち時間へ変わるだけです。

この記事の用語: DLQ:繰り返し失敗したジョブを隔離するキュー。冪等キー:重複処理を防ぐ識別子。

現場の課題

キューの長さだけを見てワーカーを増やすと、DBや外部サービスを過負荷にします。大量処理を行う一つのテナントが、共有能力を使い切る可能性もあります。

単純な対策だけでは不十分な理由

10通のメールと10件の動画エンコードでは負荷が違います。件数より種別別の最古待ち時間を見て、DBや外部サービスの実能力を超えない同時実行上限を置きます。

処理フロー

プロデューサー
受付とPriority
ブローカー
分離キュー
ワーカー
制限同時実行数
依存サービス
保護Budget
受付時とワーカーの各依存サービスで処理能力を制限します。

アーキテクチャ上の判断

障害領域を分離

Interactive、Bulk、外部連携を別キューまたはプールに分けます。

テナント公平性を強制

テナント別In-flight QuotaとWeighted Schedulingを使います。

再試行を有限化

一時・恒久エラーを分類し、回数、総期限、DLQ ポリシーを設定します。

さらに深く考える

Backpressureは受付から

予測遅延が目標を超えたら低Priority処理を拒否・延期・劣化します。

復旧を段階化

Outage後は依存サービス 上限を守りRampで滞留ジョブを解消します。

実装手順

  1. ジョブを遅延目標、処理コスト、テナントで分類してからキューへ入れます。
  2. 各ジョブへ冪等キー、再試行上限、最終失敗時の方針を持たせます。
  3. 最古ジョブの待ち時間でスケールし、DBと外部サービスの安全上限を超えないようにします。

コード例: Leaseを使う冪等 ジョブ

job = broker.receive(visibilityTimeout = 60s)
if inbox.exists(job.id): ACK
with dependencyLimiter.acquire(job.kind):
  result = handle(job.payload)
  transaction(inbox.insert(job.id), save(result))
ACK

処理権限の有効時間は通常実行より長くし、長時間ジョブはHeartbeatで延長します。

想定しておく障害

  • 処理中にVisibilityが切れ、重複実行されます。
  • 依存サービスの部分復旧で再試行Stormが起きます。
  • DLQが無監視で増え、恒久的な欠落になります。

監視すべきこと

指標何が分かるか
種別別最古ジョブの待ち時間遅延目標違反を直接示します。
試行数と失敗理由再試行の有効性を示します。
テナント別In-flight一部Tenantによる資源占有を可視化します。

設計の検証方法

  • DBをThrottleしBudget内に収まるか確認します。
  • 一つのテナントのBulk中もInteractive目標を維持します。
  • ジョブ中にLeaseを切り、結果が一つか確認します。

本番導入の進め方

最古待ち時間と再試行理由を先に測ります。高リスクなジョブを別プールへ分離し、観測のみの上限から少数テナントへ適用し、DLQからの再実行も訓練します。

本番前チェックリスト

  • ジョブ コストが違う場合、Message数より最古ジョブの待ち時間が重要です。
  • 再試行はJitter付き待ち時間の段階的増加と有限期限を使います。
  • DLQには担当者、アラート、再実行ツールが必要です。

まとめ

本番キューは無限バッファではなく、有限な処理能力を配分する仕組みです。

Z-SOFTとの協業

今日のテクノロジーに関する一つひとつの判断が、その後の何年にも影響を与えます。

現状を評価し、目標を明確にし、企業の成長方針に合ったアーキテクチャを選定するために、Z-SOFTのチームにご相談ください。

相談を予約する