手册

本番環境における CQRS (コマンド クエリ責任分離): 一貫性、エラー、および回復戦略 (CQRS 3)

CQRS は実稼働環境でどのように安全に機能しますか?一貫性の遅れ、イベントの重複、シーケンスの破損、投影の回復、再試行、DLQ および Saga 戦略。

CQRS (コマンド クエリ責任分離) — 意思決定の構造

部分 4 的 4

CQRS production recovery flow for retries, projections, and consistency

How these failures look to a user

If a banking balance is delayed by two seconds, a user may think money disappeared. If a like count is delayed by two seconds, most users may accept it. The same technical lag creates two different product risks.

Likewise, if the same OrderPlaced message arrives twice, inventory can be reduced twice. Production concepts should therefore be read not only as definitions, but through their effect on the user and the business.

本番環境における本当の質問

幸せな道筋は単純です。コマンドが受け入れられ、イベントが解放され、投影が更新されます。運用環境では、メッセージが 2 回到着したり、コンシューマーが遅れたり、投影が壊れたり、ユーザーがリストに書き込んだ順序を確認できなかったりします。```text Command accepted → event published → projection delayed → user refreshes "Siparişim kayboldu mu?"


## 最初に説明した概念```text
📦 Consistency lag
Write başarılı olduktan sonra read modelin güncellenmesine kadar geçen süre.

📦 Retry
Geçici teknik hatada aynı işi kontrollü biçimde yeniden deneme.

📦 Dead-letter queue (DLQ)
Normal akışta işlenemeyen mesajların incelenmek üzere ayrıldığı kuyruk.

📦 Checkpoint
Projection'ın güvenle işlediği son event konumu.
```**結果整合性** は、データが間違っていることを意味するものではありません。異なるモデルは異なる瞬間に同じ真実に到達します。これが許容できる場合、製品はこれをユーザーに正しく説明する必要があります。そうでない場合は、重要なクエリに対して別の整合性戦略を選択する必要があります。

## Every defence has a reason

- We keep a **checkpoint** **because** a replay needs to know where a projection can safely resume.
- We need **idempotency** **because** applying a duplicate event twice corrupts real business effects such as inventory or payment.
- We limit **retry** **because** repeating a malformed message cannot repair it; it can only amplify load and incorrect impact.
- We use a **DLQ** **because** a message unresolved by the normal flow needs visible ownership and investigation.
- The **partition key is the aggregate ID** **because** the causal order of one aggregate matters more than global event order.
- We **replay** **because** verified event history remains correct even when a projection is broken.

## 一貫性の遅延は製品による決定であり、技術的な決定ではありません

支払いを受け取ってから 2 秒以内に注文リストに支払いが表示されない場合、ユーザーはデータが失われたように感じることがあります。まず、目に見える契約を決定します。どの画面を、取引後どのくらいの期間で更新する必要がありますか?```text
POST /orders → 202 Accepted + orderId + version
GET /orders/{id}?minVersion=42
  → projection 42'ye ulaştıysa güncel görünüm
  → henüz ulaşmadıysa "işleniyor" durumu
```楽観的な UI、ポーリング、またはバージョン待ちを使用できます。これらはラグをリセットしません。 **なぜなら** 本当の仕事は、遅延の意味をユーザーに正直に示すことだからです。重要な決定については、コマンド側の結果がそのまま残ります。

## 重複したイベントとシーケンスの破損

少なくとも 1 回の配信により、同じメッセージの繰り返しが正規化されます。同じ注文イベントを 2 回処理すると、在庫数が 2 回減少する可能性があります。コンシューマはイベント ID と集計バージョンを確認する必要があります。```text
if event.id already processed: ignore
if event.version <= projection.version: ignore
apply event
store checkpoint and event id
```このコントロールは、インデックス付きルックアップで O(1) 平均コストまたは O(log n) コストを実行します。順序付けがパーティション内でのみ保証されている場合、パーティション キーは集約 ID である必要があります。 **なぜなら** 同じ順序の因果的順序が全体的な順序から重要であるからです。

## 再試行、DLQ、およびオペレーターの決定の瞬間

すべての間違いをやり直す必要があるわけではありません。ネットワークタイムアウトは一時的なものである可能性があります。無効なイベント スキーマは永続的なエラーです。

|エラーの種類 |反応 |なぜ |
| --- | --- | --- |
|タイムアウト / 503 |指数バックオフを使用して再試行 |依存症は回復できる |
|レート制限 |遅延再試行 |負担を増やさずに回復する |
|スキーマ検証エラー | DLQ + アラーム |再試行してもメッセージを修正できません |
|ビジネスルール違反 |保存、レビュー、補正 |自動再試行は誤った影響を拡大する可能性があります。

DLQ はダンプではありません。各メッセージには、所有者、レビュー時間、再生手順、およびアラームが必要です。

## Projection が破損した場合に回復するにはどうすればよいですか?

プロジェクションはキャッシュではなく、再現可能なビジネス ビューです。```text
1. Consumer'ı durdur veya yeni projection sürümü oluştur
2. Son güvenli checkpoint'i doğrula
3. Event stream'i kontrollü replay et
4. Sayım ve örnek veri doğrulaması yap
5. Trafiği yeni projection'a yönlendir
6. Lag ve hata oranını izle
```再生コストは O(n) で、イベント数に比例します。スナップショットまたはセグメント化された再生により、これを軽減できます。しかし、スナップショットのソースは本物ではありません。 **なぜなら**、回復のために信頼できる記録は検証されたイベント履歴であるからです。

## サーガの失敗への道

電子商取引で支払いが失敗した場合、在庫を永久に保留したままにするべきではありません。 Saga は技術的なロールバックではなく、ビジネス上合理的な補償です。```text
Reserve inventory → Capture payment → Create shipment
                 payment fails → Release inventory
