分散トランザクションソリューションを選択するにはどうすればよいでしょうか?

分散トランザクションソリューションを選択するにはどうすればよいでしょうか?

分散トランザクションに関与する参加者は、非同期ネットワークに分散されます。参加者はネットワーク通信を通じて分散一貫性を実現します。ネットワーク通信では、必然的に障害やタイムアウトが発生しやすくなります。したがって、分散トランザクションの実装は、ローカル トランザクションよりも困難になります。この記事では、5 つの分散トランザクション ソリューションをまとめ、その特徴を分析します。かなり長いので、生徒は保存して後で読むことができます。

概要

トランザクションとは、すべて正常に実行されるか、すべてキャンセルされる、グループ化できない操作のセットです。取引を必要とする最も一般的なシナリオは、銀行口座間の振替です。口座 A が口座 B に 100 元を振り替える場合、口座 A は 100 元を減額し、口座 B は 100 元を増額する必要があります。両方のアカウントのデータ変更が成功した場合にのみ、転送は成功したとみなされます。より厳密に言えば、トランザクションは次の 4 つの ACID プロパティを使用して記述できます。

  • 原子性: トランザクション内のすべての操作は、正常に実行されるか、キャンセルされます。一部の操作は実行され、一部の操作は実行されないという状態は存在できません。
  • 一貫性: たとえば、口座 A と口座 B にそれぞれ 100 元がある場合、2 つの口座が同時に何回送金しても、2 つの口座の合計金額は 200 元のままです。
  • 分離: 分離とは、同時実行トランザクション間の相互影響の度合いを指します。分離も、コミットされていない読み取り、コミットされた読み取り、繰り返し可能な読み取りなどのレベルに分割されます。
  • 耐久性: 永続性とは、トランザクションが完了した後もデータへの変更が失われないことを意味します。

単一のデータベースではネットワークのやり取りが不要なので、複数のテーブル間でトランザクションを実装するのは比較的簡単です。このタイプのトランザクションをローカル トランザクションと呼びます。

ただし、単一のデータベースのパフォーマンスがボトルネックになると、データベース(物理インスタンス)に分割する必要があり、データベース(データベース インスタンス)間のトランザクション要件が発生します。エンタープライズアプリケーションの規模が拡大するにつれて、企業はビジネスの成長のニーズを満たすためにサービス指向の変革をさらに進めることになります。現在、マイクロサービス アーキテクチャはますます普及しており、サービス間のトランザクション シナリオも増加しています。

これらは分散トランザクションの要件です。分散トランザクションとは、トランザクションの開始者、参加者、データ リソース サーバー、およびトランザクション マネージャーが分散システムの異なるノードに配置されていることを意味します。

要約すると、分散トランザクションには 3 つのシナリオがあります。

  • データベース間の分散トランザクション
  • サービス間の分散トランザクション
  • ハイブリッド分散トランザクション

​​

​​

分散トランザクションに関与する参加者は、非同期ネットワークに分散されます。参加者はネットワーク通信を通じて分散一貫性を実現します。ネットワーク通信では、必然的に障害やタイムアウトが発生しやすくなります。したがって、分散トランザクションの実装は、ローカル トランザクションよりも困難になります。以下に、いくつかの一般的な分散トランザクション ソリューションを示します。

分散トランザクションモード

XA仕様

最も古い分散トランザクション製品は、1980 年代に AT&T が発売した Tuxedo (Transactions for Unix, Extended for Distributed Operations) でしょう。 Tuxedo はもともと、通信分野の OLTP システム向けに開発された分散トランザクション ミドルウェアでした。その後、標準化団体 X/Open は Tuxedo の設計アイデアといくつかのインターフェースを吸収して採用し、分散トランザクション仕様である XA 仕様を立ち上げました。

XA 仕様では、次の 4 つのコア ロールを含む分散トランザクション処理モデルが定義されています。

  • RM (リソース マネージャー): リソース マネージャーは、データの一貫性と整合性を確保するために、データ リソースの操作および管理インターフェイスを提供します。最も代表的なものはデータベース管理システムです。もちろん、一部のファイル システムや MQ システムも RM と見なすことができます。
  • TM (トランザクション マネージャー): トランザクション マネージャーは、ライブラリ間のトランザクションに関連付けられたすべての RM の動作を調整するコーディネーターです。
  • AP (アプリケーション プログラム): ビジネス ルールに従って RM インターフェイスを呼び出して、ビジネス モデル データの変更を完了するアプリケーション プログラム。データの変更に複数の RM が関与し、トランザクションを保証する必要がある場合、AP は TM を通じてトランザクションの境界を定義します。 TM は、トランザクションに関与する RM を調整して、グローバル トランザクションを共同で完了する責任を負います。
  • CRM (通信リソース マネージャー): 主にサービス間でトランザクションを伝播するために使用されます。

次の図は、XA 仕様で定義されているトランザクション モデルの図です。分散トランザクションを開始する TM インスタンスはルート ノードと呼ばれ、他の TM インスタンスは総称してトランザクション参加者と呼ばれます。トランザクション イニシエーターはグローバル トランザクション全体を開始する責任があり、各トランザクション参加者は独自のトランザクション ブランチを実行する責任があります。 TM インスタンスが別の TM インスタンスへのサービス呼び出しを開始する場合、開始側は上位ノードと呼ばれ、呼び出されたインスタンスは下位ノードと呼ばれます。

​​

​​

