面接で聞かれる分散トランザクションをどう解決するか?一気に明らかにしましょう!

分散トランザクションの基本

事務

トランザクションは操作単位を指します。この操作単位内のすべての操作は、最終的には一貫した動作を維持する必要があります。つまり、すべての操作が成功するか、すべての操作がキャンセルされるかのいずれかです。簡単に言えば、トランザクションは「何もしないか、すべてを行う」メカニズムを提供します。

地方事情

ローカル トランザクションは、実際にはデータベースによって提供されるトランザクション メカニズムと考えることができます。データベース トランザクションに関して言えば、データベース トランザクションには 4 つの主要な特徴があると言わざるを得ません。 、
A:原子性(Atomicity)トランザクション内のすべての操作は完了したか、完了していないかのいずれかです。
C:一致性(Consistency)データベースは、トランザクションの実行前後で一貫した状態でなければなりません。トランザクション
I:隔离性(Isolation)。並行環境では、異なるトランザクションが同じデータに対して同時に動作する場合、トランザクションは相互に影響を与えません。つまり、トランザクションが正常に
D:持久性(Durability)終了する限り、データベースに対して行われた更新は永続的に保存される必要があります。

データベース トランザクションが実装されると、トランザクションに関係するすべての操作が分離不可能な実行ユニットに組み込まれます。この実行ユニット内のすべての操作は成功するか失敗します。いずれかの操作が失敗すると、トランザクション全体がロールバックされます。

分散トランザクション

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

簡単に言えば、大規模な操作はさまざまな小さな操作で構成されます。これらの小さな操作は異なるサーバーに分散され、異なるアプリケーションに属します。分散トランザクションは、これらの小さな操作がすべて成功するかすべて失敗することを保証する必要があります。

本質的に、分散トランザクションは、異なるデータベース内のデータの一貫性を確保することを目的としています。

分散トランザクションのシナリオ

  • 単一のシステムが複数のデータベースにアクセスする場合、
    サービスはデータの追加、削除、変更操作を完了するために複数のデータベース インスタンスを呼び出す必要があります。

     

  • 複数のマイクロサービスが同じデータベースにアクセスする
    複数のサービスは、データの追加、削除、変更操作を完了するためにデータベース インスタンスを呼び出す必要がある

     

  • 複数のマイクロサービスが複数のデータベースにアクセスする
    複数のサービスがデータの追加、削除、変更操作を完了するためにデータベース インスタンスを呼び出す必要がある

     

分散トランザクションソリューション

世界情勢

グローバル トランザクションは DTP モデルに基づいて実装されます。DTP は、X/Open 組織によって提案された分散トランザクション モデルですX/Open Distributed Transaction Processing Reference Model分散トランザクションを実装するには、次の 3 つの役割が必要であると規定されています。

  • AP:アプリケーションアプリケーションシステム(マイクロサービス)

  • TM: トランザクション マネージャー トランザクション マネージャー (グローバル トランザクション管理)

  • RM: リソース マネージャー リソース マネージャー (データベース)

トランザクション全体は 2 つのフェーズに分かれています。

フェーズ 1: 投票フェーズでは、すべての参加者がトランザクションの実行を事前に送信し、トランザクションが成功したかどうかに関するフィードバックをコーディネーターに送信します。

フェーズ 2: 実行フェーズでは、コーディネーターは参加者全員のフィードバックに従って参加者全員に通知し、一斉にコミットまたはロールバックを実行します。

 

アドバンテージ:

  • データの整合性の確率が向上し、導入コストが低くなります

欠点:

  • 単一問題点: トランザクション コーディネーターのダウンタイム

  • 同期ブロッキング: 送信時間を遅らせ、リソースのブロッキング時間を延長します。

  • データの不整合: 送信の第 2 フェーズではコミット結果がまだ不明であり、データの不整合が発生する可能性があります。

信頼できるメッセージングサービス

信頼性の高いメッセージ サービスに基づくソリューションは、メッセージ ミドルウェアを通じて上流と下流のアプリケーション データ操作の一貫性を確保することです。
A と B という 2 つのシステムがあり、それぞれタスク A とタスク B を処理できるとします。この時点で、同じトランザクション内でタスク A とタスク B を処理する必要があるビジネス プロセスが存在します。この分散トランザクションを実現するには、メッセージミドルウェアを使用できます。

 

