分散トランザクションと分散システムの整合性ソリューション

分散システムでは、「一貫性」、「可用性」、「パーティションフォールトトレランス」の3つすべてを同時に満たすことは不可能です。分散システムでのトランザクションの一貫性は技術的な問題です。どちらのソリューションが優れていますか?
OLTPシステムの分野では、ボブがスミスに送金する最も典型的なケースなど、多くのビジネスシナリオでトランザクションの一貫性の必要性に直面します。従来のエンタープライズ開発では、システムは単一のアプリケーションの形式で存在することが多く、複数のデータベースにまたがることはありません。
通常は、開発プラットフォーム(Spring、JDBC、ADO.NETなど)で独自のデータアクセステクノロジとフレームワークを使用し、リレーショナルデータベースのトランザクション管理メカニズムと組み合わせてトランザクション要件を達成するだけで済みます。リレーショナルデータベースには通常、原子性、一貫性、分離性、耐久性などのACID特性があります。
大規模なインターネットプラットフォームは、多くの場合、一連の分散システムで構成され、開発言語プラットフォームとテクノロジースタックは比較的複雑です。特に、今日のSOAおよびマイクロサービスアーキテクチャでは、一見単純な機能に多くの内部呼び出しが必要になる場合があります。「サービス」と運用複数のデータベースまたはシャードを実現するには、状況がはるかに複雑になることがよくあります。単一の技術的手段とソリューションでは、これらの複雑なシナリオに対処して満足させることはできなくなります。
分散システムの特徴は、
読者に分散システムの研究をしてもらい、「CAPの法則」や「塩基理論」などを聞いたことがあるかもしれませんが、非常に賢く、化学理論ACIDは酸であり、塩基はたまたまアルカリ性です。著者はここでこれらの概念をあまり説明していません、そして興味のある読者は関連する参考資料をチェックすることができます。CAP法は次のとおりです。
CAP法

分散システムでは、「CAP法」の「一貫性」、「可用性」、「パーティションフォールトトレランス」を同時に満たすことは不可能です。「白、豊か、美しい」はより困難です。インターネット分野のほとんどのシナリオでは、システムの高可用性と引き換えに強力な整合性を犠牲にする必要があります。システムは、最終時間がユーザーが許容できる範囲内にある限り、「最終的な整合性」を確保するだけでよいことがよくあります。
分散トランザクション
は分散システムに言及し、分散トランザクションに言及することになります。分散トランザクションを理解するには、最初に2フェーズコミットプロトコルを導入する必要があります。簡単ですが不正確な例を挙げて説明します。
最初の段階では、張先生が「コーディネーター」としてWeChatをXiaoqiangとXiaoming(参加者、ノード)に送信し、明日8時に学校の門に集まるように編成します。一緒に山に登り、XiaoqiangとXiaomingが返事をするのを待ち始めました。
第2段階では、XiaoqiangとXiaomingの両方が質問に答えなかった場合、全員が予定どおりに到着しました。XiaoqiangまたはXiaoMingのいずれかが「明日は無料ではありません、いいえ」と答えた場合、張先生はすぐにXiaoqiangとXiaoMingに「登山活動はキャンセルされました」と通知します。
注意深い読者は、このプロセスに多くの問題があるかもしれないことに気付くでしょう。Xiaoqiangが電話を見なかった場合、張先生は返事を待っていたでしょう。XiaoMingは自宅ですべての登山用具を準備したかもしれませんが、張先生が情報を確認するのを待っていました。さらに深刻なのは、Xiaoqiangが明日8時までに応答しなかった場合、たとえ「タイムアウト」になったとしても、Xiaomingは登山のために集まるかどうかということです。
これは2フェーズ送信プロトコルの欠点であるため、業界は後にこのタイプの問題を解決するために3フェーズ送信プロトコルを導入しました。
2フェーズ送信プロトコルは、主流の開発言語プラットフォームおよびデータベース製品で広く使用および実装されています。XOpen組織が提供するDTPモデル図は次のとおりです。

XOpenが提供するDTPモデル

XAプロトコルは、TM(トランザクションマネージャー)とRM(リソースマネージャー)の間のインターフェイスを指します。現在の主流のリレーショナルデータベース製品はすべてXAインターフェイスを実装しています。JTA(Java Transaction API)はX / Open DTPモデルに準拠しており、XAプロトコルはトランザクションマネージャーとリソースマネージャーの間でも使用されます。本質的に、2フェーズコミットプロトコルは分散トランザクションの実装にも使用されます。XAトランザクションの成功と失敗のモデル図を見てみましょう。
XAの成功
XAが失敗しました