図の出典: 「分散トランザクション処理: 参照モデル、バージョン 3」32 ページ、図 3-2

XA 仕様では、分散トランザクションは RM ローカル トランザクション (この時点ではローカル トランザクションはブランチ トランザクションと見なされます) に基づいて構築され、TM はこれらのブランチ トランザクションが正常にコミットまたはロールバックされるように調整する役割を担います。 XA 仕様では、分散トランザクション処理プロセスを 2 つのフェーズに分割するため、2 フェーズ コミット プロトコル (2 フレーズ コミット) とも呼ばれます。

1) 準備段階

TM はトランザクション開始ログを記録し、各 RM にコミット準備操作を実行できるかどうかを問い合わせます。

RM は、指示を受け取った後、自身のステータスを評価し、リソースの予約、リソースのロック、操作の実行など、ローカル トランザクションの準備操作を実行しようとしますが、トランザクションをコミットせず、TM からの後続の指示を待機します。試行が失敗した場合、TM にはこのフェーズの実行が失敗したことが通知され、TM 自身の操作がロールバックされ、その後、TM はこのトランザクションに参加しなくなります (MySQL を例にとると、このフェーズではリソースのロックと、REDO ログおよび UNDO ログの書き込みが完了します)。

TM は RM の応答を収集し、トランザクション準備完了ログを記録します。

2) コミット/ロールバックフェーズ

このフェーズでは、前のフェーズの調整結果に基づいて、トランザクションのコミットまたはロールバック操作を開始します。

前の手順ですべての RM が成功の結果を返した場合、次のようになります。

  • TM はトランザクション コミット ログを記録し、トランザクション コミット指示をすべての RM に送信します。
  • RM は指示を受信すると、トランザクションをコミットし、リソースを解放し、TM に「コミットが完了しました」と応答します。
  • TM はすべての RM から応答を受信すると、トランザクション終了ログを記録します。

RM が実行失敗を返すか、前のステップで応答せずにタイムアウトした場合、TM はそれを実行失敗として処理します。それから:

  • トランザクション中止ログを記録し、トランザクション ロールバック指示をすべての RM に送信します。
  • RM は指示を受信すると、トランザクションをロールバックし、リソースを解放し、ロールバックが完了したことを TM に応答します。
  • TM はすべての RM から応答を受信すると、トランザクション終了ログを記録します。

​​

​​

一部のシナリオでは、XA 仕様で次の最適化手段も定義されています。

  • TM がトランザクション全体に 1 つの RM のみが関与していることを検出した場合、プロセス全体が 1 フェーズ コミットに低下します。
  • RM が AP から受信したデータ操作が読み取り専用操作である場合、フェーズ 1 でトランザクションを完了し、フェーズ 2 プロセスには参加しないことを TM に通知できます。ダーティリードのリスクがあります。
  • RM はフェーズ 1 が完了した後、フェーズ 2 からの指示を長時間待機できない場合、ローカル トランザクションを自動的にコミットまたはロールバックできます。これをヒューリスティック補完と呼びます。このシナリオではトランザクションの一貫性が損なわれ、例外が発生する可能性があることに注意してください。

XA 仕様では、コア コンポーネント間の相互作用インターフェイスが詳細に定義されています。 TM と RM 間の相互作用インターフェースを例に挙げます。次の図に示すように、完全なグローバル トランザクションでは、TM と RM 間のやり取りは比較的頻繁に行われます。

​​

​​

トランザクションの実行中に、ダウンタイムやネットワーク タイムアウトが発生する可能性があります。このような異常なシナリオでは、XA 仕様の実装によって例外処理方法が異なる場合があります。参考までに以下をご参照ください。

  • フェーズ 1 で RM を照会する前に TM がクラッシュし、回復後にアクションは必要ありません。
  • フェーズ 1 で TM が RM にクエリを実行した後、RM がクラッシュします。フェーズ 1 では一部の RM のみがリクエストを受信した可能性があります。そのため、この時点でロールバック リクエストを RM に送信する必要があります。
  • TM はフェーズ 1 で RM に完了を要求しますが、ログを完了しようとするとクラッシュします。クラッシュ前のトランザクションネゴシエーションの結果は不明であるため、回復後に RM にロールバック要求を送信する必要があります。
  • TM はフェーズ 1 でトランザクション準備ログの記録を完了するとクラッシュします。リカバリ後、ログに基づいてコミットまたはロールバックの指示を開始できます。
  • TM は、ステージ 2 でコミット/中止ログを記録する前にクラッシュします。回復後、ログに基づいてコミットまたはロールバック命令を開始できます。
  • フェーズ 2 では、トランザクション終了ログを記録する前に TM がクラッシュします。リカバリ後、ログに基づいてコミットまたはロールバック命令を開始できます。
  • フェーズ 2 でトランザクション終了ログを記録した後、TM がクラッシュします。回復後は操作は必要ありません。
  • フェーズ 1 では、RM がタイムアウトすると、TM はそれを失敗として扱い、すべての RM にロールバック命令を送信します。
  • フェーズ 2 では、RM がタイムアウトした場合、TM はタイムアウトした RM に指示を送信し続ける必要があります。

機能分析

XA 2 フェーズ コミット プロトコルは、ローカル トランザクションのようなトランザクションの 4 つの ACID プロパティを実装するように設計されています。

  • アトミック性: 準備フェーズとコミット フェーズ中にトランザクションがアトミックであることを確認します。
  • 一貫性: XA プロトコルは強力な一貫性を実装します。
  • 分離: XA トランザクションは完了するまでリソース ロックを保持するため、書き込みの分離を実現できます。
  • 永続性: これはローカルトランザクションに基づいて実装されているため、問題はありません。

