分散トランザクションの選択:XA、2PC、TCC、Saga、Ali Seata

マイクロサービスの登場以来、過去数年で、ByteTCC、TCC-transaction、EasyTransaction、最近人気の高いSeataなど、多くの分散トランザクションフレームワークが登場しました。最近、私はSeataのソースコード(v0.5.2)を見て、分散トランザクションに関する私の理解の一部を記録する機会を得ました。(3年前は、プロジェクト自体で柔軟なトランザクションフレームワークを作成する必要があったため、この種のフレームワークはまだ成熟していませんでした)。

この記事は5つのパートに分かれています。最初に、分散トランザクションの概念の進化を明らかにし、次にXAが不要な理由を簡単に説明します。3番目のパートでは、2フェーズサブミッションの「リフト」について説明します。4番目のパートでは、シータのアーキテクチャのハイライトと問題を紹介します。分散トランザクションの選択について話します。

スペースの制限により、オンラインで検索可能な詳細の一部はこの記事では詳しく説明しません(たとえば、XA、Saga、TCC、Seataなどの原則の詳細な紹介)。

まず、分散トランザクションの一般化

分散トランザクションに関しては、複数のリソースが関係するデータベーストランザクションの問題が最も早い時期に発生します。

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

ただし、トランザクションという用語の意味はSOAアーキテクチャーとともに徐々に拡大し、状況に応じて2つのカテゴリーに分類できます。

  • システムトランザクション;

  • 事業取引。

前者はデータベーストランザクションを指し、後者はビジネストランザクションを指します。

同時に、分散型トランザクションの意味も一般化しており、特にSOAとマイクロサービスの概念が普及した後は、主にビジネスシナリオを指します。独立してデプロイされた多数のサービスを配置する必要がある場合は、トランザクション全体の原子性と一貫性を確保する方法性的な問題。このタイプの分散トランザクションは、飛行機の購入、レンタカー、ホテルの予約で構成される固定旅行トランザクションなどの長期トランザクションとも呼ばれます。フライトの予約の確認には1〜2日かかる場合があります。概念の理解を統一するために、この記事ではデフォルトでそのような長いトランザクションを参照しています。

分散トランザクションの概念の一般化には技術的な問題も伴いますが、マイクロサービスでの分散トランザクションのACIDをどのように保証する必要がありますか?従来の2フェーズコミット/ XAでも解決できますか?データベースベースのXAが自分でできるAdouに少し似ていて動作しないのは残念です。

2.なぜ誰もがXAを使用しないのですか?

実際には必要ありません。たとえば、IBMメインフレーム上のCICSに基づく多くのクロスリソースは、XAプロトコルに基づく分散トランザクションです。実際、XAは分散トランザクション処理の標準でもありますが、インターネットではほとんど使用されません。理由は私は以下があると思います:

  • パフォーマンス(ブロッキングプロトコル、応答時間の増加、ロック時間、デッドロック);

  • データベースサポートの完全性(MySQL 5.7より前のすべてに欠陥があります)。

  • コーディネーターは、独立したJ2EEミドルウェア(初期のWeblogic、Jboss、後期の軽量Atomikos、Narayana、およびBitronix)に依存しています。

  • O&Mは複雑であり、DBAはこの分野での経験がありません。

  • すべてのリソースがXAプロトコルをサポートするわけではありません。

  • 大きな工場はそれを理解していないので、中小企業はそれを敢えて使用しません。

厳密に言うと、XAは仕様とプロトコルです。XAは一連のインターフェースのみを定義します。ただし、現在のXAの実装のほとんどはデータベースまたはMQです。そのため、XAについて言及するときは、多くの場合、リソースレイヤーに基づいた基盤となる分散トランザクションソリューションを指します。実際、一部のデータシャーディングフレームワークやミドルウェアもXAプロトコルをサポートしていますが、結局のところ、その互換性と普遍性は優れています。

3.「プロモーション」は2段階で送信されます

データベースベースのXAプロトコルは基本的に2フェーズコミットですが、パフォーマンス上の理由から、インターネットでの同時実行性の高いシナリオには適していません。データベースがローカルACIDのみを保証できる場合、一貫性Cを保証するために、トランザクション異常が発生した後、トランザクション全体のアトミック性をどのようにして実現しますか?さらに、処理中に分離を確実にする方法は?