JavaEEプラットフォームでは、WebLogicやWebshareなどの主流の商用アプリケーションサーバーがJTAの実装とサポートを提供します。ただし、Tomcatでは実装されていません(実際、TomcatをJavaEEアプリケーションサーバーと見なすことはできないと思います)。これを実現するには、サードパーティのフレームワークJotm、Automikosなどを使用する必要があります。どちらもSpringをサポートしています。トランザクション統合。
Windows .NETプラットフォームでは、ado.netのTransactionScop APIを使用してプログラムできます。また、WindowsオペレーティングシステムでMSDTCサービスを構成して使用する必要があります。データベースがmysqlを使用していて、mysqlがLinuxプラットフォームにデプロイされている場合、分散トランザクションをサポートできません。スペースに限りがあるため、ここでは拡張しません。興味のある読者は、関連資料を参照して、自分で練習することができます。
概要:この方法は実装がそれほど難しくなく、従来のモノリシックアプリケーションに適しています。同じ方法でデータベース間の操作が行われます。ただし、分散トランザクションはパフォーマンスに比較的大きな影響を与えるため、同時実行性とパフォーマンス要件が高いシナリオには適していません。アーキテクチャ、機能X、A、B、さらに多くのアトミックサービスのバックエンドを調整する必要性のサービスで
提供さ
れるロールバックインターフェイスしたがって、問題は、AとBの呼び出しの1つが失敗した場合はどうなるかということです。
著者の仕事でこのような問題に遭遇することがよくあり、AサービスとBサービスの呼び出しを調整するためにBFFレイヤーを提供することがよくあります。一部の結果を同期的に返す必要がある場合は、「シリアル」方式でそれらを呼び出そうとします。呼び出しAが失敗した場合、Bは盲目的に呼び出されません。Aへの呼び出しは成功したが、Bへの呼び出しが失敗した場合、Aへの呼び出しを今すぐロールバックしようとします。
もちろん、対応する個別のロールバックインターフェイスを厳密に提供する必要がない場合もありますが、パラメータを渡すことで巧妙に実装できます。
この場合、ロールバックインターフェースを提供できるサービスを前面に出すように最善を尽くします。例を見てみましょう。
私たちのフォーラムの1つは、毎日正常にログインした後、ユーザーに5ポイントを提供しますが、ポイントとユーザーは2つの独立したサブシステムサービスであり、異なるDBに対応するため、制御がより面倒です。ソリューション:
1.ログインおよびボーナスポイントのサービスコールをBFFレイヤーのローカルメソッドに配置します。
2.ユーザーがインターフェースへのログインを要求した場合、最初にポイントを追加する操作を実行し、ポイントが正常に追加された後にログイン操作を実行します。3
。ログインが成功した場合は、もちろんそれが最善であり、ポイントも正常に追加されます。ログインに失敗した場合は、追加したポイントに対応するロールバックインターフェースを呼び出します(ポイントを引く操作を実行します)。

概要:この方法には多くの欠点があり、非常に単純なシナリオであり、ロールバックを提供するのが非常に簡単で、依存するサービスも非常に少ない場合を除いて、通常、複雑なシナリオでは推奨されません。
この実装により、大量のコードと高い結合度が発生します。また、簡単にロールバックできないビジネスが多いため、非常に限られています。シリアルサービスが多い場合、ロールバックのコストが高すぎます。


実際、この考え方を実現するためのローカルニューステーブルは、ebayから派生し、後に業界で広く使用されているAlipayの説教から派生しています。基本的な設計の考え方は、リモート分散トランザクションを一連のローカルトランザクションに分割することです。パフォーマンスとデザインの優雅さを考慮しない場合は、リレーショナルデータベースのテーブルを使用して実現できます。
説明するために銀行間送金の典型的な例を見てください。
最初のステップの擬似コードは次のとおりです。1Wを差し引き、ローカルトランザクションを介してバウチャーメッセージがメッセージテーブルに挿入されるようにします。
偽のコード
2番目のステップは、1Wが銀行口座に追加されたことを相手に通知することです。次に、問題は、相手にどのように通知するかです。
通常2つの方法:
1。サブスクリプションメッセージと他のリッスン、ニュースイベントによって自動的にトリガーされるMQの高い適時性
2.ポーリングモードはスキャンのタイミングを使用して、
2つの方法でデータメッセージテーブルをチェックします。実際には長所と短所があります。 MQのみに依存している場合、通知の失敗の問題が発生する可能性があります。また、定期的なポーリングが多すぎると、効率が最高になりません(90%は役に立たない)。したがって、通常は2つの方法を組み合わせて使用​​します。
通知の問題は解決され、新しい問題があります。このニュースが繰り返し消費され、ユーザーのアカウントにさらにお金が追加された場合、その結果は深刻ではないでしょうか。
よく考えて、実際に消費者に知らせ、「消費状況表」を通じて消費状況を記録することができます。「追加」操作を実行する前に、メッセージ(IDを提供)が消費されているかどうかを確認し、消費が完了した後、ローカルトランザクション制御を介して「消費ステータステーブル」を更新します。このようにして、繰り返し消費される問題が回避されます。