XA は最も初期の分散トランザクション仕様です。 Oracle、MySQL、SQLServer などの主流のデータベースはすべて XA 仕様をサポートしています。 J2EE の JTA 仕様も XA 仕様を参照して記述されており、XA 仕様と互換性があります。

XA は、リソース管理レベルで実装される分散トランザクション モデルであり、ビジネスへの影響は低くなります。

XA 2 フェーズ コミット プロトコルは、分散トランザクションの 3 つのシナリオをカバーできます。ただし、グローバル トランザクションの実行中は、RM は常にリソースのロックを保持します。特にサービス間シナリオで RM が多すぎると、ネットワーク通信の数と時間が大幅に増加するため、ブロック時間が長くなり、システム スループットが非常に低下し、トランザクション デッドロックの可能性が高まります。したがって、マイクロサービス アーキテクチャ シナリオのクロスサービス分散トランザクション モードには適していません。

各 TM ドメインでは、TM が単一ポイントであるため、単一ポイント障害のリスクがあります。フェーズ 1 後に TM が失敗すると、参加している RM はフェーズ 2 からの要求を長時間受信できず、リソース ロックを長時間保持することになり、ビジネスのスループットに影響を及ぼします。同時に、完全なグローバル トランザクションには、TM と RM 間の最大 8 回のやり取りが含まれ、これは非常に煩雑であり、システムの処理パフォーマンスに大きな影響を与えます。

XA 2 フェーズ プロトコルにより、スプリット ブレイン例外が発生する可能性があります。フェーズ 2 で TM が RM にトランザクションをコミットするように通知し、命令が発行された後にシステムがクラッシュし、一部の RM のみがコミット要求を受信した場合、TM が回復したときに、このトランザクションのすべての RM ローカル トランザクションの一貫性を調整できなくなります。

XA は多くの例外シナリオを処理する必要があり、フレームワークの実装に一定の課題をもたらします。オープンソースの実装については、Atomikos、Bitronix を参照してください。

XA 2 フェーズ コミットの問題に対応して、改良された 3 フェーズ コミット ソリューションが提案されました。 3 フェーズ コミット ソリューションは、主に単一点障害の問題を解決し、リソースの長期ロックを回避するために RM 側にタイムアウト メカニズムを導入します。しかし、3 段階の送信方式では、スプリット ブレインという異常な状況を回避することはできません。実際の適用事例は少ない。興味のある学生は自分で関連情報を見つけることができます。

TCC

TCC (Try、Commit、Cancel) は補償トランザクションです。このモデルでは、アプリケーションの各サービスが、試行、確認、キャンセルの 3 つのインターフェースを提供する必要があります。その中心的な考え方は、リソースを予約する(中間状態を提供する)ことによって、リソースのロックをできるだけ早く解除することです。トランザクションをコミットできる場合、予約されたリソースが確認されます。トランザクションをロールバックする必要がある場合、予約されたリソースは解放されます。

TCC も 2 フェーズ コミット プロトコルであり、2PC/XA のバリエーションとして考えることができますが、リソース ロックを長時間保持しません。

TCC モデルでは、トランザクションの送信を 2 つのフェーズに分割します。

1) フェーズ1

ビジネス チェック (一貫性) を完了し、ビジネス リソース (準分離) を予約します。これが TCC での試みです。

2) フェーズ2

試行フェーズですべてのビジネス リソースが正常に予約された場合は、確認操作が実行され、それ以外の場合はキャンセル操作が実行されます。

  • 確認: ビジネスチェックは実行されません。ビジネス操作を実行するために予約されたリソースのみが使用されます。障害が発生した場合、システムは再試行を続けます。
  • キャンセル: ビジネス操作をキャンセルし、予約されたリソースを解放します。失敗した場合は再試行されます。

​​

​​

TCC モードでは、トランザクションの開始者と参加者の両方がトランザクション ログを記録する必要があります。トランザクションの開始者は、グローバル トランザクションと各ブランチ トランザクションのステータスと情報を記録する必要があります。取引の参加者は、ブランチ取引のステータスを記録する必要があります。

TCC トランザクションの実行中、どの段階でもダウンタイム、再起動、ネットワーク中断などの異常な状況が発生する可能性があります。この時点で、トランザクションは非アトミック状態であり、最終的に一貫性のない状態です。このとき、メイントランザクション記録とブランチトランザクション記録のログに基づいて、残りのブランチトランザクションの送信またはロールバックを完了し、分散トランザクション全体のすべての参加者が最終的な一貫性のある状態に到達し、トランザクションのアトミック性を実現する必要があります。

単純な電子商取引システムを例に挙げてみましょう。シャオミンさんはタオバオで100元を使って本を購入し、10ポイントを獲得した。製品にはいくつかの操作があります:

注文システムは製品注文を作成する

決済システムはシャオミンの支払いを受け入れる

在庫管理システムは製品在庫を減算します

会員システムはシャオミンのアカウントに会員ポイントを追加します

これらのアクションはトランザクションとして実行する必要があり、同時に成功するかキャンセルされる必要があります。

TCC トランザクション モードを使用する場合、各システムを次の状態に変換する必要があります。

