非同期バルクジョブは処理サイズ別レーンと予約済み実行枠で短時間ジョブの待ちを防ぐ
バックエンド
設計判断
キュー設計
非同期処理
知識
判断
運用
非同期バルク処理で、数件から数十万件まで同じキュー・同じ worker プールへ流すと、少数の長時間ジョブが worker 枠を占有し、数件の短時間ジョブまで開始待ちになる。FIFO キューのメッセージグループやテナント単位ロックは「同一主体内の直列化」には有効だが、worker 枠そのものを長時間ジョブが占有する問題は解決しない。
判断基準
- 小規模ジョブに対して「いつでも同程度の開始体験」を求めるなら、小規模ジョブ用の queue / topic / priority lane と、そこ専用の予約済み worker 枠を持つ。
- 大規模ジョブは別レーンに流し、低めの並列度・長めの visibility / lease・chunk 処理でスループットを最適化する。
- 同一主体で同時実行したくない業務制約がある場合は、キュー順序だけに寄せず、DB の active lock やユニーク制約でジョブ作成時点に排他を確定する。これにより UI は「待たせる」ではなく即座に競合を返せる。
- cold start が大きい実行基盤を小規模ジョブに使うと開始体験が悪化する。小規模は温かい worker、巨大処理は専用 task / bulk lane という分離が扱いやすい。
落とし穴
- 単一 FIFO キューで MessageGroupId を主体 ID にしても、worker 数が少なく長時間ジョブで埋まれば他主体の短時間ジョブは待つ。
- 優先度付きの自前 scheduler を作ると柔軟だが、lease、再実行、監視、DLQ 相当を自分で持つことになる。まずは size class による少数レーン分離で足りるかを見る。
- DB と外部キューへの二重書き込みは不整合になり得る。重要なジョブでは transactional outbox や未送信イベントのリカバリを用意する。
検証
長時間ジョブを予約済み bulk 枠いっぱいに投入した状態で、小規模ジョブを投入し、開始までの時間が小規模レーンの SLO 内に収まることを確認する。同一主体からの二重投入はジョブ作成時点で競合になり、キュー内で待ち続けないことも確認する。