概要:アピール方法は非常に古典的な実装であり、基本的に分散トランザクションを回避し、「結果整合性」を実現します。ただし、リレーショナルデータベースのスループットとパフォーマンスにはボトルネックがあり、頻繁な読み取りおよび書き込みメッセージはデータベースに圧力をかけます。したがって、実際の同時実行性の高いシナリオでは、このソリューションにもボトルネックと制限があります。

MQ(非トランザクションメッセージ)
一般に、非トランザクションメッセージでサポートされているMQ製品を使用する場合、ローカルトランザクションドメインでMQのビジネスオペレーションとオペレーションを管理することは困難です。より一般的な説明として、上記の「銀行間振込」を例にとると、控除完了後のMQ配信メッセージ操作の成功を保証することは困難です。このような一貫性を保証するのは難しいようです。
注意深い分析は完全に不可能ではありません。最初にメッセージプロデューサーの最後から分析します。疑似コードを参照してください。
非トランザクションメッセージ

上記のコードとコメントに基づいて、考えられる状況を分析しましょう
。1。データベースの操作が成功し、MQへのメッセージの配信も成功し、誰もが満足している
2.データベースの操作が失敗し、メッセージが配信されないMQに
成功しているが、MQにメッセージを届けることができなかった、例外が投げされているデータベースの3.操作だけで実行するデータベースを更新するための操作がロールバックされる
ビューの分析点以上のいくつかの例から、ルックス問題が大きくないように。次に、消費者が直面している問題を分析しましょう
。1。メッセージが一覧表示されたら、消費者に対応する業務を正常に実行する必要があります。サービスの実行が失敗した場合、メッセージを無効にしたり失ったりすることはできません。メッセージが業務と一致していることを確認する必要があります
。2。メッセージが繰り返し消費されないようにします。繰り返し消費
するため、一貫したメッセージングと業務運営を確保する方法の業績に影響を与えることができない場合、失われませんか?
主流のMQ製品はすべて、メッセージを永続化する機能を備えています。コンシューマーがダウンしているか、コンシューマーが失敗した場合、再試行メカニズムを実装できます(一部のMQは、再試行の回数をカスタマイズできます)。
メッセージの繰り返しの消費によって引き起こされる問題を回避するにはどうすればよいですか。
1.消費者がビジネスに電話をかけるためのサービスインターフェイスのべき等性を確認します
。2 簡単に判断できるように、消費ログまたは同様のステータステーブルを通じて消費ステータスを記録します(MQに依存するのではなく、自分でビジネスに実装することをお勧めします)。この機能を提供する製品)
。この方法はより一般的であり、パフォーマンスとスループットは、リレーショナルデータベースメッセージテーブルを使用するよりも優れています。MQ自体とそのビジネスの可用性が高い場合、理論的にはほとんどのビジネスシナリオに対応できます。ただし、十分なテストを行わずに直接商社で使用することはお勧めしません。