1) 注文システム

  • 試してください: 注文を作成すると、ステータスが「支払い保留中」として表示されます
  • 確認: 注文ステータスを「完了」に更新します
  • キャンセル: 注文ステータスを「キャンセル済み」に更新します

2) 支払いシステム

  • 試してみましょう: Xiao Ming の口座に 1,000 元があると仮定し、口座の 100 元を凍結します。この時点で、シャオミンが見ている残高はまだ1,000元です。
  • 確認: 口座残高を900元に変更し、凍結記録を解除します。
  • concel: 凍結記録をクリアします。

3) 在庫システム

  • 試してください: 在庫に 10 冊の本があると仮定し、そのうちの 1 冊を凍結すると、実際の在庫にはまだ 10 冊の本が残ります。
  • 確認: 残りの在庫を 9 冊に更新し、凍結されたレコードをクリアします。
  • キャンセル: 凍結されたレコードをクリアします。

4) 会員制度

  • 試してください:シャオミンが3000ポイントを持っていると仮定すると、シャオミンのアカウントに10ポイントが事前に追加され、アカウントに表示されるポイントは依然として3000ポイントです。
  • 確認: アカウントポイントを 3010 に更新し、増加前の記録をクリアします。
  • キャンセル: 事前に追加されたレコードをクリアします。

機能分析

TCC トランザクションには、次の 4 つのトランザクション特性があります。

  • アトミック性: トランザクション イニシエーターは、コミットまたはロールバックされるすべてのブランチ トランザクションを調整します。
  • 一貫性: TCC トランザクションは最終的な一貫性を提供します。
  • 分離タイプ: try を通じてリソースを事前に割り当てることでデータの分離が実現されます。
  • 永続性: 各ブランチトランザクションによって実装されます。

TCC トランザクション モデルはビジネス側への影響が非常に大きく、ビジネス側で機能の実装を 1 つのインターフェイスから 3 つに分割する必要があり、その結果、開発コストが高くなります。

同時に、非同期ネットワークでの通信障害やタイムアウトによって発生する異常な状況を解決するために、TCC トランザクションでは、ビジネス側が設計と実装において次の 3 つの戦略に従う必要があります。

  • 空のロールバックを許可する: 理由は、フェーズ 1 で例外が発生すると、一部の参加者が try 要求を受信せず、トランザクション全体のキャンセル操作がトリガーされるためです。試行が失敗した場合、または試行操作を実行しなかった参加者がキャンセル要求を受信した場合は、空のロールバック操作が必要になります。
  • 冪等性を維持する: 理由は、フェーズ 2 でネットワーク タイムアウトなどの例外が発生すると、参加者の確認/キャンセル メソッドが繰り返し呼び出されるため、これら 2 つのメソッドの実装で冪等性を保証する必要があるためです。
  • リソースのハングアップを防ぐ: ネットワークの異常により、2 つのステージの厳密な順次実行を保証することが不可能になります。参加者側の試行要求はキャンセル要求よりも遅れて到着します。キャンセルはトランザクションの正確性を保証するために空のロールバックを実行しますが、この時点では try メソッドは実行できなくなります。

TCC トランザクションは、分散トランザクションをリソース レイヤーからビジネス レイヤーに移動するため、ビジネスはリソース ロックの粒度を柔軟に選択でき、グローバル トランザクションの実行中はロックが常に保持されるわけではないため、システム スループットは 2PC/XA モードよりもはるかに高くなります。

TCC トランザクションをサポートするオープン ソース フレームワークは、ByteTCC、Himly、および TCC-transaction です。

佐賀

佐賀は新しい概念ではありません。関連する論文は 1987 年に公開されました。これは、XA 2 フェーズ コミット仕様とほぼ同じ時期です。

Saga は TCC と同様に補償トランザクションですが、試行フェーズはありません。代わりに、分散トランザクションを、一連のローカル トランザクションで構成されるトランザクション チェーンとして扱います。

トランザクション チェーン内の各フォワード トランザクション操作は、可逆トランザクション操作に対応します。 Saga トランザクション コーディネーターは、トランザクション チェーン内のブランチ トランザクションを順番に実行する役割を担います。ブランチ トランザクションが実行されると、リソースが解放されます。ブランチ トランザクションが失敗した場合、トランザクション補正操作が反対方向に実行されます。

Saga の分散トランザクション チェーンが n 個のブランチ トランザクション [T1、T2、...、Tn] で構成されている場合、分散トランザクションには 3 つの実行シナリオがあります。

  • T1、T2、...、Tn: n 個のトランザクションはすべて正常に実行されます。
  • T1、T2、...、Ti、Ci、...、C2、C1: i 番目 (i<=n) のトランザクションが失敗した場合、i->1 の順序で補償操作が呼び出されます。補償が失敗した場合は、再試行を続けます。補正操作は並列実行するように最適化できます。
  • T1、T2、...、Ti (失敗)、Ti (再試行)、Ti (再試行)、...、Tn: トランザクションが成功する必要があるシナリオに適用されます。障害が発生した場合、再試行が継続され、補償操作は実行されません。

​​

​​

シャオミンが国慶節の連休中に遊びに出かけたい場合、北京から出発して、まずロンドンに行き、ロンドンで3日間遊び、その後パリに行き、パリで3日間遊び、その後北京に戻ることができます。旅行全体には、さまざまな航空会社の航空券の予約と、ロンドンとパリの現地ホテルの予約が含まれます。シャオミンさんは、チケットやホテルが手に入らなければ旅行をキャンセルするつもりだ。総合旅行サービスプラットフォームがこのワンクリック注文機能を提供する場合、これは長い取引になります。 Saga モデルを使用してサービスがオーケストレーションされる場合、次の図のようになります。いずれかのリンクに障害が発生すると、補償操作によって以前の旅程予約がキャンセルされます。

