5 つの主要な分散トランザクションについてどれくらい知っていますか?

5 つの主要な分散トランザクションについてどれくらい知っていますか?

[[396086]]

この記事はWeChatの公開アカウント「Mu Xiaonong」から転載したもので、著者はMu Xiaonongです。この記事を転載する場合は、穆小農の公式アカウントまでご連絡ください。

1. はじめに

トランザクション: 一般的に、実行する必要があること、または実行されたことを指し、トランザクションの開始 (トランザクションの開始) からトランザクションの終了 (トランザクションの終了) までの間に実行されるすべての操作で構成されます。

簡単に言えば、すべてが実行されるか、すべてが失敗するかのどちらかです。

分散トランザクションは、分散システムで実行され、複数の異なるマシン上のトランザクションで構成されるトランザクションです。上記のように、分散システム内のすべてのトランザクションが実行された場合にのみ成功し、そうでない場合は失敗します。

トランザクションACIDの基本特性:

  • 原子性: トランザクションは分割できない作業単位です。トランザクションに含まれるすべての操作は、実行されるか、実行されないかのいずれかになります。
  • 一貫性: トランザクションが実行される前と実行後のデータの整合性を指します。
  • 分離: トランザクションの実行は他のトランザクションによって妨害されることはありません。つまり、トランザクション内で使用される操作とデータは他の同時トランザクションから分離されており、同時に実行されるトランザクションは互いに干渉できません。
  • 永続性: 永続性とも呼ばれ、トランザクションがコミットされると、データベース内のデータに加えられた変更は永続的に保存されます。

2. 分散トランザクションの目標と実際の適用シナリオ

分散トランザクションの目的は、複数の独立したトランザクションの一貫性の問題を解決することです。

たとえば、複数のマイクロサービスにまたがる注文システムという機能があります。各マイクロサービスはライブラリ内にないため、データベース トランザクションを使用してトランザクションを保証することはできません。この場合、分散トランザクションを使用できます。

例: ショッピング モール プロジェクトでは、ユーザーが注文に対して支払いを行います。支払いシステムでは、支払いテーブルが更新されます。別の注文システムでは、注文データベース内の注文のステータスが支払済みになります。注文テーブルと支払いテーブルは異なるデータベースにあるため、2 つのデータベース間のトランザクションをどのように保証できますか?

支払操作:支払残高の変更、注文ステータスの変更

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

  • 2 フェーズ コミット プロトコル (2PC)
  • 3 フェーズ コミット プロトコル (3PC)
  • 補償取引(TCC)
  • メッセージミドルウェアの実装
  • シータフレーム

4. 2フェーズコミットプロトコル(2PC)

XAプロトコルに基づいて、強力な一貫性を採用し、ACIDに準拠します。

2PC: (2 フェーズ コミット プロトコル) は、XA/JTA 仕様に基づいています。

4.1 ゼオ

XA は、X/Open 組織によって提案された分散トランザクション アーキテクチャ (またはプロトコル) です。 XA アーキテクチャは主に、(グローバル) トランザクション マネージャーと (ローカル) リソース マネージャー間のインターフェイスを定義します。

XA インターフェイスは、トランザクション マネージャーと 1 つ以上のリソース マネージャー間の通信ブリッジを形成する双方向システム インターフェイスです。つまり、XA ベースのトランザクションでは、複数のデータベースにアクセスするシステムや、データベースとメッセージング ミドルウェアなどのリソースの両方にアクセスするシステムなど、複数のリソースのトランザクション管理を実行できます。このようにして、コミットされたすべてのトランザクションまたはキャンセルされたすべてのトランザクションを複数のデータベースとメッセージ ミドルウェアに直接実装できます。 XA 仕様は Java 仕様ではなく、一般的な仕様です。

4.2 シリアル

JTA (Java Transaction API) は、XA プロトコルの JAVA 実装である J2EE のプログラミング インターフェイス仕様です。主に以下を定義します。

