ホームページ >データベース >mysql チュートリアル >分散トランザクションの詳細な図解説明

分散トランザクションの詳細な図解説明

不言
不言転載
2018-12-15 10:41:398827ブラウズ

この記事の内容は、分散取引について写真と文章で詳しく解説していますので、困っている方は参考にしていただければ幸いです。

今回は分散トランザクションフレームワークを使いながら分散トランザクションの知識を学んだので、この記事では分散トランザクションについてお話します。まず、トランザクションとは何かを確認しましょう。

トランザクション

トランザクションとは何ですか?これはバックエンド開発であり、日常の開発でデータベースとのやり取りがある限り、トランザクションが使用されることは間違いありません。ここで、トランザクションとは何かを説明するために Wiki から説明を抜粋します。

は、データベース管理システムの実行プロセスにおける論理単位であり、限られた一連のデータベース操作で構成されます。

データベース システムにはトランザクション特性があり、これがデータベース システムを区別する重要な機能です。ファイルシステムから。従来のファイル システムでは、ファイルの書き込み中にオペレーティング システムが突然クラッシュすると、ファイルが破損する可能性があります。データベース システムには、データベースがある状態から別の状態に確実に変化するようにトランザクション機能が導入されています。作業を送信するときに、すべての変更が保存されるか、何も保存されないかのどちらかを確認できます。

通常、トランザクションは複数の読み取りおよび書き込み操作で構成されます。

トランザクションには、一般に ACID として知られる 4 つの基本特性があります。

A(原子性): 原子性。トランザクションは、すべてのステートメントが成功するか、すべてが失敗するかのどちらかとして扱われます。一部のステートメントが成功し、一部のステートメントが失敗するという状況は存在しません。

C(一貫性): 一貫性。データベースの状態がある状態から別の状態に変化する場合、データベースの整合性制約は、トランザクションの開始前と終了後も変更されません。データベース整合性制約とは何を意味しますか?たとえば、テーブルの名前フィールドが一意制約である場合、トランザクションがコミットまたはロールバックされた後に名前フィールドが一意でなくなると、データベースの整合性制約が破壊されます。

I(孤立): 孤立。複数の同時トランザクションは、相互に影響を与えることなく実行されます。

D(耐久性): 耐久性。トランザクションがコミットされた後、データベースに対する変更をデータベースに永続的に保存できます。したがって、この機能では、データベース システムがクラッシュ時に復元する必要がある場合に、データを失わずに送信できる必要があります。

したがって、初期の頃、私たちのシステムには 1 つのデータ ソースしかありませんでしたが、この時点では、ビジネスの正確性を確保するためにデータベース システムのトランザクションに依存することができました。

ただし、ビジネスが拡大し続けると、ビジネスの 1 つのテーブルに数千万のデータが含まれる可能性があり、別のデータベース インスタンスを使用すると、パフォーマンスの問題が発生する可能性があります。この時点では、サブデータベースとテーブルについて検討します。ただし、これにより、単一のアプリケーションが複数のデータ ソースに接続される可能性があります。以下の例を参照してください。

分散トランザクションの詳細な図解説明

上記の購入プロセスでは、販売者残高テーブルとユーザー残高テーブルは 2 つの別々のデータベース インスタンスにあるため、別々のトランザクションで確実に控除を行うことができます。販売者残高またはユーザー残高の控除は成功するか失敗します。ただし、両方のトランザクションが同時に成功するか失敗するかは保証できません。

システムがますます大きくなるにつれて、システム アプリケーションを複数のマイクロサービスに分割して、1 つのアプリケーションが 1 つのデータ ソースのみを操作できるようにすることも考えられます。このとき、次の図に示すように、1 つのビジネス コールで複数のアプリケーションが呼び出され、各アプリケーションが独立してデータ ソースを操作する状況が発生します。

分散トランザクションの詳細な図解説明

この場合、すべての呼び出しが成功することは保証できません。

上記の例から、ビジネスの発展に伴い、従来のスタンドアロン トランザクションではビジネスのニーズを満たすことができなくなっていることがわかります。現時点では、それを確保するために分散トランザクションが必要です。

分散トランザクション

Wiki の説明からの抜粋です。

分散トランザクションは、2 つ以上のネットワーク ホストが関与するデータベース トランザクションです。

まず、分散トランザクションを実装するための理論的基礎について話しましょう。

分散トランザクション技術理論

CAP定理。分散システム (相互に接続され、データを共有するノードの集合) では、読み取りおよび書き込み操作に関しては、一貫性、可用性、およびパーティション耐性のみを保証できます。そのうち、他方は犠牲にする必要があります。 。

