この動画で学んだことをメモる。
TL;DR
- Single DB transactionで行けるならそれでいくべき
- アプリケーションの中で 2 Phase Commit を使うべきではないことは議論の余地がない。
- Eventual Consistency (= Isolation の喪失) を許容できるのであれば、SAGAを使う。
- システム数が少ない初期段階は、Choreographyを使うことが多い。
- 複雑になってきたら、Orchestration に移行。
- Strong Consistencyが必要であれば、Distrbuted DB (Spannerなど)を使うべき。これは内部で 2 Phase Commit を使用している。
現在業界でもっとよく使われているのは、以下の Orchestration Based SAGA パターン。
🔺 2 Phase Commit (2PC)
= Classic academic solution であり、実際のシステムではほぼ使われていない。
ただし、Google Spanner などのDBの内部では使われている。
todo 仕組みまとめる
特徴
- 比較的強めのconsistencyを保証する
- atomicity (all or nothing) を保障する
問題点
- ブロッキングプロトコルなのでスケールしない
- 遅いノードのトランザクションを待つ必要があるので、entire system moves at the speed of the slowest system.
- coordinator, 参加者ノードの一つでも壊れると他がブロッキング状態になる
⭕️ SAGA Pattern
特徴
- No DB rollback, but compensating actions (= business level UNDOs)
- Refund instead of Rollback
- Cancel instead of Abort
- つまり、ロールバックを「ビジネスレベルのアクションの打ち消し」として定義する。
- Strong consistency は保障されない。Eventual consistency = Isolation の喪失。
- それぞれの処理/ロールバックは冪等にすべきである。
問題点
- Invisible Rollback が不可能。
- 例えば、クレジットカードの refund 履歴が残ったりする。email は、一度送られると元に戻せない。
Choreography Based SAGA
(訳すとダンスの振り付け)
= 中央集権的な制御装置を置かず、各サービスがイベントを投げ合い、数珠つなぎに処理を進める方式。Event-Driven で動く。各々のサービスは自分の処理が失敗した場合、どのサービスのロールバック処理を呼び出すべきかを知っている、
実装の注意
- 「サービスが持つDBへの書き込み」と「後継のサービスへのメッセージをキューへ挿入」をAtomicにやる必要がある。このために、CDC か Outbox Pattern (memo)を用いる。
特徴
- 処理が複雑でなければ、実装コストが低い。
- 処理が複雑になると、ロジックがサーバー間に分散されて複雑になる。各サービスが後継処理/ロールバック処理を把握しておく必要がため。
Orchestration Based SAGA
= 「オーケストレーター」と呼ばれる中央のコントローラーが、各サービスに対して「次はこれをやって」と指示を出す方式 (非同期キューを介して行うのが一般的)。処理が失敗した場合、オーケストレーターが責任を持って然るべきサービスのロールバック処理を実行する。
Temporal や、AWS StepFunctions を使って実現できる。
実装の注意
- 「オーケトレーターが持つDB内ののState更新」と「担当サービスへのメッセージをキューへ挿入」をAtomicにやる必要がある。このために、CDC か Outbox Pattern (memo)を用いる。
特徴
- 処理が簡単であれば、コストが割高である。オーケストレーターサーバーの導入とメンテナンスが必要になる。
- 処理が複雑になれば、コストに見合う。後継処理/ロールバック処理のステートマシンの所在が、オーケストレーター1箇所になり、把握しやすいため。