トランザクション マネージャー インターフェイス javax.transaction.TransactionManager は、トランザクションの開始、コミット、取り消しなどの操作を定義します。 XA 仕様に準拠したリソース定義インターフェース javax.transaction.xa.XAResource。リソースが JTA トランザクションをサポートする場合、XAResource インターフェイスと、インターフェイスによって定義された 2 フェーズ コミット関連のインターフェイスを実装する必要があります。

4.3 フローチャート

4.4 提出プロセス

1. 要求フェーズ (コミット要求フェーズ、投票フェーズとも呼ばれる、手順 (1 ~ 5)) 要求フェーズでは、コーディネーターはトランザクション参加者にトランザクションをコミットまたはキャンセルする準備をするように通知し、その後投票プロセスに入ります。投票プロセス中に、参加者はコーディネーターに決定を通知します。同意 (トランザクション参加者のローカル ジョブ実行が成功) またはキャンセル (ローカル ジョブ実行が失敗)。

2. コミット フェーズ、手順 (6 ~ 7) このフェーズでは、コーディネータは最初のフェーズの投票結果に基づいてコミットするかキャンセルするかを決定します。すべての参加者がトランザクションをコミットすることに同意した場合にのみ、コーディネーターはすべての参加者にトランザクションをコミットするように通知します。それ以外の場合は、コーディネーターはすべての参加者にトランザクションをキャンセルするように通知します。参加者はコーディネーターからのメッセージを受信した後、対応する操作を実行します。

4.5 デメリット

  • 単一障害点: トランザクションの開始、送信、キャンセルはすべてコーディネータによって管理されます。コーディネーターがダウンしたら、すべてが台無しになります。
  • 同期ブロッキングのデメリット: 上記の紹介と例から、参加システムがボスの実際の送信またはキャンセルトランザクション指示を受信しない場合、現在のリソースがロックされ、実際にはトランザクション関連の操作が実行されないことがわかります。そのため、分散システム環境全体がブロックされます。
  • データの不整合のデメリット: ボスコーディネーターが実際のトランザクション送信を弟に送信すると、ネットワーク障害により一部のシステムが実際の指示を受信できず、一部の送信が表示され、一部の送信は表示されません。したがって、データの不整合が発生します。

4.6 解決できない問題

コーディネータがミスを犯し、参加者もミスを犯した場合、2 フェーズ プロセスではトランザクション実行の整合性を保証できません。コミット メッセージを送信した後にコーディネータがクラッシュし、このメッセージを受信する唯一の参加者も同時にクラッシュするとします。そうすると、新しいコーディネーターがいても、このトランザクションのステータスは不確実であり、トランザクションがコミットされたかどうかは誰にもわかりません。それを知っていた人々は沈黙させられた。

5. 3フェーズコミットプロトコル(3PC)

強力な一貫性を採用し、ACID に準拠します。第 2 フェーズでは、タイムアウトと事前送信のメカニズムが追加されます。 3つの主要なフェーズ、canCommit、preCommit、doCommitがあります。

5.1 フローチャート

5.2 プロセス

1. CanCommit フェーズ: 3PC の CanCommit フェーズは、実際には 2PC の準備フェーズと非常によく似ています。コーディネーターは参加者にコミット要求を送信し、参加者はコミットできる場合は Yes 応答を返し、そうでない場合は No 応答を返します。

2. PreCommit フェーズ: コーディネータは、コホートの応答に基づいて、トランザクションの PreCommit 操作を続行するかどうかを決定します。

応答に応じて 2 つの可能性があります。 A. コーディネーターがすべてのコホートから Yes 応答を受け取った場合、トランザクションを事前実行し、事前コミット要求を送信します。コーディネーターはコホートに PreCommit リクエストを送信し、準備フェーズに入ります。トランザクションの事前コミット。 PreCommit 要求を受信すると、コホートはトランザクション操作を実行し、元に戻す情報とやり直し情報をトランザクション ログに記録します。フィードバックに応答します。コホートがトランザクション操作を正常に実行すると、ACK 応答を返し、最終命令の待機を開始します。

B. いずれかのコホートがコーディネータに No 応答を送信した場合、またはコーディネータが待機タイムアウト後にコホートから応答を受信しなかった場合、割り込み要求を送信してトランザクションが中断されます。コーディネーターはすべてのコホートに中止要求を送信します。トランザクションを中断します。コホートがコーディネータから中止要求を受信した後 (またはタイムアウト後もコホート要求が受信されない場合)、トランザクションは中断されます。