```補償も冪等である必要があります。ReleaseInventory が 2 回実行された場合に、インベントリが 2 回増加してはなりません。振り付けはローカルな小さなフローを重視しています。オーケストレーションは、複数ステップのプロセスにおけるステート マシンと単一の監視ポイントを提供します。

## 可観測性

コンシューマのラグ、再試行回数、DLQ の深さ、チェックポイント経過時間、重複率、エンドツーエンドの処理時間を測定します。トレース ID をコマンドからイベント、コンシューマー、そしてユーザーに返されるクエリに移動します。アラームは、技術的な指標ではなく、ユーザーへの影響において意味を持ちます。

## 誤った信頼を生み出す一致```text
❌ Retry = güvenilirlik
✓ Retry, yalnızca geçici hatada ve idempotent işlemde güvenlidir.

❌ DLQ = kurtarma
✓ DLQ, inceleme ve replay sürecinin başlangıcıdır.

❌ Replay = her zaman güvenli
✓ Sürümleme ve yan etkiler ayrılmadan replay etkiyi tekrar üretebilir.

❌ Eventual consistency = rastgele gecikme
✓ Gecikme ölçülmeli, ürünle kabul edilmeli ve kullanıcıya açıklanmalıdır.

実稼働準備状況チェック

  1. ユーザーに見える一貫性ラグの目標はありますか?
  2. 消費者の重複イベントや順序が乱れたイベントに対して安全ですか?
  3. 再試行ポリシーは一時的なエラーと永続的なエラーを区別しますか?
  4. DLQ メッセージとリプレイ Runbook の所有者は定義されていますか?
  5. 実稼働データで Projection を安全に再構築できますか?
  6. 佐賀の補償はべき等ですか?

これらの質問のそれぞれに証拠を持って答えることができない場合、システムは拡張できないように見えるかもしれません。しかし、まだ操作可能ではありません。

この記事で覚えておくべきことは何ですか?

  1. 最終的な整合性は、ユーザー エクスペリエンスによって管理されるべき契約です。
  2. 重複や順序の破損は、分散配信では通常の現象であり、特殊なケースではありません。
  3. リトライは、DLQ とリプレイとともに設計された回復システムです。
  4. プロジェクションが再構築できない場合、それは運営上の負債になります。
  5. Saga はロールバックしません。ビジネスへの影響を補償します。

本番環境のアーキテクチャは、メッセージが最初に正しく到着することではありません。それは、彼らが二度到着したり、遅れたり、予想外の順番で到着したりしたときのあなたの行動に現れます。

FAQ

Frequently asked questions

整合性ラグとは何ですか?

書き込みが成功してから読み取りモデルが更新されるまでの時間。

リトライとは何ですか?

一時的な技術的エラーが発生した場合に、制御された方法で同じジョブを再試行します。

「リトライ=信頼性」は正しいでしょうか?

再試行は、一時的なエラーとべき等操作の場合にのみ安全です。

このセクションでは何を修正しますか?

分散システムにおける部分的な障害も例外ではありません。この記事はエラーを解消することを目的としたものではありません。データの正確性、ユーザーの信頼性、エラー発生時の回復時間をどのように維持するかに焦点を当てています。最終的な整合性は、ユーザー エクスペリエンスを通じて管理する必要がある契約です。幸せな道筋は単純です。コマンドが受け入れられ、イベントが解放され、投影が更新されます。運用環境では、メッセージが 2 回到着したり、コンシューマーが遅れたり、投影が壊れたり、ユーザーがリストに書き込んだ順序を確認できなかったりします。

学到的工程原理

  • 整合性の遅延は、製品によって受け入れられ、ユーザーに表示される契約である必要があります。
  • 冪等コンシューマ設計は、複製、シーケンスの中断、および再生のために必須です。
  • 回復;これは、チェックポイント、ランブック、可観測性を備えた事前に設計された機能です。

继续阅读

继续阅读

系列中的下一个

同系列

同系列

Paylaş