​​

​​

機能分析

Saga トランザクションは、トランザクションの次の 3 つの特性を保証できます。

  • 原子性: Saga コーディネーターは、トランザクション チェーン内のローカル トランザクションを調整して、すべてをコミットするか、すべてをロールバックすることができます。
  • 一貫性: Saga トランザクションは最終的な一貫性を実現できます。
  • 永続性: ローカル トランザクションに基づいて、この機能を適切に実装できます。

ただし、Saga はトランザクションの分離を保証しません。ローカル トランザクションがコミットされると、変更は他のトランザクションにも表示されます。正常に送信されたデータが他のトランザクションによって変更された場合、補正操作は失敗する可能性があります。たとえば、控除が失敗したが、お金がすでに使われてしまった場合、ビジネス設計ではこのシナリオを考慮してこの問題を回避する必要があります。

Saga トランザクションは、TCC トランザクションと同様に、ビジネス実装に対する要件が高く、次の 3 つの戦略に従うビジネス設計と実装が必要です。

  • 空の補償を許可する: ネットワーク異常により、トランザクション参加者は補償操作指示のみを受信します。通常の操作が実行されていないため、空の補正が必要です。
  • べき等性の維持: トランザクションの転送操作と補正操作の両方が繰り返しトリガーされる可能性があるため、操作のべき等性を確保する必要があります。
  • リソースの停止を防ぐ: ネットワークの異常により、トランザクションの転送操作命令が補償操作命令よりも遅れて到着した場合、通常の操作を破棄する必要があります。そうしないと、リソースの停止問題が発生します。

Saga と TCC はどちらも補償トランザクションですが、送信フェーズが異なるため異なります。

  • 佐賀は不完全な補償です。補償操作を行うと、元のトランザクション操作の痕跡が残るため、業務への影響を考慮する必要があります。
  • TCC は完璧な補償です。補償操作により、以前の元のトランザクション操作が完全にクリーンアップされ、トランザクションがキャンセルされる前のステータス情報をユーザーが認識できなくなります。
  • TCC トランザクションは非同期をより適切にサポートできますが、通常、補正フェーズでの非同期には Saga モードの方が適しています。

Saga モードは、長いビジネス プロセスと長いトランザクションを含むシナリオに非常に適しています。その実装はビジネスへの影響が少ないため、マイクロサービス アーキテクチャのシナリオに非常に適しています。同時に、Saga は 1 フェーズ コミット モードを採用しており、リソースを長時間ロックせず、「バレル効果」も発生しないため、このモード アーキテクチャを使用するシステムは高性能で高スループットを実現します。

Alibaba の Seata オープンソース プロジェクトと Huawei の ServiceComb オープンソース プロジェクトはどちらも Saga モデルをサポートしています。

メッセージベースの分散トランザクション

メッセージベースの分散トランザクション モデルの中心的な考え方は、メッセージ システムを通じて他のトランザクション参加者に自身のトランザクションの実行ステータスを通知することです。

メッセージング システムの導入により、トランザクション参加者がより効果的に分離され、各参加者が非同期で実行できるようになります。

このモードの難しさは、ローカル トランザクションの実行とメッセージ送信の一貫性を解決することにあります。つまり、両方を同時に正常に実行するか、キャンセルする必要があります。

これを実現するには主に 2 つの方法があります。

  • トランザクションメッセージベースのソリューション
  • ローカルメッセージベースのソリューション

トランザクションメッセージに基づく分散トランザクション

通常のメッセージでは、ローカル トランザクションの実行とメッセージ送信の一貫性の問題を解決できません。メッセージ送信はネットワーク通信プロセスであるため、メッセージ送信プロセスが失敗したり、タイムアウトしたりする可能性があります。タイムアウト後、メッセージは正常に送信されるか、失敗する可能性があります。メッセージの送信者を特定できないため、送信者がトランザクションをコミットするかロールバックするかによって不整合が発生する可能性があります。

この問題を解決するには、トランザクション メッセージを導入する必要があります。トランザクション メッセージと通常のメッセージの違いは、トランザクション メッセージが正常に送信された後、準備済み状態になり、サブスクライバーが使用できないことです。ダウンストリーム サブスクライバーは、トランザクション メッセージの状態が消費可能状態に変更された後にのみメッセージを監視できます。