3. DoCommit フェーズ: このフェーズは実際のトランザクションをコミットするために使用されます。これは次の 2 つの状況に分けられます。

commitAを実行します。コミットリクエストを送信します。コーディネーターは、コホートから送信された ACK 応答を受信すると、コミット前状態からコミット状態に移行します。そして、すべてのコホートに doCommit リクエストを送信します。 B.トランザクションのコミット。 doCommit リクエストを受信すると、Cohort は正式なトランザクション コミットを実行します。トランザクションのコミットが完了したら、すべてのトランザクション リソースを解放します。 C. フィードバックに応答します。トランザクションがコミットされると、ACK 応答がコーディネーターに送信されます。 D. 取引を完了します。コーディネーターがすべてのコホートから ACK 応答を受信すると、トランザクションが完了します。

割り込みトランザクションコーディネータが参加者から送信された ACK 応答を受信しない場合、割り込みトランザクションが実行されます。

A. 割り込み要求を送信します。コーディネーターはすべての参加者に中止要求を送信します。 B. トランザクションのロールバック。中止要求を受信した後、参加者はフェーズ 2 で記録された元に戻す情報を使用してトランザクションのロールバック操作を実行し、ロールバックが完了したらすべてのトランザクション リソースを解放します。 C. フィードバック結果参加者がトランザクションのロールバックを完了すると、コーディネータに ACK メッセージを送信します。 D. トランザクションの中断 コーディネータは参加者からフィードバックされた ACK メッセージを受信すると、トランザクションの中断を実行します。

5.3 デメリット

コーディネータが PreCommit に入った後に中止要求を送信した場合、1 つのコホートのみが中止操作を受信して​​実行し、システム ステータスに不明な他のコホートが 3PC に基づいてコミットを続行することを選択すると、システム ステータスが不整合になります。

5.4 2PCと3PCの違い

質問を追加すると成功の可能性が高まります。

タイムアウト メカニズムは、コーディネーターとコホートの両方に設定されます (2PC では、タイムアウト メカニズムがあるのはコーディネーターのみで、つまり、一定時間内にコホートからメッセージが受信されない場合は、デフォルトで失敗します)。コーディネータが失敗し、参加者がタイムアウトを待機する場合、トランザクションはデフォルトでコミットされます。少し進歩しました。

参加者が異常であり、コーディネーターも異常である場合、他の参加者は強制的に服従させられます。

事前コミット フェーズは 2PC の準備フェーズとコミット フェーズの間に挿入されるため、3PC には CanCommit、PreCommit、DoCommit の 3 つのフェーズがあります。 PreCommit は、最終コミット フェーズの前に、参加しているすべてのノードの状態が一貫していることを保証するバッファーです。

6. メッセージベースの最終的な一貫性

最終的な一貫性を採用し、BASE 理論に従います。

BASE: 正式名称は、「Basically Available (基本的に利用可能)」、「Soft state (ソフト状態)」、「Eventually Consistent (最終的に一貫性がある)」という 3 つのフレーズの略称です。これはeBayの建築家によって提案されました。

基本的に利用可能: 分散システム環境では、メイン プロセスに影響しない一部の機能の利用不可を犠牲にしてダウングレードし、コア サービスの通常の可用性を確保することが許可されます。

ソフト状態: トランザクションにおいて、システムに影響を与えることなく、システムが中間状態を持つことを許可することを意味します。データベースのマスター・スレーブ・レプリケーションを例に挙げます。レプリケーション中に遅延が発生することは完全に許容されます。

最終的に一貫性がある: データベースのマスター スレーブ レプリケーションを例にとると、マスター スレーブ レプリケーションにはわずかな遅延がありますが、最終的にはすぐにデータの一貫性が保たれます。

分散トランザクションは問題を 100% 解決することはできませんが、成功の確率を高めることしかできません。 2 つのステージ間の時間はミリ秒単位です。解決策: 時間指定のタスク補正。プログラムまたはスクリプトの補償。人間の介入。

