要点: Brokerの順序Guaranteeより、業務が必要とする順序Boundaryの定義が重要です。
課題
Global Orderは並列性を失い、RetryはDuplicateを生み、Replayは外部Side Effectを再実行する危険があります。
単純な対策だけでは不十分な理由
Orderは一注文内で必要であり全顧客Globalではありません。
Event、Ingestion、Processing Timeのどれを使うか定義します。
処理フロー
Aggregate Version→Partition
Key別Order→Consumer
Inbox・Version→Replay
Side Effect隔離
アーキテクチャ上の判断
Aggregate Version
Duplicate、Gap、Staleを検出します。
Gapを局所隔離
他Keyを止めずParkします。
Replay-safe Consumer
Projectionと通知等を分離します。
さらに深く考える
Exactly-onceはOutcome
外部SystemにはBusiness Idempotencyが必要です。
MeaningもVersion化
旧Fixtureを新ConsumerでTestします。
実装手順
- Business Orderに合うPartition Keyを選びます。
- Event ID、Aggregate ID、Version、Timeを持たせます。
- State Rebuildと外部Side Effectを分離します。
技術例: Version-aware Consumer
if inbox.contains(event.id): ACK
current = projection.version(event.aggregateId)
if event.version <= current: ACK
if event.version > current + 1: park(event)
transaction(apply(event), inbox.add(event.id))
ACKParkしたGapにはAlertとRecovery Policyが必要です。
想定すべき障害パターン
- MigrationでVersionがResetします。
- Replayが通知を再送します。
- Hot AggregateがPartitionを飽和させます。
監視すべきシグナル
| シグナル | 確認する理由 |
|---|---|
| Gap・Stale率 | Ordering不具合です。 |
| Dedup Hit率 | Delivery不安定を示します。 |
| Replay Throughput | Recovery進捗です。 |
設計の検証方法
- EventをShuffle・Duplicate・Delayします。
- 隔離Projectionへ履歴Replayします。
- Hot Partition時の他Keyを確認します。
安全なRollout計画
Metadata、Inbox、Replay環境の順で導入し、Incident利用前に全履歴を訓練します。
本番前チェックリスト
- Stream別Orderingを文書化します。
- Duplicate・Delayを許容します。
- ReplayにRateとSide-effect Policyがあります。
まとめ
Message CorrectnessはBrokerだけでなく明示Orderと決定的Consumerから得られます。