0から始めるギークタイム学習アーキテクチャ第22章解説より抜粋

CAP の理論的な定義では、3 つの要素のうち 2 つだけを選択できますが、分散環境で考えると、ネットワーク自体が選択できないため、P (パーティション トレランス) 要素を選択する必要があることがわかります。 100%を達成する 信頼性は高いものの、失敗する可能性があるため、パーティション分割は避けられない現象です。 CA を選択して P を放棄した場合、パーティショニングが発生したときに、 C では、システムは書き込みを禁止する必要があります。書き込み要求があると、システムはエラーを返します (たとえば、現在のシステムでは書き込みが許可されていません)。A はエラーを返さないことを要求しているため、これは A と競合します。 そしてタイムアウトなし。したがって、分散システム用の CA アーキテクチャを選択することは理論的に不可能であり、次の 3 つの単語の略語である CP または AP アーキテクチャ

BASE 理論のみを選択できます。

基本的に利用可能: 分散システムに障害が発生した場合、コア機能を確実に利用できるようにするために、利用可能な機能の一部が失われることが許容されます。

ソフト状態 (ソフト状態): システム内の中間状態の存在を許可します。この状態は、システムの可用性には影響しません。これは、CAP の不一致を指します。

最終的に整合性 (最終的に整合性): 結果的に整合性とは、一定期間後にすべてのノード データが整合性を持つことを意味します。

BASE は、CAP の AP スキームの補足です。 BASE でソフト状態と結果整合性を使用して、遅延整合性を確保します。 BASE と ACID は反対です。ACID は強整合性モデルですが、BASE ではこの強整合性が犠牲になり、短期間でデータの不整合が生じても、最終的には整合性が保たれます。

次に、分散トランザクションの実装オプションを見てみましょう。