最も直接的な方法は、論理に従ってサービスを1つずつ呼び出すことですが、例外がある場合はどうなりますか?次に、正常に補正されたものを補正し、補正が成功します。単純なモデルは佐賀です。しかし、佐賀はこのように隔離を保証していなかったため、TCCが登場しました。実際のトランザクションロジックの前に、ビジネスをチェックし、関連するビジネスリソースまたは「中間状態」で「予約」を実行します。すべての予約が成功した場合は、これらの予約されたリソースの実際のビジネス処理を完了します。チケット席などのシーン。

もちろん、Ebayに基づくメッセージテーブル、つまり信頼性のあるメッセージの一貫したモデルもありますが、これは基本的には佐賀モデルの特定の実装でもあります。

  • アプリケーション共有トランザクションに基づいて実行軌跡を記録します。

  • 次に、非同期再試行によってトランザクションが最終的に一貫していることを確認します(これにより、この方法は、ビジネスで補正ロールバックが許可されているシナリオには適さなくなります)。

このタイプの分散トランザクションシナリオは、マイクロサービスだけでなく、SOA時代にも存在します。CommonSaga、TCC、および信頼性の高いメッセージの最終的に一貫したモデルも、何年も前から存在していましたが、最近になってようやく登場しました。マイクロサービスの台頭により、これらのソリューションは再び注目を集めています。

「佐賀」参照リンク:https://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf

これらのソリューションをXAと注意深く比較すると、これらのソリューションは基本的にリソースレイヤーからアプリケーションレイヤーへの2フェーズコミットであることがわかります。

  • 佐賀の核心は補償です。最初の段階は通常のサービス呼び出しのシーケンスです(データベーストランザクションは正常に送信されます)。実行が成功した場合、2番目の段階では何​​も行われません。ただし、実行に例外がある場合は、補償サービスが順番に呼び出されます。 (通常、未実行のサービスの逆トランザクションを逆の順序で呼び出します)、トランザクション全体の一貫性を確保します。アプリケーションの実装コストは平均です。

  • TCCの特徴は、ビジネスリソースのチェックとロックです。第1ステージはリソースをチェックしてロックします。第1ステージが成功すると、第2ステージがロックされたリソースに対してトランザクションロジックを実行します。それ以外の場合は、ロックされたリソースが解放されます。アプリケーションの実装コストは高くなります。

  • 信頼性の高いメッセージに基づいて、サービスは通常、最初の段階で呼び出され、メッセージテーブルがトランザクションとともに記録されます。2番目の段階では、メッセージが配信および消費されます。アプリケーションの実装コストは低いです。

これらのモデルに基づく分散トランザクションフレームワークに固有であり、DTP(分散トランザクション処理)モデルも利用します。

DTP(分散トランザクション処理)参照リンク:http://pubs.opengroup.org/onlinepubs/009680699/toc.pdf

▲DTPモデル

  • RMはローカルトランザクションの送信を担当し、同時にトランザクションの参加者の役割を果たしながら、ブランチトランザクションの登録とロックの決定を完了します。

  • TMは、トランザクション全体のサブミットとロールバックのトリガーを担当し、トランザクション全体のコーディネーターの役割を果たします。

異なるフレームワークが実装されている場合、各コンポーネントの役割の機能と展開形式はニーズに応じて調整されます。たとえば、一部のTMはアプリケーションと一緒にjarパッケージの形式で展開され、一部は削除されて個別に展開する必要があります(たとえば、SeataのTMの主な機能) TC(Transaction Coordinator)と呼ばれる論理的に一元化されたサーバーに配置します)

第4に、シータアーキテクチャの利点と損失

アリは今年の初めに、オープンソースの分散トランザクションフレームワークであるFescarをリリースしました。これは、後にAnt TCCプログラムと統合された後、Seataに名前が変更されました。現在のバージョンは0.6に過ぎませんが、GitHubスターは9kを超えています。アスペクトは、アリの分散トランザクションフレームワークに対する皆の期待も示しています。

Seataの使用法と原則はgithub wikiで明確に説明されており、インターネット上のソースコード分析に関する記事は多数あります。次に、Seata ATモードの原理を分析して、そのハイライトと問題を確認します。

「Seataの使用法と原則」参照リンク:https://github.com/seata/seata/wiki

SeataのMTおよびTCCのサポートは制限されており、これらの2つのモードは、既存のアプリケーションエコシステムとの互換性を高めるためのものです。

Seataチームは詳細なコールフローチャートを作成しました。この図に照らしてソースコードを読む方がはるかに簡単です。

▲シータ実行フローチャート