MQ(トランザクションメッセージ)
たとえば、ボブはスミスに送金します。最初にメッセージを送信するか、最初に控除を実行する必要がありますか?
問題があるようです。最初にメッセージを送信し、控除操作が失敗した場合、スミスのアカウントに余分な金額があります。逆に、最初に控除が実行されてからメッセージが送信された場合、控除は成功したがメッセージは送信されず、スミスはお金を受け取ることができない可能性があります。上記の例外のキャプチャとロールバックの方法に加えて、他のアイデアはありますか?
アリババのRocketMQミドルウェアを例として取り上げて、その設計と実装のアイデアを分析しましょう。
RocketMQが最初のステージでPreparedメッセージを送信すると、メッセージのアドレスを取得し、2番目のステージでローカル処理を実行し、3番目のステージで最初のステージで取得したアドレスを使用してメッセージにアクセスし、状態を変更します。注意深い読者は再び問題を見つけるかもしれません。確認メッセージが送信されない場合はどうなりますか?RocketMQは、メッセージクラスター内のトランザクションメッセージを定期的にスキャンします。準備済みメッセージが見つかると、ボブのお金が削減されたかどうかをメッセージ送信者に確認します。削減された場合、ロールバックする必要がありますか、それとも確認メッセージを送信し続ける必要がありますか?RocketMQは、送信者が設定した戦略に従って、確認メッセージの送信をロールバックするか続行するかを決定します。これにより、メッセージ送信とローカルトランザクションが同時に成功または失敗することが保証されます。以下に示すように:
RocketMQ

概要:著者の理解によると、ほとんどすべての有名なeコマースプラットフォームとインターネット企業は、「究極の一貫性」を実現するために同様の設計アイデアを採用しています。この方法は、幅広いビジネスシナリオに適しており、比較的信頼性があります。ただし、この方法の技術的な実現はより困難です。現在、主流のオープンソースMQ(ActiveMQ、RabbitMQ、Kafka)はトランザクションメッセージをサポートしていないため、二次開発または新しいホイールが必要です。残念ながら、RocketMQのトランザクションメッセージ部分のコードはオープンソースではないため、自分で実装する必要があります。Alipayトランザクションの学生が知っている
他の報酬
統合インターフェースは、通常、コールバックインターフェースとAlipay、復号化パラメーターをページングし、トランザクション関連のサービスコールシステムのステータスを更新します。注文は更新され、支払いが成功しました。同時に、Alipayは、コールバックページに「成功」​​という単語が出力された場合、またはビジネスが正常に処理されたことを示す対応するステータスコードが出力された場合にのみ、コールバックリクエストを停止します。それ以外の場合、Alipayは、正常なIDが出力されるまで、一定期間後に顧客へのコールバック要求を開始します。
実際、これは非常に典型的な補正の例であり、一部のMQ再試行補正メカニズムに似ています。
一般的に成熟したシステムでは、通常、高レベルのサービスとインターフェイスの全体的な可用性は非常に高くなります。一部のサービスが一時的なネットワーク障害または呼び出しタイムアウトが原因である場合、この再試行メカニズムは実際には非常に効果的です。
もちろん、より極端なシナリオを考えると、システム自体にバグがある場合、またはプログラムロジックに問題がある場合は、1W回再試行しても役に立ちません。「明らかに支払いは済んでいるが、支払いが済んでおらず、発送されない」という悲劇ではないでしょうか。
実際、取引システムの信頼性を高めるために、通常、トランザクションなどの高レベルのサービスコードに詳細なログレコードを追加します。システムで致命的な例外が発生すると、電子メール通知が送信されます。同時に、そのようなログをスキャンして分析し、この特別な状況をチェックし、プログラムを通じて補償を試み、関係者に電子メールで通知するための定期的なタスクがバックグラウンドで行われます。
特別な状況では、最後の障壁でもある「人工補償」があります。
概要
また、アピールしたいくつかのスキームのデザインのアイデア、長所、短所などをまとめました。読者はすでにある程度の理解を持っていると思います。実際、分散システムのトランザクションの一貫性はそれ自体が技術的な問題であり、すべてのシナリオに対処できる単純で完璧なソリューションはありません。具体的には、ユーザーは依然としてさまざまなビジネスシナリオに基づいて選択を行う必要があります。

古いドライバーの紹介
DingLongは、現在、テクニカルアーキテクトとして垂直ビジネスプラットフォームで働いています。同時実行性と可用性の高いアーキテクチャ設計に注意を払い、システムサービス、サブデータベースとテーブル、パフォーマンスチューニングなどについて、詳細な調査と豊富な実務経験を持っています。テクノロジーの研究と共有に情熱を注いでいます。

この記事はInfoQで最初に公開されました。無断転載を禁じます。転載しないでください。
住所:http //www.infoq.com/cn/articles/solution-of-distributed-system-transaction-consistency
記事を読んでもまだ満足できない場合は、QRコードをスキャンしてフォローし、質問してください。 。QRコード

おすすめ

転載: blog.csdn.net/dinglang_2009/article/details/51810151