ローカルトランザクションとトランザクションメッセージ送信の処理フローは次のとおりです。

  • トランザクション開始者は事前にトランザクション メッセージを送信します。
  • トランザクション メッセージを受信した後、MQ システムはメッセージを保持し、メッセージのステータスは「送信待ち」になり、送信者に ACK メッセージが提供されます。
  • トランザクション イニシエーターが ACK メッセージを受信しない場合、ローカル トランザクションの実行はキャンセルされます。 ACK メッセージが受信されると、ローカル トランザクションが実行され、ローカル トランザクションの実行ステータスを通知する別のメッセージが MQ システムに送信されます。
  • メッセージ通知を受信すると、MQ システムはローカル トランザクションの実行ステータスに応じてトランザクション メッセージのステータスを変更します。実行が成功した場合、メッセージは「消費可能」に変更され、適切なタイミングでサブスクライバーに送信されます。トランザクションの実行が失敗した場合、トランザクション メッセージは削除されます。
  • ローカル トランザクションが実行された後、MQ に送信された通知メッセージが失われる可能性があります。したがって、トランザクション メッセージをサポートする MQ システムには、まだ「送信待ち」状態にあるメッセージをスキャンし、メッセージの送信者にトランザクション メッセージの最終ステータスを照会し、その結果に基づいてトランザクション メッセージのステータスを更新する、時間指定のスキャン ロジックがあります。したがって、トランザクションの開始者は、MQ システムにトランザクション メッセージ ステータス クエリ インターフェイスを提供する必要があります。
  • トランザクション メッセージのステータスが「送信可能」の場合、MQ システムはメッセージを下流の参加者にプッシュし、プッシュが失敗した場合は継続的に再試行します。
  • メッセージを受信した後、ダウンストリーム参加者はローカル トランザクションを実行します。ローカル トランザクションが正常に実行された場合、ACK メッセージが MQ システムに送信されます。実行が失敗した場合、ACK メッセージは送信されず、MQ システムはメッセージをプッシュし続けます。

​​

​​

ローカルメッセージに基づく分散トランザクション

トランザクション メッセージング モデルには、MQ システムに対する高い要件があります。すべての MQ システムがトランザクション メッセージングをサポートしているわけではありません。 RocketMQ は、現在トランザクション メッセージングをサポートしている数少ない MQ システムの 1 つです。依存する MQ システムがトランザクション メッセージをサポートしていない場合は、ローカル メッセージの分散モードを使用できます。

このモードの中心的な考え方は、トランザクションのイニシエーターがローカル メッセージ テーブルを維持し、ビジネスの実行とローカル メッセージ テーブルの実行が同じローカル トランザクション内にあることです。業務が正常に実行された場合、「送信保留中」状態のメッセージがローカル メッセージ テーブルに記録されます。システム内でスケジュールされたタスクが開始され、ローカル メッセージ テーブル内のステータスが「送信予定」のレコードが定期的にスキャンされ、MQ システムに送信されます。送信が失敗したりタイムアウトになったりした場合は、送信が成功するまで送信が継続され、その後、ローカル メッセージ テーブルからレコードが削除されます。その後の消費およびサブスクリプションのプロセスは、トランザクション メッセージ ベースのモデルと同様です。

​​

​​

機能分析

メッセージベースの分散トランザクション モードは、次の ACID 機能をサポートします。

  • アトミック性: 最終的には、すべてのブランチ トランザクションを実行することも、まったく実行しないことも可能です。
  • 一貫性: 最終的な一貫性を提供します。
  • 分離: 分離は保証されません。
  • 耐久性: 現地取引により保証されます。

メッセージベースの分散トランザクションは、分散システムをより効果的に分離することができ、トランザクション参加者間の呼び出しは同期呼び出しではなくなります。

MQ システムに対する要件は高く、ビジネスの実装にも多少影響を及ぼします。トランザクション メッセージ ステータス クエリ インターフェイスが提供される、またはローカル メッセージ テーブルを維持する必要があります。原則として、下流ブランチトランザクションの成功のみを受け入れ、トランザクションのロールバックは受け入れません。トランザクションが失敗した場合は、継続的に再試行する必要があります。企業間のシステム間の呼び出しなど、最終的な一貫性がそれほど重要でないビジネス シナリオに適しており、適用可能なシナリオは限られています。

ベストエフォート通知分散トランザクション

ベストエフォート通知タイプの分散トランザクション ソリューションも MQ システムに基づくソリューションですが、MQ メッセージの信頼性は必要ありません。

Xiao Ming が China Unicom のオンライン ビジネス ホールを通じて携帯電話料金をトップ チャージし、チャージ方法として Alipay を選択したとします。全体の操作プロセスは次のとおりです。

  • シャオミンはチャージ金額「50元」と支払い方法「Alipay」を選択します。
  • China Unicom Online Business Hall に「支払中」ステータスの再チャージ注文が作成され、Alipay の支払いページにジャンプします (この時点で Alipay システムに入りました)。
  • Alipayがシャオミンの支払いを検証・確認すると、シャオミンの口座から50元が差し引かれ、China Unicomの口座に50元が追加されます。実行が完了すると、メッセージが MQ システムに送信されます。メッセージの内容は、支払いが成功したかどうかを示します。メッセージ送信の失敗は許可されます。
  • メッセージが正常に送信された場合、Alipay の通知サービスがメッセージを購読し、China Unicom のインターフェースを呼び出してこの支払いの結果を通知します。この時点で China Unicom のサービスが失敗し、通知が失敗した場合、呼び出しが成功するか、スケジュールされた時間枠の上限に達するまで、China Unicom のインターフェイスは 5 分、10 分、30 分、1 時間、...、24 時間という時間間隔で繰り返し呼び出され、通知は行われません。これがベストエフォート通知の意味です。
  • China Unicom のサービスが正常に戻り、Alipay から通知を受信した場合、支払いが成功した場合はアカウントに再チャージされます。支払いが失敗した場合、再チャージはキャンセルされます。実行が完了すると、確認応答が Alipay 通知サービスに送信されます。確認応答は失敗を許可し、Alipay システムは再試行を続けます。したがって、China Unicom の再チャージ インターフェースは冪等性を維持する必要があります。
  • China Unicom のサービス障害が長時間続き、正常に回復した後、Alipay がサービスに通知する時間枠を超えている場合、China Unicom は「支払い」注文をスキャンし、Alipay に注文の支払い結果を確認するリクエストを積極的に開始します。

