この記事はWeChat公式アカウント「妹の味」から転載したもので、著者は妹が飼っている犬です。記事を転載する場合は、ミスシスターテイスト公式アカウントまでご連絡ください。 分散CAP理論は誰もがよく知っているはずです。一貫性 (C)、可用性 (A)、およびパーティション耐性 (P) の間の一連のトレードオフについて説明します。多くの場合、一貫性と可用性のバランスを取る必要があり、分散トランザクションはこの一般的な前提の下で可能な限り一貫性を実現するように設計されています。 目標は小さく、問題は大きく、アプローチは異なります。 「マイクロサービスで分散トランザクションを実装するにはどうすればいいですか?」この質問をされたとき、私は通常「分散トランザクションの使用を避けるようにしてください」と答えます。これは Martin Fowler も推奨しています。しかし現実は常に残酷です。マイクロサービスを分割した後、分散トランザクションは避けられない非常にハードコアな要件であり、まだ解決方法を見つける必要があります。ただし、分散環境は複雑であり、ネットワークの状態によってタイムアウトが発生することがあります。トランザクションを一貫した状態に到達させることは非常に困難です。 分散トランザクションは、一連の小さなサブトランザクションで構成されます。これらのサブトランザクションも、大規模な分散トランザクションと同様に、ACID 原則に従う必要があります。一貫性属性に関しては、一貫性が達成されるまでの時間に応じて、強い一貫性と最終的な一貫性 (BASE) に分けられます。 サブトランザクションについては若干の誤解があることに注意してください。トランザクションと呼ばれるのは、データベースを扱う操作だけではありません。マイクロサービス環境では、RPC を介して別のリモート インターフェイスを呼び出して関連データの状態を変更する場合、この RPC インターフェイスはトランザクションとも呼ばれます。 したがって、分散トランザクションでは、これらのサブトランザクションに関係する操作をリソースと呼びます。操作が正常に完了した場合、追加の処理は必要ありません。トランザクションは主に例外が発生した後の処理を扱います。 次に、一般的な分散トランザクション ソリューションを見てみましょう。 1. 1フェーズコミット(1PC)まず、最も単純なトランザクション送信の状況を見てみましょう。 企業内で調整が必要なリソースが 1 つだけの場合は、直接送信できます。たとえば、データベースを使用する場合は、begin、commit などの命令を直接使用して、トランザクションの送信を完了できます。 Spring では、このようなトランザクションはアノテーションを通じて完了できます。ネストされたトランザクションが発生した場合、基本的には、ThreadLocal を介して渡すことによって実装されます。したがって、管理する必要がある子スレッド関連のトランザクションがアプリケーションにある場合、それを実行することはできません。 分散トランザクションをもう一度見てみましょう。いわゆる分散トランザクションは、2 つ以上のリソースを調整して、共同送信または共同失敗の効果を実現することであり、分散 ACID です。 2. 2フェーズコミット(2PC)1 フェーズ コミットの概念を拡張すると、最も単純な分散トランザクション ソリューションは 2 フェーズ コミットになります。 2 フェーズ コミットは、参加するリソースが 2 つあることを意味するのではなく、分散調整フェーズが 2 つあり、調整が必要なリソースが複数ある可能性があることを意味します。 2.1 主要プレーヤーコーディネーター、つまり独自のトランザクション マネージャーを構築する必要がありますが、通常、システム全体で 1 つしかありません。 トランザクション参加者は、いわゆるリソースを参照します。通常、それらは複数存在します。そうでない場合は、分散トランザクションとは言えません。 2.2 プロセス広い意味で、2PC (2 フェーズ コミット) の 2 つのフェーズとは何ですか?
準備フェーズは投票フェーズとも呼ばれます。いわゆる投票とは、参加者がコーディネータに、リソースを送信できるかどうか(準備ができていることを示す)またはトランザクションをキャンセルするかどうか(例外が発生するなど)を通知することです。 この投票は非常に興味深いです。参加者の 1 人が false を返す限り、トランザクションを終了してロールバックを実行する必要があります。すべての投票が可決された場合にのみ、正常にコミットできます。コーディネーターがすべての参加者に結果を通知するプロセスは第 2 段階です。 2 フェーズ コミットは実は非常に理解しやすいものです。各参加者の実行は、通常の SQL 更新ステートメントとして考えることができます。それらはそこでハングし、コーディネータが明確なコミットまたはロールバック メッセージを出すまで待機し、その後正常に実行されます。 2.3 問題
3番目のポイントについては、例を挙げてみましょう。たとえば、すべてのコミット要求フェーズで yes が返され、その後コーディネーターがコミット コマンドを送信したとします。しかし、このとき、サーバー A の 1 つがクラッシュしたため、コミットを実行できませんでした。この時点で、クライアントにも成功メッセージが届きます。マシン A が再起動した後、回復してコミット命令の実行を継続できる必要があります。これらはすべてエンジニアリングで処理する必要があるものです。 2.4 フレームワーク2PC は XA トランザクションとも呼ばれます。 MySQL などのほとんどのデータベースは XA プロトコルをサポートしています。 Java では、JTA (JPA ではありません) が XA プロトコルの実装です。 Spring には JTA 用のトランザクション マネージャーもあります。 Atomikos と Bitronix は JTA を実装しており、jar パッケージを提供するだけで済みます。 XA プロトコルを実装するデータベースまたはメッセージ キューには、準備、コミット、ロールバックの機能がすでに備わっています。 Seata などのフレームワークで使用する場合は、独立した Seata サービス コーディネーター ノードを起動する必要があります。 seata で使用される AT は外部トランザクション マネージャーを使用し、その概念は XA に似ています。 3. 3相コミット(3PC)2 フェーズ コミットと比較すると、3 フェーズ コミットの最も典型的な機能は、タイムアウト メカニズムが追加されていることです。もちろん、3 段階というのは、3 つの段階があることを証明しており、その差はより顕著です。本質的には 2PC の改良に過ぎないので、完全に 2PC の影に満ちています。 3.1 主要プレーヤー3PCと2PCは同じです。 3.2 プロセス3PC には、2PC よりも 1 つステップが多く、それは調査段階です。
コミット フェーズは、コミット コマンドまたはロールバック コマンドを送信することだけです。重要な処理はまだ準備段階にあります。 3PC はそれを 2 つに分割します。 以下の対応に注意してください。 2PC と 3PC はどちらも準備フェーズがありますが、機能は異なります。
3PC の照会フェーズは、2PC の準備フェーズに対応します。どちらのフェーズでも参加者に準備ができているかどうかを尋ねますが、実行プロセスにはいくつかの違いがあります。 なぜこれをするのですか? 2PC には効率の問題があるからです。 2PC の実行プロセスがブロックされています。リソースが準備フェーズに入った後、次のステップに進む前に、すべてのリソースの準備が完了するまで待機する必要があります。この過程で、彼らは世界情勢について何も知りません。 たとえば、参加者が 5 人 ABCDE おり、E は実際に問題のある参加者リソースです。ただし、2PC は毎回 ABCD の事前コミットを実行します。 E について問い合わせると、問題があることがわかり、ABCD と他の参加者のロールバックを順番に実行します。この場合、ABCD は無駄なトランザクションの前処理とロールバックを実行し、リソースを無駄にします。 3PC は照会フェーズを分割し、すべての参加者が正常な状態にある場合にのみ実際のトランザクション処理を開始するため、より効率的で耐障害性に優れています。確率論的な観点から見ると、コミット前の粒度が小さくなるため、コミット段階で問題が発生する確率が小さくなり、多くのトラブルを回避できます。 さらに、3PC ではタイムアウト メカニズムが導入されています。 PreCommit フェーズでタイムアウトが発生した場合、失敗とみなされます。 DoCommit フェーズでは、タイムアウトが発生した場合でも実行は継続されます。しかし、何があろうとも、すべてが永遠に続くわけではありません。 3.3 問題3PC は理論的には優れており、ブロックの問題を回避できますが、ネットワーク通信が 1 つ多く必要になります。参加者の数が多く、ネットワークの品質が悪い場合、このオーバーヘッドはかなりのものになります。実装も比較的複雑で、実用的なアプリケーションは多くありません。 3PC も完璧ではありません。PreCommit フェーズと DoCommit はアトミックではなく、2PC と同様に一貫性の問題が残っています。 4. TCCTCC は柔軟なトランザクションですが、上で紹介したものは固定されたトランザクションです。場合によっては、技術的な問題はビジネスモデリングを通じて解決できることがあります。 2PC と 3PC は概念的には単純に見えますが、分散環境では、さまざまなタイムアウトやダウンタイムの問題を考慮すると、慎重に検討するのは非常に困難です。 2PC 用のフレームワークは非常に多くありますが、3PC についてインターネット全体を検索したところ、有名な実装はほとんどないことがわかりました。 悲しまないでください。より理解しやすく、より直感的な分散トランザクションを用意しました。それは 2007 年のアンティーク、TCC です。 TCC は有名な補償トランザクションであり、インターネット環境で最も一般的に使用されている分散トランザクションです。その中心的な考え方は、各操作に対して、確認アクションと対応する補償アクション、合計 3 つのメソッドを準備することです。 データベースに頼るのではなく、独自のコードに頼る方がよいでしょう。 2PC と 3PC はすべてデータベースに密接に結びついていますが、TCC はプログラマーに好まれています (つまり、より多くのコードを記述する必要があります)。 画像-20210914162640227.png 写真の通り、TCCも3段階に分かれていますが、とても大まかです!
これら 3 つのステージは、一種の 2 フェーズ コミットのように見えますか?全くない。しかし、それらのプロセスは比較できます。
上記から、2PC はトランザクション プロセスの分割であり、TCC は正常状況の提出と異常状況の補償であることがわかります。従来のコードと比較すると、試行と確認を一緒に行うことで実際のビジネス ロジックが構成されます。 TCC は非常に理解しやすいですが、3 つのアクションがべき等性を持ち、ビジネスに対して特定の要件を満たしている必要があるという大きな前提があります。資金移動を例にとると、金額を凍結してみることになります。確認すると控除が完了します。キャンセルすると金額の凍結が解除されます。対応する注文番号が一貫している限り、複数回実行しても問題ありません。 TCC トランザクションのイニシエーターとして、ビジネス ノード上で直接完了することができ、TCC コードと同じ場所にあります。したがって、TCC では追加のコーディネーターとトランザクション プロセッサは必要ありません。ローカル テーブルまたはリソースに保存できます。 はい、HashMap でも何らかの情報を記録する必要があります。そうしないと、ロールバックの根拠は何でしょうか? 4.1 問題TCC トランザクションでは、より多くのコーディングと、試行と確認の正しい分割が必要です。 TCC は中央コーディネータが存在せず、ブロッキングも必要ないため、同時実行性が高く、インターネット サービスで広く使用されています。 チームは、TCC インターフェイスを設計し、それを適切な試行段階と確認段階に分割し、ビジネス ロジックのグレーディングを実装できる必要があります。 4.2 フレームワークByteTCC、tcc-transaction、seata など。 5. サガSAGA は柔軟性のあるものです。 サガは1987年の論文まで遡る長い歴史があり、古いワインと言えます。これは主に長期間のトランザクションを扱いますが、ACID は保証されず、最終的な一貫性のみが保証されます。 いわゆる長期トランザクションは、インターリーブされたサブトランザクションに分解できます。最終的な一貫性を実現するために、メッセージを通じて一連のローカル サブトランザクションを調整します。 SAGA オーケストレーターはステートマシンとして考えることができます。メッセージが処理されるたびに、次に実行するメッセージ (サブトランザクション) が認識されます。 たとえば、トランザクション T を T1、T2、T3、T4 に分割します。次に、これらのサブトランザクションに対応する実行ロジックと補正ロジックを提供する必要があります。はい、TCC と同じですが、TCC よりも Try アクションが 1 つ少なく、これらの操作がべき等であることも必要です。 実は、SAGA のコンセプトは非常に理解しやすいのです。通常のビジネス ロジックに従って実行するだけです。ただし、いずれかのステップで例外が発生した場合は、以前に送信されたすべてのデータをロールバック (補正) する必要があります。唯一の特別な点は、通常、トランザクション操作がメッセージ駆動を通じて完了することです。 本質を追求するなら、SAGA も TCC も同じで、どちらも最初に実行軌跡を記録し、その後、継続的な再試行を通じて最終状態に到達します。 上の図は、Rob Vettor が描いた典型的な SAGA トランザクション分割図です。図では、黒い線が通常の業務プロセスを表し、赤い線が補償業務プロセスを表しています。これはシンプルな電子商取引のチェックアウトプロセスです。トランザクション全体は 5 つのマイクロサービスにまたがっており、非常に大規模で長いトランザクションであると言えます。 ご覧のとおり、このようなトランザクション フローはテキストの説明では理解しにくいため、SAGA には通常、トランザクション オーケストレーション プロセスを直接視覚化するためのプロセス エディターが装備されています。 5.1 問題その質問の方がずっと興味深いです。
5.2 フレームワークマイクロサービス アーキテクチャ デザイン パターンの第 4 章では、SAGA を使用する具体的な例が説明されており、現在インターネット上の記事のほとんどはここから来ています。しかし、私の知る限り、SAGA を使用しているインターネット企業は多くなく、TCC を使用している企業のほうが多くなっています (おそらく、遭遇する分散トランザクションが長いトランザクションではないためです)。 Seata は、主にステート マシン駆動型オーケストレーション モードを使用する SAGA アプローチも提供します。トランザクションのオーケストレーションをサポートするために、Seata は専用のプロセス エディター (オンライン) を提供します。
設計が完了したら、JSON ファイルとしてエクスポートし、解析後にデータベースに書き込むことができます。 bytetcc は tcc と呼ばれますが、SAGA もサポートしています。 5.3 SAGA vs TCC前述のように、私は日常業務で SAGA よりも TCC を使用していますが、これもビジネス シナリオによって決まります。以下で簡単に比較してみましょう。
6. ローカルメッセージテーブルローカル メッセージ テーブルの使用シナリオは比較的限られています。これらは MQ に依存して実装されます。これらは、データベース トランザクションと MQ 間のトランザクションの問題を解決します。 図に示すように、分散トランザクションが存在します。正常に保存された後は、後続の業務の実行を調整するために MQ が必要になります。ただし、DB への書き込みと MQ への書き込みでは一貫性が確保できないため、MQ に送信されたステータスをキャッシュするためのローカル メッセージ テーブルを追加する必要があります。このプロセスについて以下に説明します。
このようなサイクルを通じて、ローカル DB と MQ コンシューマーの状態の一貫性が実現され、最終的な一貫性を備えた分散トランザクションが完了できます。 ご覧のとおり、MQ を再送信するプロセスがあるため、このモデルでは、重複とビジネスへの影響を回避するために、コンシューマーもべき等関数を実装する必要があります。 6.1 問題ローカル メッセージ テーブル ソリューションを使用しているシステムはまだ多くありますが、その欠点も明らかです。 業務と連動した専用コードを開発する必要があり、抽象的なフレームワークを完結することができません。 ローカル メッセージ テーブルをデータベースに書き込む必要があります。データベース自体の I/O がすでに高い場合は、データベースへの負荷が増加します。 7. ベストエフォート報酬最大努力補償は減衰補償メカニズムです。 最も簡単な例を見てみましょう。 WeChat 支払いのアクセス側の場合、WeChat 支払いが成功すると、指定したインターフェースに支払い結果がプッシュされます。 WeChat 決済 + お支払い結果処理は、大規模な分散トランザクションとみなすことができます。関係するシステムには、WeChat と独自のシステムが含まれます。 システムがリクエストの処理に失敗し続ける場合、WeChat Pay は再試行を続けます。これはベストエフォート補償と呼ばれ、システム内およびシステム間の両方で使用できます。 ただし、無期限に再試行することはできず、再試行の間隔は通常、時間の経過とともに短くなります。一般的に使用される減衰戦略は次のとおりです。
上記の式は、処理が失敗した場合、1 秒後、つまり最大 2 時間後に再試行することを意味します。それでも失敗する場合は、手動処理チャネルに入ることしかできません。 ベストエフォート補償は単なるアイデアであり、実際にそれを適用する方法は数多くあります。たとえば、最初にメッセージ キューにトランザクションを実装し、次にメッセージ キューの再試行メカニズムに依存して、最大限の労力補償の効果を実現します。これらはすべて実行可能な解決策です。 8. 結論この記事では、ローカルの問題から始めて、2PC、3PC、TCC、SAGA、ローカル メッセージ テーブル、ベスト エフォート補償などについて説明しました。また、さまざまなソリューションのいくつかのアプリケーション シナリオとソリューションについても学習しました。 分散トランザクションフレームワークは、これらの理論に基づいてさまざまな程度に改訂され、多くの革新も遂げてきました。たとえば、LCN フレームワーク (ロック、確認、通知) は、コントローラーとイニシエーターの概念を抽象化します。興味のある人は自分で学ぶことができます。 インターネット企業では、高い同時実行性が求められるため、実際のアプリケーションでは、通常、強力なトランザクションではなくソフト トランザクションを選択してビジネスを処理します。最も一般的に使用されるソリューションは、TCC、SAGA、ローカル メッセージ テーブルなどです。SAGA は長いトランザクションの処理に特に適していますが、分離性はやや劣ります。 TCC は一貫性と並行性に優れていますが、より多くのコーディングが必要です。ローカル メッセージ テーブルのアプリケーション シナリオは制限されており、結合されたサービスは再利用できません。各ソリューションには長所と短所があり、使用シナリオに基づいて選択する必要があります。 フレームワークとしては、Alibaba の seata (以前は fescar と呼ばれていました) が広く使用されており、XA、TCC、SAGA などのモードをサポートしています。この機能が必要な場合は、統合してみることができます。 この記事を読んだ後、「マイクロサービスで分散トランザクションを実装するにはどうすればいいか」という疑問に遭遇したときに、繰り返しになりますが、「分散トランザクションの使用を避けるようにしてください」という答えに加えて、本当に実現可能な解決策を見つけることもできます。 著者について: Sister Taste (xjjdog)、プログラマーが寄り道をすることを許可しない公開アカウント。インフラストラクチャと Linux に重点を置きます。 10 年間のアーキテクチャと 1 日あたり数千億のトラフィックを基に、私たちはお客様とともに高並行性の世界を探求し、新たな体験をお届けします。 |
TikTokとWeChatは再び対立しており、過去と同様に、それぞれの側に独自の意見があります。 W...
Baidu アルゴリズムの継続的な更新と改善により、ウェブサイトの降格は当たり前のことになってきてい...
海外VPS(海外VPSレンタル、海外VPSレンタル)をレンタルする場合、(1)国内市場と比較した速度...
Chinanews.com、8月17日。公安部のウェブサイトによると、公安部、国家工商行政管理総局、...
インターネットへの関心が高まるにつれ、ますます多くの伝統的な業界がインターネット マーケティングに関...
北京時間2月25日早朝のニュース、海外メディアの金曜報道によると、米国の判事は先日、プライバシー保護...
組織は、継続的なコンプライアンスを維持しながら、クラウド インフラストラクチャ全体にわたる高度なセキ...
友情リンクとは何ですか?フレンドリー リンクは、インタラクティブなアンカー テキスト リンクとしても...
前回の「インターネット マーケティングの効果を測定するためのコア指標」シリーズでは、エンゲージメント...
Docker を使用すると、開発者やオペレーターはコンテナを使用してアプリケーションを簡単に作成、デ...
インターサーバーはどうですか?インターサーバーロサンゼルスVPSはいかがでしょうか?通常、ホストキャ...
Prohostingserver は、仮想ホスティング、リセラー、VPS、サーバーレンタルを統合した...
みなさんこんにちは。今日は内部リンクの価値についてお話ししたいと思います。なぜ内部リンクの役割ではな...
幸運な人を除いて、経験豊富なウェブマスターなら誰でも、自分のウェブサイトがブロックされた経験があると...
9月3日のアップデートで、百度はウェブサイトのセキュリティリスク警告機能を正式に追加しました。ハッカ...