7. TCC

ソリューション: TCC (Try、Confirm、Cancel)、2 段階の補償ソリューション。

名前の通り、トランザクションを実装するには、リソースの事前占有、実際の操作リソースの確認とコミット、占有のキャンセル = ロールバックの 3 つの API を定義する必要があります。

後者の 2 つのステップが実行の途中で失敗した場合は、ログに記録し、補正を行って、人間のスタッフに通知します。

2PC: リソース レベルでの分散トランザクションであり、常にリソース ロックを保持します。

データベースが 12 個以上ある場合、一度に多数のデータベースをロックすると、リソースが極度に浪費されることになります。スループットが低下しました。

TCC: ビジネス レベルでの分散トランザクションは最終的に一貫性があり、常にロックを保持するわけではありません。ロックの粒度が削減され、データベースに対する各操作の後にロックが解除されます。

それはすべて相対的です。1 日にリクエストが 1 件しかない場合は、2PC の方が TCC よりもパフォーマンスが優れています。 tcc には複数のインターフェース呼び出しがあるためです。現時点では、2PC は 1 回の呼び出しだけなので、リソースを占有することを恐れません。 TCC は、同時実行性の高いシナリオで大きな利点があります。

8. メッセージミドルウェアの実装

メッセージ キューの柔軟なトランザクション フロー チャート:

1. 支払いテーブルを操作し、状態を「新規」にしてイベント テーブルにデータを挿入し、データベースに格納します。これらの操作 (1、2、3) はすべて 1 つのデータベース内にあるため、1 つのトランザクションに含まれます。

2. スケジュールされたタスクはイベント テーブルを読み取り、キューに送信します。送信が成功すると、イベント テーブル new の状態が (公開済み) に変更され、イベント テーブルが監視され、イベント テーブルにデータが挿入されます。

3. スケジュールされたタスクが公開イベント テーブルを読み取るかどうかを確認します。公開されたイベント テーブルの場合は、注文テーブルを更新し、イベント テーブルを処理済みに更新します。これにより、大きなトランザクションが複数の小さなトランザクションに分割されます。

テーブルデザイン:

  1. 作成する テーブル`t_order_event` (
  2. `id` int (16)はない  NULL
  3. `order_type` varchar (32)デフォルト  NULL COMMENT 'イベントタイプ(支払いテーブルの支払い完了、注文テーブルの変更ステータス)'
  4. `process` varchar (32)文字  utf8mb4utf8mb4_0900_ai_ciのデフォルトにセットする  NULL COMMENT 'イベントリンク(新規、公開済み、処理済み)'
  5. `content` varchar (255)デフォルト  NULL COMMENT 'イベントコンテンツ、イベント発生時に渡す必要のあるデータを保存します'
  6. `create_time` 日時デフォルト  NULL  の上 アップデート  CURRENT_TIMESTAMP
  7. `update_time` 日時デフォルト  NULL  の上 アップデート  CURRENT_TIMESTAMP
  8. 主要な キー(`id`)
  9. ) エンジン=InnoDBデフォルト文字セット=utf8mb4照合=utf8mb4_0900_ai_ci;

9. Seataフレームワーク

Seata は、高性能で使いやすい分散トランザクション サービスを提供することを目的としたオープン ソースの分散トランザクション ソリューションです。 Seata は、ユーザーに AT、TCC、SAGA、XA トランザクション モードを提供し、ユーザー向けのワンストップ分散ソリューションを作成します。

公式ウェブサイト API (強く推奨): https://seata.io/zh-cn/docs/overview/what-is-seata.html

Seata ダウンロードアドレス: https://seata.io/zh-cn/blog/download.html

フローチャート:

手順:

1. seataサーバーをダウンロードする

https://seata.io/zh-cn/blog/download.html