分散トランザクション実装計画

  1. データベース リソース レベルに基づく

  • 2PC 2 フェーズ送信プロトコル

  • 3PC 3 フェーズ サブミッション プロトコル

  • ビジネス レベルに基づく

    • TCC

    データベースリソースレベルの実装計画に基づいて、複数のトランザクションがあるため、各トランザクションのステータスを管理する役割が必要です。この役割をコーディネーターと呼び、トランザクションの参加者を参加者と呼びます。参加者とコーディネーターは通常、特定のプロトコルに基づいています。現在、より有名なものは XA インターフェイス プロトコルです。コーディネーターと参加者のイデオロギー設定に基づいて、2PC と 3PC が XA 分散トランザクションを実装するために提案されました。

    2PC 2 フェーズ コミット プロトコル

    名前のとおり、このプロセスは主に 2 つのステップに分かれています。

    最初のフェーズでは、コーディネーター (トランザクション マネージャー) が関連するトランザクションを事前送信します。この時点で、データベース リソースは ロックされ始めます。参加者は、元に戻すおよびやり直しをトランザクション ログに書き込みます。 第 2 フェーズでは、参加者 (リソース マネージャー) がトランザクションをコミットするか、Undo ログを使用してトランザクションをロールバックし、リソースを解放します。

    全体のプロセスは次のとおりです。

    分散トランザクション送信成功シナリオ:

    分散トランザクションの詳細な図解説明

    分散トランザクション ロールバック シナリオ:

    分散トランザクションの詳細な図解説明

    このソリューションの利点は、実装が比較的シンプルで、主流のデータベースでサポートされており、強い一貫性があることです。 MySQL 5.5 以降は、XA プロトコルに基づいて実装されます。

    対応するソリューションにも欠点があります。

    1. コーディネーターの単一点の問題です。送信フェーズ中にコーディネーターがダウンし、参加者が待機している場合、リソースはロックされブロックされます。コーディネーターを再選することは可能ですが、これでは問題は解決されません。

    2. 同期のブロック時間が長すぎます。送信プロセス/ロールバック プロセス中に、送信が完了してリソースが解放されるまで、実行プロセスのトランザクション全体がブロックされます。 、参加者はブロックされています。指示が受信されない場合、参加者はブロックされたままになります。

    3. データに一貫性がありません。第 2 段階では、コーディネーターが最初のコミット シグナルを送信してクラッシュすると、最初のパーティシパントがトランザクションを送信しますが、2 番目のパーティシパントはコーディネーター シグナルを受信して​​いないためトランザクションをコミットできません。

    そこで、2PC の欠点を踏まえて、3PC という改善案が提案されました。

    3PC 3 フェーズ サブミッション プロトコル

    3 フェーズ サブミッションは、2 フェーズ サブミッションに基づいて、2 フェーズを改良したものです。 3段階の手順は以下の通りです。

    1. CanCommit の場合、コーディネーターは参加者にトランザクションをコミットできるかどうかを尋ねます。

    2. PreCommit: すべての参加者がトランザクションをコミットできる場合、コーディネーターは PreCommit コマンドを発行し、参加者はリソースをロックして最後のコマンドを待ちます。

    • #すべての参加者は確認情報を返し、コーディネーターは各トランザクションにトランザクション実行通知を発行し、リソースをロックして実行ステータスを返します。

    • 一部の参加者が拒否情報を返したか、コーディネーターがタイムアウトになりました。この場合、コーディネーターはトランザクションが正常に実行できないと判断し、割り込みコマンドを発行し、各参加者は準備状態を終了します。
  • Do Commit。第 2 フェーズで ACK への応答がすべて発行された場合、Do Commit が発行され、トランザクションが最終的に送信されます。それ以外の場合は、トランザクション中断コマンドが発行されます。すべての参加者はトランザクションをロールバックします。

    • すべての参加者はトランザクションを通常どおり実行し、コーディネーターは最終コミット命令を発行してロックされたリソースを解放します。

    • 一部の参加者がトランザクションの実行に失敗し、コーディネーターがタイムアウトになり、コーディネーターはロックされたリソースを解放するロールバック コマンドを発行しました。

    # 詳細については、下の図を参照してください。

    分散トランザクションの詳細な図解説明#3 フェーズ送信は 2 フェーズと比較して、トランザクションのブロックを減らし、単一点障害を解決するタイムアウト メカニズムを導入しています。 3 番目のフェーズでは、参加者がコーディネーター信号の受信に失敗すると、タイムアウトを待った後、参加者はデフォルトでコミットを実行し、リソースを解放します。

    3 つの段階ではまだデータの一貫性の問題を解決できません。コーディネーターがロールバック コマンドを発行しても、ネットワークの問題により、参加者が待機時間内にそのコマンドを受信できない場合、この時点で参加者はデフォルトでトランザクションをコミットし、他のトランザクションがロールバックされるため、トランザクションの不整合が発生します。

    TCC

    TCC トランザクション

    トランザクション実行中の粒度の大きなリソース ロックの問題を解決するために、業界は、ビジネスレベルのトランザクション定義。ロックの粒度はビジネス自体によって完全に制御されます。それは本質的に補償の考えです。トランザクションの実行プロセスを、試行と確認/キャンセルの 2 つの段階に分割します。各段階のロジックはビジネス コードによって制御されます。このようにして、トランザクションのロック粒度を完全に自由に制御できます。ビジネスは、分離を犠牲にしても、より高いパフォーマンスを達成できます。

    TCC は、それぞれ Trying、confirm、Cancel の略です。データベース レベルに基づく 2PC および 3PC とは異なり、TCC はアプリケーション レベルに基づきます。

    TCC の 3 つのアクションは次のとおりです。


    試行:

      すべてのビジネス チェック (一貫性) を完了します。
    • 必要なビジネスを予約します。リソース(準隔離)
    • ##確認:

    ##実際に業務を実行

    • # #操作の確認冪等性を満たす必要があります

    • キャンセル:
    • ##試行フェーズで確保されたビジネス リソースを解放します

    ##キャンセル操作は冪等性を満たす必要があります

    • 上記の文は少しぎこちなく、理解しにくいように思えますが、問題はありません。実際のケースを使って説明しましょう。

    • 以下では、モールでの 1 回限りの支払いプロセスをシミュレートします。ユーザーは注文時に複合支払い、つまり残高と赤い封筒の支払いを使用します。通常のプロセスは次のとおりです:
    • 注文の作成

    注文の実行

    1. コール残高システム、残高を差し引いてください
    2. 赤い封筒システムに電話して、赤い封筒の残高を差し引いてください
    • 注文ステータスを支払い済みに変更してください

    • 完了後にお支払いください。

    • #実際の処理は以下の通りです。

    ただし、このような支払いプロセスでは複数のサブサービスが呼び出されるため、すべてのサービスが成功するかどうかは保証できません。たとえば、赤色のサービスを呼び出す場合などです。エンベロープ システムが赤エンベロープ システムの失敗を差し引く。この時、赤い封筒サービスの障害によりメソッドが異常終了してしまうという恥ずかしい場面に遭遇しました。これはユーザーエクスペリエンスにとって非常に不親切です。したがって、この支払いプロセス中に、このプロセスを動作全体として扱うメカニズムが必要であり、このプロセス内のすべてのサービス呼び出しが成功または失敗し、トランザクション全体になることを保証する必要があります。

    分散トランザクションの詳細な図解説明現時点では、TCC トランザクションを導入し、注文プロセス全体を全体として扱うことができます。導入後、残高システムの引き落としが失敗したため、このタイミングでオーダーシステムと紅封筒システムをロールバックしました。全体のプロセスを以下に示します。

    分散トランザクションの詳細な図解説明残高システムに障害が発生したため、このプロセスでのすべての変更を元に戻す必要があるため、注文システムにキャンセル通知を送信します。および赤い封筒システムの失効通知。

    したがって、システムに TCC トランザクションが導入された後、呼び出しプロセスを変更する必要があります。

    TCC トランザクションをシステムに導入する方法分散トランザクションの詳細な図解説明TCC トランザクションの 3 つのステップに従って、現時点では、各サービスを試行、確認、キャンセルの 3 つのステップに変換する必要があります。

    TCC 試してみます:

    上記の業務に従って、注文システムは注文ステータスを PAYING に変更するための try メソッドを追加します。残高システムには、まず残高が十分であるかどうかを確認し、次に残高を差し引き、次に差し引かれた残高を凍結金額に追加する try メソッドが追加されます。赤封筒システムはバランスシステムと同じです。変換プロセスから、TCC try メソッドは各ビジネス リソースをチェックする必要があり、このプロセスでは中間状態を導入する必要があることがわかります。以下の図に基づいてプロセス全体を見てみましょう。

    分散トランザクションの詳細な図解説明

    TCC 確認:

    TCC ステップ 1 試してみる すべてのサブサービス呼び出しが成功した場合、この時点で確認する必要があります。それぞれのサーブ。各サービスに確認メソッドを追加します。たとえば、残高システムの確認メソッドは凍結金額を 0 に設定するために使用され、赤封筒システムは上記のとおりです。注文システムにより、注文ステータスが SUCCESS に変更されます。確認メソッドは冪等性の実現に注意する必要があります。たとえば、注文システムを更新する前に、注文ステータスが PAYING であることを確認してから注文を更新する必要があります。全体のプロセスを以下に示します。

    分散トランザクションの詳細な図解説明

    # そういえば、各サービスのプロモーションには TCC トランザクション フレームワークを使用する必要があります。 TCC トランザクション マネージャーは、TRY メソッドの終了を感知すると、各サービスが提供する確認メソッドを自動的に呼び出して、各サービスのステータスを最終状態に変更します。

    TCC キャンセル:

    TCC Try プロセス中に赤いエンベロープの凍結方法が失敗した場合は、以前の変更をすべて元に戻して、初期状態に変更する必要があります。 cancel メソッドも、以下に示す確認メソッドのように冪等である必要があります。

    分散トランザクションの詳細な図解説明

    これを見ると、TCC Try が成功し、確認は成功、試行は失敗、キャンセルは成功する必要があります。システムを最終状態に更新するには確認が鍵となるためです。しかし、現実は非常に冷酷であり、本番システムでの確認またはキャンセルが失敗する可能性は確実にあります。この場合、TCC フレームワークは確認の呼び出し結果を記録する必要があります。確認呼び出しが失敗した場合、TCC フレームワークはそれを記録し、一定の間隔で再度呼び出す必要があります。

    要約と感想

    全文を読んだ後は、分散トランザクションについて基本的に理解する必要があります。

    これを踏まえてまとめます。分散トランザクションを使用するには、それを実際のシナリオと組み合わせて適用する必要があります。

    ビジネスがまだ初期段階にある場合は、実際にデータベース トランザクションを選択して、オンラインでの迅速な反復を確保できます。

    ビジネスが一定の段階に達すると、システムが分割され始めます。このとき、ビジネスで一貫性を確保する必要がある場合は、分散トランザクションを使用する必要があります。このときに分散トランザクションを利用する場合、業務に応じてどちらを利用するかを検討する必要があります。

    2PC または 3PC によって実装された分散フレームワークを使用すると、ビジネス アプリケーション層を変更する必要がなく、アクセスが比較的簡単です。ただし、それに対応するパフォーマンスは低く、データ リソースは長時間ロックされます。インターネットなどの同時実行性の高いビジネス シナリオには適していません。

    TCC ベースの分散フレームワークを使用すると、2PC よりも高いパフォーマンスが得られ、データの最終的な整合性を確保できます。しかし、アプリケーション層では、1 つのメソッドを 3 つのメソッドに変換する必要があり、いくつかの中間状態をビジネスに導入する必要があるため、アプリケーションの変換の度合いは比較的大きくなります。

    以上が分散トランザクションの詳細な図解説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。