1.ハイライト

他の分散トランザクションフレームワークと比較すると、Seataアーキテクチャの主な特徴はいくつかあります。

  • アプリケーション層は、SQL解析に基づく自動補正を実装し、ビジネスへの侵入を最小限に抑えます。

  • トランザクションの登録とロールバックを担当する分散トランザクションでのTC(トランザクションコーディネーター)の独立した配置。

  • グローバルロックを通じて、書き込みの分離と読み取りの分離を実現します。

これらの機能の具体的な実装メカニズムについては、公式Webサイトとgithubで詳しく説明されているため、ここでは紹介しません。

2.パフォーマンスの低下

シータが追加したオーバーヘッドを見てみましょう(純粋なメモリ操作では無視できます)。

更新SQLには、グローバルトランザクションのxid取得(TCとの通信)、イメージの前(SQLの解析、データベースのクエリを1回)、イメージの後で(データベースのクエリを1回)、アンドゥログの挿入(データベースの書き込みを1回)、コミットの前に(TCを使用)通信(ロックの競合を判別するため)では、これらの操作はリモート通信RPCを必要とし、同期されます。

また、元に戻すログが書き込まれるときのBLOBフィールドの挿入パフォーマンスは高くありません。SQLを書き込むたびにオーバーヘッドが大きくなり、概算で応答時間が5倍になると推定されます(第2段階は非同期ですが、実際にはシステムリソース、ネットワーク、スレッド、データベースを占有します)。

前面と背面の画像を生成する方法は?

druidを使用してSQLを分析し、ビジネスSQLのwhere条件を再利用して、実行するSelect SQLを生成します。

3.コストパフォーマンス

自動補正を実行するには、すべてのトランザクションを前後にミラーリングして保持する必要があります。しかし、実際のビジネスシナリオでは、この成功率はどれくらいですか、または分散トランザクションの失敗をロールバックする必要がある比率はいくつですか。この比率はシナリオによって異なります。トランザクションオーケストレーションを実行する前に多くのトランザクションが正しいかどうかがチェックされることを考えると、ロールバックの確率は実際には比較的低くなります。28番目の原則によると、トランザクションの20%をロールバックするには、成功したトランザクションの80%の応答時間を5倍にする必要があると推定されます。このコストは、アプリケーションに補償トランザクションを開発させるよりも価値がありますか?それは私たちの検討に値するものです。

業界には、ミラーリングの前後にデータベースビンログを使用してSQLを復元するという考え方もあります。これにより、元に戻すログ生成レコードの同期が保存され、パフォーマンスの損失が減ると同時に、ビジネスへの侵入がゼロになるので、個人的にはより良い方法だと感じています。

4.グローバルロック

1)ホットスポットデータ

Seataは各ブランチトランザクションで対応するロック情報を伝達し、コミットステージの前に順番にロックを取得します(すべてのロック情報を取得する前にすべてのSQL情報を実行する必要があるため、コミット前に判断されるため)。XAと比較して、Seataは最初のステージの成功後にデータベースロックを解放しますが、最初のステージの前にグローバルロックを決定すると、データロックの占有時間も長くなります。このオーバーヘッドは、実際のビジネスシナリオによるXAの準備よりもはるかに低くなります。テストする。グローバルロックの導入により分離が実現しますが、問題はブロッキングであり、同時実行性、特にホットデータが減少するため、この問題はより深刻になります。

2)ロールバックロックの解放時間

Seataがロールバックする場合、TCメモリのロックを解放する前に各ノードの取り消しログを削除する必要があるため、第2ステージがロールバックの場合、ロックを解放する時間が長くなります。

3)デッドロックの問題

Seataのグローバルロックの導入により、デッドロックのリスクがさらに増加し​​ますが、デッドロックが実装されている場合、再試行を続け、最終的にグローバルロックがタイムアウトするまで待機します。この方法はエレガントではなく、データベースロックの占有時間も長くなります。

「シータグローバルロックの導入によりデッドロックのリスクが高まる」参照リンク:https://github.com/seata/awesome-seata/blob/master/wiki/en-us/Fescar-AT.md

5.その他の問題

1)シータを使用する一部のアプリケーションで、データがダーティまたはファントムでないことを確認するにはどうすればよいですか?

Seataは@GlobalLockアノテーションを提供します。これは軽量のグローバルロック決定の機能を提供できます(元に戻すログを生成しません)。ただし、Seataを使用するには統合する必要があります。

