【要約】DBポーリングからRedis Queueへ拡張できるOutbox Worker設計 [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
非同期処理を実装する際、開発者は最初からRedis Queue等の導入を検討しがちである。しかし、安易な導入は状態管理の混乱を招く。具体的には以下の問題に直面する。
- ・MySQLのトランザクション状態とQueueの配送状態が混在する。
- ・claim、retry、repairの境界が曖昧になり、保守性が低下する。
- ・処理の正本が不明確になり、分散環境での整合性担保が困難になる。
// Approach
本記事では、MySQLを処理状態の正本とし、配送手段を抽象化する設計を採用している。配送層の変更が業務ロジックに影響を与えないよう、以下のステップで構成する。
- ・MySQLの
outbox_eventsに全ての処理状態を記録する。 - ・Queueには
event_idのみを載せ、Workerは必ずMySQLでclaimを行う。 - ・「処理lease」と「配送lease」を分離し、二重配送と重複実行を制御する。
- ・業務ロジックを
EventHandlerとして分離し、配送層の変更を吸収する。
// Result
この設計により、システムの整合性を維持したまま、段階的なスケーリングが可能となる。導入による具体的な成果は以下の通りである。
- ・初期はDBポーリングによる最小構成で、迅速な開発とリリースができる。
- ・負荷増大時は、
EventHandlerを維持したままRedis Queueへ移行できる。 - ・
Repair機能により、未配送や期限切れイベントの自動補正が可能になる。
Senior Engineer Insight
> 本設計の真価は、Redis Queueを「通知レイヤー」に留め、状態管理をDBに集約した点にある。分散システムにおいて、メッセージキューの信頼性に依存しすぎると、不整合時の復旧が困難になる。状態の正本をMySQLに固定し、配送層をアダプターとして切り離す構成は、スケーラビリティと整合性のトレードオフを極めて現実的に解決している。実戦投入において、非常に堅牢なアーキテクチャであると評価する。