ステップ 1: メッセージはシステム A によってミドルウェアに配信されます。

  1. システム A はタスク A を処理する前に、まずメッセージ ミドルウェアにメッセージを送信します。

  2. メッセージ ミドルウェアはメッセージを受信した後も保持しますが、配信はしません。永続化が成功したら、A に確認応答を返信します。

  3. システム A が確認応答を受信すると、タスク A の処理を​​開始できます。

  4. タスク A が処理された後、コミットまたはロールバック リクエストがメッセージ ミドルウェアに送信されます。リクエストの送信後、システム A ではトランザクションの処理が終了します。

  5. メッセージ ミドルウェアは、Commit を受信するとメッセージをシステム B に配信し、Rollback を受信するとメッセージを直接破棄します。ただし、メッセージ ミドルウェアがコミット コマンドとロールバック コマンドを受信できない場合は、「タイムアウト クエリ メカニズム」に依存する必要があります。

タイムアウト クエリのメカニズム システム A は、通常のビジネス プロセスの実現に加えて、メッセージ ミドルウェアによる呼び出しのためのトランザクション クエリ インターフェイスも提供する必要があります。メッセージミドルウェアはリリースメッセージを受信するとカウントを開始し、タイムアウトしても確認指示を受信しない場合はシステムAが提供するトランザクションクエリインタフェースを能動的に呼び出してシステムの現在の状態を問い合わせます。インターフェイスは 3 つの結果を返し、ミドルウェアは 3 つの結果に応じて異なる反応をします。

  • 送信: メッセージをシステム B に配信します。

  • ロールバック: 最初のメッセージを直接破棄します。

  • 処理中: 待機し続けます

ステップ 2: メッセージはミドルウェアによってシステム B に配信されます。

メッセージミドルウェアは下流システムにメッセージを届けるとブロッキング待ち状態となり、下流システムは直ちにタスクを処理し、タスク処理完了後にメッセージミドルウェアに応答を返します。

  • メッセージミドルウェアは確認応答を受信するとトランザクションが完了したとみなします。

  • メッセージ ミドルウェアが確認応答のタイムアウトを待っている場合、下流のコンシューマが消費成功応答を返すまで再配信されます。
    一般的なメッセージミドルウェアでは、メッセージのリトライ回数や時間間隔を設定できますが、最終的にメッセージが正常に配信されなかった場合は手動での介入が必要になります。ここでシステム A を使用せずに手動介入を使用してロールバックする理由は、主にシステム全体の設計が複雑であるためです。

 

信頼性の高いメッセージ サービスに基づく分散トランザクションの場合、前半では非同期を使用してパフォーマンスに重点を置き、後半では同期を使用して開発コストに重点を置きます。

ベストエフォート通知

定期校正とも呼ばれるベストエフォート通知は、実際には 2 番目のソリューションをさらに最適化したものです。エラー メッセージを記録するローカル メッセージ テーブルを導入し、失敗したメッセージの定期的な校正機能を追加して、メッセージがダウンストリーム システムで確実に消費されるようにします。

 

ステップ 1: メッセージはシステム A によってミドルウェアに配信されます。

  1. ビジネスを処理するのと同じトランザクションでローカル メッセージ テーブルにレコードを書き込みます。

  2. ローカル メッセージ テーブル内のメッセージをメッセージ ミドルウェアに継続的に送信する専用のメッセージ センダーを準備し、送信が失敗した場合は再試行します。

ステップ 2: メッセージはミドルウェアによってシステム B に配信されます。

  1. メッセージを受信した後、メッセージ ミドルウェアは、対応する下流システムにメッセージを同期的に配信し、下流システムのタスク実行をトリガーします。

  2. 下流システムの処理が成功すると、メッセージ ミドルウェアに確認応答がフィードバックされ、メッセージ ミドルウェアはメッセージを削除してトランザクションを完了します。

  3. 配信に失敗したメッセージについては、再試行メカニズムを使用して再試行し、再試行に失敗したメッセージについては、エラー メッセージ テーブルに書き込みます。

  4. メッセージ ミドルウェアは障害メッセージのクエリ インターフェイスを提供する必要があり、ダウンストリーム システムは定期的に障害メッセージをクエリして消費します。

 