2)TCは論理的に単一のポイントであり、高可用性と高パフォーマンスを実現する方法は、引き続き後続のバージョンで継続的な最適化を必要とします。

3)スタンドアロンのマルチデータソースクロスサービスは現在サポートされていません。

5、分散トランザクションの選択

厳密なACIDトランザクションには、分離に対する高い要件があります。トランザクションの実行中はすべてのリソースをロックする必要があります。長いトランザクションの場合、トランザクション期間全体でデータを排他的に使用すると、システムの同時パフォーマンスに深刻な影響を与えます。したがって、同時実行性の高いシナリオでは、ACIDの一部の機能が緩和されてパフォーマンスが向上し、BASEの柔軟なトランザクションが実現します。柔軟なトランザクションのアイデアは、mutex操作をリソースレベルからビジネスロジックを通じてビジネスレベルに移動することです。強整合性の要件を緩和することにより、システムのスループットが向上します。さらに、例外が発生した後のトランザクションの最終的な一貫性を保証するために、自動例外回復メカニズムが提供されます。

XAに基づく分散トランザクションがACIDを厳密に保証する必要がある場合、実際のトランザクション分離レベルはSERLALIZABLEです。

上記からわかるように、柔軟なトランザクションにはアプリケーション層が参加する必要があるため、このタイプの分散トランザクションフレームワークの最初の機能の1つは、ビジネスの変革のコストを最小限に抑え、パフォーマンス(応答時間、スループット)を可能な限り改善して、できれば分離を確保することです。 。

優れた分散トランザクションフレームワークアプリケーションは、次の特性を可能な限り満たしています。

  • ビジネス変革の低コスト。

  • パフォーマンスの低下が少ない。

  • 分離は完全であることが保証されています。

しかし、CAPと同様に、これらの3つの特性は相互にチェックおよびバランスが取れており、多くの場合、そのうちの2つしか満たせず、三角形の制約を描くことができます。

事業報酬に基づく佐賀は1.2を満たし、TCCは2.3を満たし、シータは1.3を満たします。

もちろん、分散トランザクションフレームワークを自分で設計する場合は、他の多くの機能を検討し、ターゲットシナリオの設定をクリアした後、トレードオフを行う必要があります。これらの機能には、以下が含まれますが、これらに限定されません。

  • ビジネス侵入(注釈、XML、補償ロジックに基づく);

  • 分離(書き込み分離/読み取り分離/コミットされていない読み取り、ビジネス分離/技術分離)

  • TM / TC展開フォーム(個別の展開とアプリケーションの展開);

  • エラー回復(自動回復、手動回復);

  • パフォーマンス(ロールバックの確率、支払った価格、応答時間、スループット)。

  • 高可用性(登録センター、データベース);

  • 永続性(データベース、ファイル、複数コピー一貫性アルゴリズム);

  • 同期/非同期(2PC実行モード);

  • ログのクリーンアップ(自動、手動);

  • ……

6.まとめ

分散トランザクションは、常に業界では困難な問題でした。困難は、CAPの定理、分散システムでの8つの主要な誤った仮定、FLPの不可能な原理、およびスタンドアロントランザクションのACIDの比較に慣れているという事実にあります。データベース分野のXA、Googleパーコレーター、Calvinモデル、またはサーガ、TCC、マイクロサービスでの信頼性の高いメッセージングやその他のソリューションなど、分散トランザクションの問題は完全には解決されていません。特定のシーン設定の下でトレードオフを求める。

「8 Distributed System Assumptions」の参照リンク:http://%5Bhttps://en.wikipedia.org/wiki/Fallacies_of_distributed_computing%5D(https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing)

「FLP不可能原則」参照リンク:html%5D(https://www.cnblogs.com/firstdream/p/6585923.html)

実際、ネットワークの不確実性のために、配布中の多くの問題が問題です。最善の解決策は、分散トランザクションを回避することです:)

最後に、トピックに戻って、シータは分散トランザクションの問題を解決しましたか?あなたが最も気にかけているものを見なさい。ビジネスをできるだけ賢明にしたい場合で、DBの操作が単純な場合は驚かされますが、応答時間を重視すると、DBの書き込み操作が多くなり、呼び出しチェーンが長くなると、期待外れになることがあります。最後に、シータオープンソースプロジェクトがどんどん良くなっていることを願っています!

元の記事を203件公開 賞賛6件 訪問4482件

おすすめ

転載: blog.csdn.net/weixin_42073629/article/details/105545392
おすすめ