機能分析

ベスト エフォート通知ソリューションの本質は、定期的な検証メカニズムを導入することで最終的な一貫性を保証することです。ビジネスへの介入が少なく、MQ システムに対する要件も低く、実装も比較的簡単です。これは、プラットフォームや企業間のシステム間のビジネス相互作用など、最終的な一貫性と短いビジネス リンクに対する感度が低いシナリオに適しています。

分散トランザクションミドルウェア

Alibaba には、2 つの分散トランザクション ミドルウェア オプションがあります。

  • Ant Financial チームによって開発された XTS には、DTX と呼ばれる金融クラウド製品があります。
  • TXC は Alibaba のミドルウェア チームによって開発されました。

XTS と TXC は同様の機能を持っています。どちらも TCC トランザクション モードをサポートし、ビジネスへの侵入が少ない分散トランザクション ソリューションを提供します。現在、これら 2 つのチームは、分散トランザクション ミドルウェア Seata のオープン ソース バージョンを共同で構築する予定です。ここでは、Seata を紹介します。

シータ

ここで、Seata (Simple Extensible Autonomous Transaction Architecture) の歴史について簡単に説明します。

  • 2014年、アリババは分散型トランザクションミドルウェア製品TXC(Taobao Transaction Constructor)を発売しました。
  • 2016 年、TXC はクラウド製品の変革を実施し、GTS (Global Transaction Service) と呼ばれる Alibaba Cloud バージョンを提供しました。
  • 2019年にGTSはオープンソース化することを発表し、オープンソースプロジェクトの名前はSeataと呼ばれました。

Seata は TCC モードと Saga モードをサポートしています。ただし、Seata の TCC モードのサポートにより、AT (自動トランザクション) モードと呼ばれる、ビジネスへの介入がゼロのソリューションが提供されます。次に、ATモードの動作メカニズムに焦点を当てます。

  • グローバル取引は、依然としてさまざまなブランチ取引に基づいて完了します。 Seata Server は、各ブランチ トランザクションを調整して、一緒にコミットまたはロールバックします。
  • 各ブランチ トランザクションが実行されると、Seata Client は SQL 実行をプロキシおよびインターセプトして行レコードを見つけ、SQL 実行の前後の行データのスナップショットを記録します。 beforeImage と afterImage を組み合わせてロールバック ログが構成され、別のテーブルに記録されます。ロールバック ログの書き込みとビジネス データの変更は、同じローカル トランザクションでコミットされます。
  • ブランチ トランザクションが完了すると、ローカル リソースのロックが直ちに解除され、トランザクション実行の結果が Seata コーディネーターに報告されます。
  • Seata コーディネーターは、各ブランチ トランザクションの完了ステータスを要約し、トランザクションのコミットまたはロールバックの解決策を生成し、その解決策を Seata クライアントに送信します。
  • 解決策がトランザクションをコミットする場合、SEATAクライアントはロールバックログを非同期にクリーンアップします。解決策がトランザクションをロールバックする場合、SEATAクライアントはロールバックログに基づいて報酬操作を実行します。補償の前に、一貫性のために現在のデータスナップショットとAfterImageを比較します。それらが一貫していない場合、ロールバックは失敗し、手動介入が必要です。

​​

​​

ATモードは、ロールバックログを自動的に生成し、ビジネスアクセスのコストとビジネス侵入の程度を削減します。ただし、ATモードの適用にはいくつかの制限があります。

  • モードでは、酸トランザクションに基づいてリレーショナルデータベースのみをサポートします。
  • モードはSQLの解析によって完了し、SQL構文のサポートは限られています。複雑なSQLを使用する場合、互換性を考慮する必要があります。
  • 複合プライマリキーは現在サポートされていません。ビジネステーブルを設計するときは、自動インクリメントプライマリキーを必ず追加してください。
  • グローバルトランザクションのデフォルトの分離レベルは、読み取りされていませんが、読み取り済みの分離レベルは、select ... for updateのようなステートメントを通じて達成できます。グローバルな排他的な書き込みロックを使用すると、読み取りのない読み取りとCommitedの読み取りレベルを達成できます。

要約する

モノリシックデータベーストランザクションは、トランザクションの4つの酸性特性を簡単に満たし、強力な一貫性保証を提供できますが、分散トランザクションが酸性特性に完全に準拠することがより困難です。分散システムの高可用性と高スループットを追求するために、分散トランザクションソリューションは一般に最終的な一貫性を提供します。

強力な一貫性の剛性トランザクションを提供するトランザクションと、最終的な一貫性の柔軟なトランザクションを提供するトランザクションを呼び出します。剛性トランザクションは、4つの酸特性を完全に満たすことができます。柔軟なトランザクションは、次のようにトランザクションの酸特性をサポートしています。

  • 原子性:完全にサポートされています。
  • 一貫性:最終的な一貫性のサポートのみが提供されます。
  • 分離:完全には保証されていません。通常、システムのスループットとパフォーマンスのために、分離要件はある程度放棄されます。
  • 永続性:完全にサポートされています。

通常、柔軟なトランザクションは、分散フィールドの基本理論に従います。

  • BA:基本的な可用性、基本的なビジネスの可用性。
  • S:ソフト状態、柔軟な状態。
  • E:最終的な一貫性、最終的な一貫性。