このアプローチの長所と短所は次のとおりです。

利点:  結果整合性を実現する非常に古典的な実装です。

短所:メッセージ テーブルはビジネス システムに結合されるため、パッケージ化されたソリューションがない場合は、処理する必要がある多くの雑務が発生します。

TCC事務

TCC は Try confirm Cancel であり、補償分散トランザクションです。TCC は、次の 3 つのステップで分散トランザクションを実装します。

  • Try: 実行するビジネスを試行するプロセスでは、ビジネスは実行されませんが、すべてのビジネスの整合性チェックが完了し、実行に必要なすべてのリソースが確保されます。

  • 確認: 業務の実行を確認するため、業務チェックは行わず、Try ステージで予約した経営リソースのみを使用します。
    通常、TCC が採用されると、確認ステージにはエラーがないと考えられます。つまり、Try が成功する限り、confirm も成功する必要があります。確認ステージで実際のエラーが発生した場合は、再試行メカニズムまたは手動処理が必要です。

  • キャンセル: 保留中のビジネスをキャンセルし、Try ステージで予約されたビジネス リソースをキャンセルします。
    通常、TCC の採用は、キャンセル ステージが成功する必要があることを意味します。キャンセル段階で実際に問題が発生した場合は、再試行メカニズムまたは手動処理が必要になります。

 

TCC 2 フェーズ コミットと XA 2 フェーズ コミットの違いは次のとおりです。

XA は、強い一貫性を備えたリソース レベルの分散トランザクションであり、2 フェーズ コミットのプロセス全体で、リソース ロックが常に保持されます。

TCC は、結果整合性を備えたビジネス レベルの分散トランザクションであり、常にリソース ロックを保持するわけではありません。

TCC トランザクションの長所と短所:

アドバンテージ: 

データベース層の第 2 段階のサブミットは、アプリケーション層を参照して達成され、データベース層の 2PC パフォーマンスが低いという問題を回避します。

欠点: 

TCCのTry、confirm、Cancelの操作機能は企業側で提供する必要があり、開発コストが高くつきます。

佐賀

Saga は補償プロトコルです。Saga モードでは、分散トランザクションに複数の参加者が存在し、各参加者がオフセットのための補償サービスになります。ユーザーは、ビジネス シナリオに応じてフォワード操作とリバース ロールバック操作を実装する必要があります。

 

補償プロトコル: Saga モードでは、分散トランザクションに複数の参加者が存在し、各参加者は前方補償サービスです。上図T1~Tn転送コール補償コールC1~Cnであり、転送コールと補償コールは 1 対 1 に対応しています。

呼び出し先サービスが n 個あると仮定すると、T1これはサービス 1 への呼び出し、その後T2にサーバー 2 への呼び出し、そして T3 はサーバー 3 への呼び出しです。このとき失敗が返された場合はロールバックが必要となり、このときT2対応する補正が呼び出されC2T1対応する補正が呼び出されC1、分散トランザクションは初期状態に戻ります。

佐賀の転送サービスも補償サービスも事業開発者が実施する必要があり、営業侵害にあたります。Saga モードの分散トランザクションは通常、イベントによって駆動され、参加者間で非同期に実行されます。Saga モードは長期的なトランザクション ソリューションです。

サーガモードの使用シナリオ

Saga モードは、トランザクションの最終的な整合性を確保する必要がある長時間の業務プロセスを持つ業務システムに適しており、最初の段階でローカルトランザクションを投入し、ロックなし、長時間処理の場合でもパフォーマンスを保証できます。

トランザクション参加者は他社のサービスやレガシー システムである可能性がありますが、これらは変換できず、TCC で必要なインターフェイスを提供でき、Saga モードを使用できます。

サーガモードのメリットとデメリット

アドバンテージ:

ローカル データベース トランザクションを 1 フェーズでロックなしで高パフォーマンスで送信します。