2. file.confを変更する

  1. サービス {
  2. #トランザクションサービスグループマッピング
  3. # 変更、オプション、my_test_tx_group に任意の名前を付けるだけです。
  4. vgroup_mapping.my_test_tx_group = "デフォルト"  
  5. # registry.type=fileの場合にのみサポートされます複数のアドレスを設定しないでください。
  6. # このサービスのアドレス
  7. デフォルト.grouplist = "127.0.0.1:8091"  
  8. #シートを無効にする
  9. グローバルトランザクションを無効にする = false  
  10. }
  11.  
  12. 店 {
  13. ## 保存モード: ファイル、DB
  14. # 改訂
  15. モード = "db"  
  16.  
  17. ## ファイルストアプロパティ
  18. ファイル {
  19. ##保存場所のディレクトリ
  20. dir = "セッションストア"  
  21. }
  22.  
  23. ##データベースストアプロパティ
  24. #db情報の変更
  25. デシベル{
  26. ## DruidDataSource(druid)/BasicDataSource(dbcp)などjavax.sql.DataSource実装。
  27.    
  28. データソース = "ドルイド"  
  29. ## mysql/oracle/h2/oceanbase など
  30. dbタイプ = "mysql"  
  31. ドライバークラス= "com.mysql.cj.jdbc.Driver"  
  32. url = "jdbc:mysql://127.0.0.1:3306/seata-server?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai"  
  33. ユーザー= "root"  
  34. パスワード= "root"  
  35. }
  36. }

3. registry.confを変更する

  1. レジストリ {
  2. # ファイル、nacos、eureka、redis、zk、consul、etcd3、sofa
  3. #改訂
  4. タイプ = "ユーレカ"  
  5.  
  6. ナコス
  7. サーバーアドレス = "localhost"  
  8. 名前空間 = ""  
  9. クラスター = "デフォルト"  
  10. }
  11. #改訂
  12. ユーレカ
  13. サービス URL = "http://localhost:8761/eureka"  
  14. アプリケーション = "デフォルト"  
  15. 重み = "1"  
  16. }
  17. レディス{
  18. サーバーアドレス = "localhost:6379"  
  19. デシベル = "0"  
  20. }
  21. ずっ
  22. クラスター = "デフォルト"  
  23. サーバーアドレス = "127.0.0.1:2181"  
  24. セッションタイムアウト = 6000
  25. 接続.タイムアウト = 2000
  26. }
  27. 領事 {
  28. クラスター = "デフォルト"  
  29. サーバーアドレス = "127.0.0.1:8500"  
  30. }
  31. etcd3 {
  32. クラスター = "デフォルト"  
  33. サーバーアドレス = "http://localhost:2379"  
  34. }
  35. ソファー
  36. サーバーアドレス = "127.0.0.1:9603"  
  37. アプリケーション = "デフォルト"  
  38. リージョン = "DEFAULT_ZONE"  
  39. データセンター = "DefaultDataCenter"  
  40. クラスター = "デフォルト"  
  41. グループ= "SEATA_GROUP"  
  42. アドレス待機時間 = "3000"  
  43. }
  44. ファイル {
  45. 名前= "file.conf"  
  46. }
  47. }
  48.  
  49. 設定{
  50. # ファイル、nacos、apollo、zk、consul、etcd3
  51. タイプ = "ファイル"  
  52.  
  53. ナコス
  54. サーバーアドレス = "localhost"  
  55. 名前空間 = ""  
  56. }
  57. 領事 {
  58. サーバーアドレス = "127.0.0.1:8500"  
  59. }
  60. アポロ
  61. app.id = "seata-server"  
  62. apollo.meta = "http://192.168.1.204:8801"  
  63. }
  64. ずっ
  65. サーバーアドレス = "127.0.0.1:2181"  
  66. セッションタイムアウト = 6000
  67. 接続.タイムアウト = 2000
  68. }
  69. etcd3 {
  70. サーバーアドレス = "http://localhost:2379"  
  71. }
  72. ファイル {
  73. 名前= "file.conf"  
  74. }
  75. }

4. データベースを作成し、テーブルを作成する

ブランチトランザクションテーブル: branchtableグローバルトランザクションテーブル: globaltableグローバルロック: lock_table

注: 表の構造は間違ってはいけない