基本理論はCAP理論の拡張であり、CAPの一貫性と可用性のトレードオフの結果です。理論の核となるアイデアは、強い一貫性を達成することはできませんが、各アプリケーションは適切な方法を採用して、システムが独自のビジネス特性に基づいて最終的な一貫性を達成できるようにすることができます。

CAP理論は、分散システムが一貫性、可用性、パーティション許容度を同時に満たすことができないため、デザインのこれら3つのポイントの中でトレードオフが行われることを示しています。厳格なトランザクションは強い一貫性を追求するため、高可用性を犠牲にします。柔軟なトランザクションは、システムの高可用性と引き換えに一貫性を犠牲にします。

システムが分散ソリューションを選択すると、一貫性要件に基づいて選択できます。ビジネスに強い一貫性要件がある場合、XA仕様の2フェーズのコミットを優先します。ビジネスに最終的な一貫性のみが必要な場合、特定のシナリオに基づいた柔軟なトランザクションソリューションから選択できます。

参照する

[1]分散トランザクションミドルウェアTXC(http://mw.alibaba-inc.com/product-txc.html)

[2]弾性設計における補償問題(https://www.jiansshu.com/p/8095001d79bb)

[3]分散トランザクションミドルウェアServiceComb

(http://servicecomb.apache.org/cn/docs/distributed-transactions-saga-implementation/)

[4] 2フェーズコミットの詳細な理解(https://sq.163yun.com/blog/article/165554812476866560)[5] seata(https://seata.io/zh-cn/)

[6] TCCトランザクションの原則

(https://www.cnblogs.com/jajian/p/10014145.html)

[7] TCCトランザクションの例外シナリオ(https://blog.csdn.net/dm_vincent/article/details/92432059

[8]トランザクションパターンの補償

(https://docs.microsoft.com/en-us/azure/architecture/patterns/compensating-transaction)

[9]メッセージベースの分散トランザクション(https://www.jianshu.com/p/04bad986a4a2)

[10]分散トランザクションの概要(http://www.tianshouzhi.com/api/tutorials/distributed_transaction/383)

[11]最初にOpen/X XAを見てください

(https://www.jiansshu.com/p/6c1fd2420274)

[12] DTP:XA仕様

(https://pubs.opengroup.org/onlinepubs/009680699/toc.pdf)

[13] DTPモデル

(https://pubs.opengroup.org/onlinepubs/009249599/toc.pdf)

【この記事は51CTOコラムニスト「アリババオフィシャルテクノロジー」によるオリジナル記事です。転載については原著者にお問い合わせください。

この著者の他の記事を読むにはここをクリックしてください

<<:  クラウドサービスは新しいインフラの「魂」となり、大手クラウドサービスプロバイダー間の競争が激化している。

>>:  クラウド コンピューティングで Python プログラミング言語が使用されるのはなぜですか?

推薦する

お茶のフランチャイズとお茶のブランドのプロモーション

近年、生活水準の向上に伴い、健康に関する話題がますます注目を集めており、人々の健康意識は絶えず高まっ...

1分で分布とクラスタリングを理解する

[[234487]]まず、定義についての私の理解を述べさせてください。分散システムとは、ネットワーク...

360は自社の製品を使って自社の360検索を打ち負かした

360 Search が突如登場してから約 1 か月が経ちました。360 Search が最初にリリ...

画像を最適化したい場合は、これらのポイントを学ぶ必要があります

ウェブマスターのウェブサイトでは、至る所で SEO 担当者がウェブサイトの記事の最適化について話して...

柔軟性を高めるために適切なクラウド プラットフォームを選択し、最適化する方法

運用をクラウドに移行することは、IT とビジネスの俊敏性を高めるための課題であることは広く認められて...

さまざまな詐欺の連鎖手法が暴露されています。騙されてはいけません。

SEO 実践者は皆、2 つのことを繰り返しています。1 つ目は、Web サイトと記事を更新することで...

Raksmartロサンゼルスベアメタルクラウド評価データ共有、raksmartの方法をお伝えします

raksmart データセンターの「ベアメタルクラウド」は、英語で「Bare-Metal Cloud...

flokinet: オランダの苦情に強い VPS、20% 割引、月額 7.6 ユーロ、1G メモリ、1 コア、20g NVMe、3T トラフィック

アイスランドのホスティングプロバイダー flokinet.is (~) は現在、7 月 31 日まで...

bgpto: 日本の東京データセンターにある独立サーバーの簡単な評価、実際のテストデータを共有

bgp.to の日本サーバーは、東京と大阪の 2 つのデータセンターにあります。異なるデータセンター...

Azure Stack HCI と Azure Stack を混同しないでください。

[51CTO.com クイック翻訳] マイクロソフトは先週、Azure Stack HCI のリリー...

エッジコンピューティングについて知っておくべき4つのこと

エッジ コンピューティングは、型破りで最先端の考え方として、テクノロジーの時代精神の中で地位を確立し...

サーバーレス vs. コンテナ: 組織にとってより効果的なクラウド ソリューションの選択

可能な限り短い時間と最小限の労力で、可能な限り多くの作業を完了することが、現代の開発の基本的な特徴で...

ループを回避しながらホームページをリダイレクトする方法

多くの Web サイトでは、ホームページへのリンクとして http://www.yourdomain...

初心者のためのクラウドコンピューティング完全ガイド

このクラウド コンピューティング ガイドでは、クラウド コンピューティングの歴史、機能、利点、欠点、...