参加者はトランザクション駆動の非同期実行を使用でき、高スループットの補償サービスはフォワード サービスの「逆」であり、理解と実装が簡単です。

欠点:

Saga モードでは、ローカル データベース トランザクションが最初の段階で送信され、「予約」アクションが実行されていないため、分離を保証できません。

シート

2019 年 1 月に、アリババのミドルウェア チームはオープン ソース プロジェクト Fescar (Fast & EaS​​y Commit AndRollback) を立ち上げ、そのビジョンは、分散トランザクションの使用をローカルと同じくらいシンプルかつ効率的にすることです。その後、Simple Extensible Autonomous Transaction Architecture (分散トランザクション ソリューションのセット) という意味を込めて Seata と名前が変更されました。

Seata の設計目標はビジネスに影響を与えないことであるため、ビジネスに影響を与えない 2PC ソリューションから始まり、従来の 2PC に基づいて進化します。分散トランザクションは、複数のブランチ トランザクションを含むグローバル トランザクションとして認識されます。グローバル トランザクションの責任は、その管轄下にあるブランチ トランザクションを調整して合意に達し、一緒にコミットを成功させるか、失敗してロールバックするかのどちらかにすることです。さらに、通常、ブランチ トランザクション自体はリレーショナル データベースのネイティブ トランザクションです。

Seata は主に 3 つの重要なコンポーネントで構成されています。

TC: トランザクション コーディネーター トランザクション コーディネーターは、グローバル ブランチ トランザクションの状態を管理し、グローバル トランザクションのコミットとロールバックに使用されます。

TM: トランザクション マネージャー トランザクション マネージャー。グローバル トランザクションをオープン、コミット、またはロールバックするために使用されます。

RM: Resource Manager リソース マネージャー。ブランチ トランザクションのリソース管理に使用され、ブランチ トランザクションを TC に登録し、ブランチ トランザクションのステータスを報告し、ブランチ トランザクションをコミットまたはロールバックするコマンドを TC から受け取ります。

 

Seata の実行フローは次のとおりです。

  1. サービス A の TM は、グローバル トランザクションをオープンするために TC に申請します。TC はグローバル トランザクションを作成し、一意の XID を返します。

  2. サービスAのRMはブランチトランザクションをTCに登録し、XIDに対応するグローバルトランザクションの管轄に組み込む

  3. サービス A はブランチ トランザクションを実行し、データベースに対して操作を実行します。

  4. サービスがリモートで B サービスの呼び出しを開始します。この時点で、XID がマイクロサービス呼び出しチェーンに伝播されます。

  5. サービスBのRMはブランチトランザクションをTCに登録し、XIDに対応するグローバルトランザクションの管轄下に置く

  6. サービス B はブランチ トランザクションを実行し、データベースに対して操作を実行します。

  7. グローバル トランザクションの呼び出しチェーンが処理された後、TM は、例外があるかどうかに応じて、グローバル トランザクションのコミットまたは TC へのロールバックを開始します。

  8. TC は管轄下のすべての支店トランザクションを調整し、ロールバックするかどうかを決定します。

Seata の 2PC 実装と従来の 2PC の違い:

  1. アーキテクチャ レベルの観点から見ると、従来の 2PC ソリューションの RM は実際にはデータベース層にあります。RM は本質的にデータベース自体であり、XA プロトコルを通じて実装されますが、Seata の RM はアプリケーション側にミドルウェア層として次の形式で展開されます。瓶パッケージです。

  2. 2 フェーズ コミットに関しては、従来の 2PC は、第 2 フェーズでの解決がコミットであるかロールバックであるかに関係なく、フェーズ 2 が完了するまでトランザクション リソースのロックを解放しません。Seata のアプローチは、フェーズ 1 でローカル トランザクションを送信することで、ロックを保持するフェーズ 2 の時間を節約し、全体の効率を向上させます。

この記事は WeChat 公開アカウント - JAVA Rizhilu (javadaily) から共有されたものです。
侵害がある場合は、[email protected] に連絡して削除してください。
この記事は「OSC ソース作成プログラム」に参加していますので、ぜひ参加・共有してください。

{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/1388595/blog/5125057