5. ロールバック用に各ライブラリにundo_logを追加する

  1. 作成する テーブル`undo_log` (
  2. `id`ビッグイント(20) NOT   NULL AUTO_INCREMENT、
  3. `branch_id` bigint (20) ではない  NULL
  4. `xid` varchar (100)文字  UT8をセットしてUTF8_general_ciを照合しない  NULL
  5. `context` varchar (128)文字  UT8をセットしてUTF8_general_ciを照合しない  NULL
  6. `rollback_info` longblob ではない  NULL
  7. `log_status` int (11)はない  NULL
  8. `log_created` 日時NOT   NULL
  9. `log_modified` 日時NOT   NULL
  10. `ext` varchar (100)文字  UT8照合UTF8_general_ciデフォルトを設定  NULL
  11. 主要な  KEY (`id`) BTREEの使用、
  12. 個性的 キー`ux_undo_log` (`xid`,`branch_id`) BTREE の使用
  13. ) ENGINE=InnoDBデフォルトCHARSET=utf8 ROW_FORMAT= DYNAMIC ;

10. まとめ

以上が分散トランザクションの紹介です。理解できない場合は、ディスカッションにメッセージを残すことができます。 Xiaonong はそれを見た瞬間に返信します。記事の不足部分について補足したり、ご意見をお送りいただくことも歓迎いたします。ありがとう、これからも続けてください。

<<:  企業内の複数のSaaSコラボレーション間の障壁を打ち破り、テンセント・千帆がエンタープライズアプリケーションコネクタをリリース

>>:  943MBから6.34kBへ、コンテナサイズを縮小する課題

推薦する

マイクロサービスにおける分散ロックの正しい姿勢をマスターする

[[391029]]序文Java ではロックはよく知られており、よく使用されるのは synchron...

ウェブサイトのプロモーションに入札することに不安を感じていますか? キーワード分析を学べば、その理由がわかります。

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますウェブサイ...

巨華軒の100億元補助金「狙撃兵」拼多多

コアリーディングJuhuasuan は Double 12 を選択してPinduoduo を直接ター...

Sveltos による Kubernetes アドオン ライフサイクル管理

Sveltos は、クラスター全体にわたる Kubernetes アドオンの展開を簡素化し、クラスタ...

すべてにインターネット思考が必要:「Roujiamo」からマイクロマーケティングを学ぶ

最近、「宇宙の中心」北京五道口に「西少葉」肉家墨という大人気の店が出現した。オープン初日に1,200...

共同購入サイトのほぼ半数が閉鎖され、多くの従業員が新しい仕事を見つけるのに苦労している。

共同購入業界は縮小している。 Tuan800の最新レポートによると、6月末現在、国内の共同購入サイト...

品質を重視したIoTデバイスがエッジコンピューティングを推進

高品質なコンテンツに対する期待が高まっており、モノのインターネットの成長により、エンドユーザーはエッ...

外部リンクにおける百度製品の重要性

現在、ウェブサイトの外部リンクを作成する人の多くは、Baidu の外部リンクを作成することについて話...

クラウドコンピューティング、ビッグデータ、人工知能の関係

今日のスマート業界で最もホットなトピックは、クラウド コンピューティング、ビッグ データ、人工知能で...

地域社会が悪質な登録を防ぐ方法

実際、左志明は最近、地域コミュニティの運営を研究しており、主要な地域ポータルコミュニティのウェブサイ...

Googleが検索結果からアンダースコアを削除したことは重要だ

2014 年 3 月 14 日、Google は検索結果ページのタイトルから下線を削除し、20 年間...

Google Cloudは長年失われていた

クラウドコンピューティングの分野では、Google は常に恥ずかしい存在であったようです。 Goog...

香港のドメイン名登録総数は2014年第1四半期に2,595件減少した。

IDC Review Network (idcps.com) は 4 月 14 日に次のように報告し...

2019年、大手企業は補助金戦争をやめるだろうか?

Ele.meがアリババに買収され、BaiduがO2O分野から撤退したことで、Meituanとアリババ...

オンラインマーケティングの効果を測定するための中核指標と、どのような論理的思考を用いるか(2)

【序文】前回の記事では、インターネット マーケティングの効果を測定する主な 2 つの方法、「人の心の...