彼女への送金で「分散トランザクション」について学んだ

彼女への送金で「分散トランザクション」について学んだ

2日前に給料をもらったのですが、最初に彼女にサプライズをあげようと思いました!そこで私は平安銀行アプリを開いて、彼女にいくらかのお金を送金しました!相手の招商銀行カードのカード番号と口座名義を記入し、ワンクリックで送金できました!終わり!

[[270009]]

画像はBaotu.comより

クリックした瞬間、アプリから口座変更通知が届き、図 1 に示すプロンプト インターフェイスが表示されました。「処理中です。他の銀行から結果が返されるのを待っています...」

良い!やはり銀行間送金なので数秒待つのは当たり前ですね!彼女が振込を受け取り、驚き感動する姿が目に浮かびました!

しかし、すべてが順調だったわけではありません。しばらくすると、図 2 に示すように、受取人の口座名が一致しないため送金が失敗したというメッセージがアプリに表示されました。

カードからお金が引き落とされたばかりですが、送金が失敗したと表示されます。銀行は私のお金を飲み込んでしまうのでしょうか?送金に失敗したお金は返金してもらえますか?

緊張して不安で落ち着かない気分になっていたところ、アプリの取り消しに関するメッセージが届きました。先ほど送金に失敗したお金が返金されました。心配しすぎだったようです...これは、私たちの平安銀行アプリが比較的安全で信頼できるものであることを証明しています!

私のカードからはすぐにお金が引き落とされるのに、相手側がお金を受け取るまでに数秒もかかるのはなぜですか?送金が失敗した後、差し引かれた金額は時間内にカードに返金されますか?お金が返ってこなかったらどうなるのでしょうか?

または、私が一度送金したのに、相手が 2 回の送金リクエストを受け取った場合はどうなりますか?これらの質問から、「取引」という言葉が頭に浮かびます。

私たちがまだ「幼児期」だった頃、先生はお金の送金の例を通して取引を説明することが多かったのですが、ここでのシーンとの違いは、先生がローカル取引について話していたのに対し、ここでは分散取引に直面しているということです。まずはローカルトランザクションを簡単に確認してみましょう。

地方問題

ローカル トランザクションについては、データベース エンジン レベルでサポートされているため、誰もがよく知っていることでしょう。そのため、データベース トランザクションとも呼ばれます。データベース トランザクションには、次の 4 つの主な特徴があります。

  • 原子性(A)
  • 一貫性
  • 隔離(I)
  • 持続性

これら 4 つの特性のうち、一貫性が最も基本的な特性であり、他の 3 つの特性は一貫性を確保するために存在すると思います。

私たちが学生だったときに先生が教えてくれた典型的な例に戻りましょう。アカウント A が 100 元をアカウント B に送金します (A と B は同じデータベース内にあります)。 A の口座からお金が引き落とされたのに、B の口座に入金されなかった場合、データの不整合が発生します。

データの一貫性を確保するために、データベース トランザクション メカニズムは、アカウント A からお金を差し引く操作とアカウント B にお金を入金する操作の 2 つの操作が同時に成功することを保証します。 1 つの操作が失敗した場合、複数の操作が同時にロールバックされます。

これはトランザクションのアトミック性です。トランザクション操作のアトミック性を保証するには、ログベースの REDO/UNDO メカニズムを実装する必要があります。

ただし、システムはマルチスレッド環境で実行されるため、アトミック性だけでは不十分です。複数のトランザクションが並行して実行される場合、各トランザクションのアトミック性が保証されていても、データの不整合が発生する可能性があります。

たとえば、口座 A の残高は元々 200 元です。口座 A が口座 B に 100 元を振り替えます。まず口座 A の残高が読み取られ、次にこの値から 100 元が差し引かれます。ただし、これら 2 つの操作の間に、口座 A は口座 C に 100 元を振り替えます。そのため、最終結果は A から 200 元を引いた金額になります。

しかし実際には、口座 A から口座 B への送金が最終的に完了した後、口座 A の損失は 100 元だけでした。口座 A から口座 C への送金で失われた 100 元が補填されたためです。

したがって、同時実行状況での一貫性を確保するために、分離が導入されます。つまり、複数のトランザクションが同時に実行された後の状態は、シリアルに実行された後の状態と同等になります。

分離には複数の分離レベルがあります。分離を実現するために (最終的には一貫性を確保するために)、データベースでは悲観的ロック、楽観的ロックなどが導入されています。

この記事のテーマは分散トランザクションなので、ローカルトランザクションについては簡単に説明します。覚えておくべきことの 1 つは、トランザクションはデータの一貫性を確保するためのものであるということです。

分散理論

卒業したばかりの年、意気込みたっぷりでインターネット企業に入社し、リーダーから最初に与えられた仕事がリスト内のデータを変更する機能を追加することだったことを今でも覚えています。

これは私を困惑させるでしょうか?数分で解決できますよ!リストに「編集」ボタンを追加するだけではないでしょうか?ボタンをクリックしてポップアップ ボックスを表示し、変更して保存します。

しかし、すべてが想像していたほどスムーズにはいきません。 [保存] をクリックしてリストを更新した後も、変更が成功しなかったかのように、ページのデータには変更前のコンテンツが表示されたままになります。しばらくしてから、リストを再度更新すると、データが正常に表示されます。

これは多くのテストの後に起こりました!こんなに大きな光景を見たことがなかったので、私はパニックになり始めました。私の文章に何か問題があったのでしょうか?結局、グループ内の経験豊富な先輩たちに助けを求めなければなりませんでした。

彼は深呼吸して私に言いました。「なんといっても、あなたは卒業したばかりの若者ですからね! 理由をお話ししましょう! 私たちのデータベースは読み取りと書き込みに分かれており、一部の読み取りデータベースと書き込みデータベースは異なるネットワークパーティションにあります。 あなたのデータは書き込みデータベースに更新され、データを読み取るときは読み取りデータベースから読み取ります。 書き込みデータベースに更新されたデータを読み取りデータベースに同期させるには一定の遅延があり、つまり読み取りデータベースと書き込みデータベースの間には短期的なデータの不整合が生じることになります!」 「これは悪い経験ではないでしょうか? 書き込まれたデータをすぐに読み取ることができないのはなぜでしょうか? では、この機能をどのように実装すればよいでしょうか?」

私の質問に直面して、同僚はイライラしながらこう言いました。「CAP 理論について聞いたことがありますか? まずは自分で学んでください!」そこで、私はこの馴染みのない言葉の背後にある秘密を理解するために、さまざまな資料を調べ始めました。

CAP理論はカリフォルニア大学のエリック・ブリューワー教授によって提唱されました。この理論によれば、分散システムは一貫性、可用性、分断耐性という 3 つの基本要件を同時に満たすことはできず、最大でもそのうちの 2 つしか満たすことができません。

一貫性: ここでの一貫性は、データの強力な一貫性 (線形一貫性とも呼ばれる) を指し、分散環境内の複数のコピー間でデータの一貫性を維持できるかどうかを指します。

つまり、あるデータに対して書き込み操作を実行した直後に読み取り操作を実行すると、書き込まれたばかりの値を読み取る必要があります。 (書き込み操作が完了した後に開始される読み取り操作は、その値、またはそれ以降の書き込み操作の結果を返す必要があります)

可用性: 障害のないノードが受信したすべての要求は、限られた時間内に結果で応答できる必要があります。 (システム内の障害のないノードが受信したすべてのリクエストは、応答を返す必要があります)

パーティション耐性: クラスター内のマシンが 2 つの部分に分割され、2 つの部分が相互に通信できない場合、システムは正常に動作し続けることができますか? (ネットワークは、あるノードから別のノードに送信されたメッセージを任意の数失うことが許されます)

分散システムでは、パーティション耐性が基本的な要件です。つまり、一貫性と可用性の間でトレードオフを行うことしかできません。

一貫性と可用性が同時に実現できないのはなぜでしょうか?前述のリストを変更する例に戻ると、データが異なるネットワーク パーティションに分散されるため、必然的にデータ同期に問題が発生し、同期にはネットワーク遅延、異常などの問題が発生するため、データの不整合が発生します。

データの一貫性を確保したい場合は、書き込みデータベースを操作するときに他の読み取り操作をロックする必要があります。

書き込みが成功し、データの同期が完了した後にのみ、読み取りと書き込みを再度解放することができ、ロック期間中はシステムは使用できなくなります。 CAP理論の詳細についてはこちらの記事が分かりやすく解説されているので参考にしてください!

分散トランザクション

分散トランザクションは、分散シナリオで満たす必要があるトランザクションです。前回の記事では、メッセージミドルウェアについて説明しました。この記事では、分散トランザクションについて説明します。これら 2 つを組み合わせることで、メッセージ ミドルウェアに基づく分散トランザクション ソリューションが実現します。

ローカルトランザクションであっても、分散トランザクションであっても、データの一貫性の問題を解決します。一貫性という言葉についてはこれまで何度も言及してきました。

ローカル トランザクションとは異なり、分散トランザクションでは、分散環境内の異なるデータベース テーブル内のデータの一貫性を確保する必要があります。

分散トランザクションには、XA プロトコル、TCC 3 フェーズ コミット、メッセージ キュー ベースなど、さまざまなソリューションがあります。この記事では、メッセージ キュー ベースのソリューションについてのみ説明します。

ローカル トランザクションでは一貫性について説明し、分散トランザクションでは必然的に一貫性の問題に直面します。冒頭の銀行間送金の例に戻ると、銀行 A のユーザーが銀行 B のユーザーに送金する場合、通常のプロセスは次のようになります。

  • 銀行Aは振込口座の確認と検証を行い、金額を差し引きます。
  • 銀行 A は銀行 B の転送インターフェースを同期的に呼び出します。
  • 銀行Bは振込先の口座を確認し、確認後、金額を増額します。
  • 銀行Bは処理結果を銀行Aに返します。

一貫性の要件が高くない通常の状況では、このような設計でニーズを満たすことができます。しかし、もし銀行のようなシステムがこのように導入されていたら、とっくの昔に破綻していただろう。

まず、この設計の主な問題を見てみましょう。

  • リモート インターフェイスへの同期呼び出しでは、インターフェイスの処理に時間がかかる場合、メイン スレッドが長時間ブロックされる可能性があります。
  • トラフィックを適切に制御できない場合、銀行 A のシステムのトラフィックのピークが銀行 B のシステムを圧倒する可能性があります (もちろん、銀行 B には独自のトラフィック制限メカニズムが必ずあります)。
  • 「ステップ 1」の実行直後に何らかの理由でシステムがクラッシュした場合、銀行 A の口座からお金が引き落とされますが、銀行 B はインターフェース呼び出しを受信できず、2 つのシステムのデータに不整合が生じます。
  • 「ステップ 3」を実行した後、何らかの理由で銀行 B がクラッシュし、要求に正しく応答できない場合 (実際には転送操作は銀行 B のシステムで実行され、保存されています)、銀行 A はインターフェイス応答を待機中に異常が発生し、転送が失敗したと誤って認識して「ステップ 1」操作をロールバックし、2 つのシステムのデータに不整合が発生します。

問題1と2は簡単に解決できます。メッセージ キューに精通している場合は、非同期処理やピークカット処理のためのメッセージ ミドルウェアの導入をすぐに思いつくはずです。

そこで私は計画を再設計しました。プロセスは次のようになります。

  • 銀行Aは口座を確認し、金額を差し引きます。
  • 銀行 B のリクエストは非同期的にキューに書き込まれ、メイン スレッドが返されます。
  • バックグラウンド プログラムを起動して、キューから処理するデータを取得します。
  • バックグラウンド プログラムは、銀行 B のインターフェイスに対してリモート呼び出しを実行します。
  • 銀行Bは振込先の口座を確認し、確認後、金額を増額します。
  • 処理が完了すると、銀行 B は銀行 A のインターフェースをコールバックして処理結果を通知します。

上の図から、メッセージ キューの導入後、システムの複雑さが瞬時に増加したことがわかります。最初の解決策のいくつかの欠点は補われましたが、さらに多くの問題ももたらしました。

例えば、メッセージキューシステム自体の可用性、メッセージキューの遅延などです。さらに、このような設計では、私たちが直面している根本的な問題、つまりデータの一貫性は解決されません。

①「ステップ1」実行直後に何らかの理由でシステムがクラッシュした場合、銀行Aの口座からお金が引き落とされますが、メッセージキューへの書き込みに失敗し、銀行Bのインターフェース呼び出しが行われず、データの不整合が発生します。

②「ステップ5」実行時に銀行Bが検証失敗により送金に失敗し、ロールバックを通知するために銀行Aのインターフェースをコールバックする際にネットワークが異常またはダウンしていた場合、銀行Aの送金はロールバックできず、データの不整合が発生します。

上記の問題に直面したため、システムを再度アップグレードする必要がありました。 「銀行口座から引き落とされたが、メッセージキューへの書き込みが失敗する」という問題を解決するには、転送ログテーブル、または転送フローテーブルを使用する必要があります。このテーブルのシンプルなデザインは次のとおりです。

このトランザクションテーブルをどのように使用しますか? 「ステップ 1」で金額を差し引くと、トランザクション テーブルに「保留中」のステータスで操作フローも書き込みます。

そして、これら 2 つの操作はアトミックである必要があります。つまり、これら 2 つの操作が同時に成功するか、同時に失敗することを保証するには、ローカル トランザクションを使用する必要があります。

これにより、振替控除が成功している限り、ステータスが「保留中」の振替取引が記録されるようになります。

このステップが失敗すると、転送は当然失敗し、後続の操作は行われません。このステップの後にシステムがクラッシュし、メッセージがメッセージ キューに正常に書き込まれなかったとしても (つまり、「ステップ 2」)、フロー データは保持されているため、問題はありません。

現時点では、補正用のバックグラウンド スレッドを追加し、転送フロー テーブルからステータスが「保留中」で最新の更新時刻が一定のしきい値を超えるデータを定期的に読み取り、補正用のメッセージ キューに戻すだけで済みます。

このようにして、メッセージが失われた場合でも補償メカニズムが存在することが保証されます。振替リクエストを処理した後、銀行 B は銀行 A のインターフェースをコールバックして振替のステータスを通知し、銀行 A の取引テーブルのステータス フィールドを更新します。これにより、以前のソリューションの 2 つの欠点が完全に解決されます。

システム設計図は次のとおりです。

これまでのところ、メッセージ損失の問題はうまく解決されており、銀行 A の送金操作が成功すれば、送金リクエストは確実に銀行 B に送信されるようになっています。

しかし、この解決策では問題が発生します。バックグラウンド スレッドをポーリングし、メッセージを処理のためにメッセージ キューに入れることによって、同じ転送要求がメッセージ キューに複数回入れられ、複数回消費される可能性があります。

このようにすると、銀行 B は同じ送金を複数回処理することになり、データの一貫性が失われます。では、銀行 B の送金インターフェースのべき等性をどのように確保するのでしょうか?

同様に、B 銀行システムに転送ログ テーブルまたは転送フロー テーブルを追加する必要があります。 B銀行は、振込依頼を受けるたびに、口座操作時に振込ログテーブルに振込ログレコードを挿入します。これら 2 つの操作もアトミックである必要があります。

転送要求を受信したら、まず固有の転送 ID に基づいてログ テーブルを確認し、転送が処理されたかどうかを判断します。そうでない場合は処理します。それ以外の場合は、折り返し直接お電話ください。

最終的なアーキテクチャ図は次のようになります。

したがって、ここでの核心は、銀行 A がローカル トランザクションを使用してログ記録とバックグラウンド スレッド ポーリングを実行し、メッセージが失われないようにすることです。

銀行 B は、ローカル トランザクションを使用してログ記録を確実にし、メッセージが繰り返し消費されないようにします。銀行Bは銀行Aのインターフェースをコールバックする際に処理結果を通知します。送金が失敗した場合、銀行Aは処理結果に基づいてロールバックします。

もちろん、分散トランザクションに対する最善の解決策は、分散トランザクションを可能な限り回避することです。

著者: 蘇静

紹介: 彼は、大規模なインターネット プロジェクトの開発において長年の経験があり、高同時実行性、分散性、マイクロサービス テクノロジーに関する詳細な研究と関連する実践経験を持っています。私は独学で、テクノロジーの研究と共有に熱心に取り組んでいます。私のモットー: 常に学ぶ心を持ち続けること!

<<:  QingCloud ハイブリッドクラウド

>>:  クラウド戦争が中盤に突入する中、勝利の要因は何になるでしょうか?

推薦する

「王宝宝」の新しいブランドマーケティング手法

2017年4月、ブラックアントキャピタルは王宝宝のシリーズB資金調達に約1億元の投資を主導しました。...

電子商取引ウェブサイトの外部リンク構築戦略とテクニック

電子商取引サイトの本質はオンラインで商品を販売することであるため、電子商取引サイトの外部リンクは一般...

マレーシア VPS: mondoze、月額 11 ドルから、マレーシアのトラフィック無制限 VPS、Linux および Windows オプションあり

マレーシアの商人であるmondozeは、公式発表によると2009年に設立されました。主にマレーシアの...

オンライン マーケティングのための最も正確な 5 つのトラフィック チャネルの分析!

トラフィックは、現在あらゆる分野の人が注目しているホットな話題です。トラフィックはデータと人気をもた...

インターネットマーケティング: ブランドに最適なマーケティングチャネルを選択する方法

少し前に、企業のオンライン マーケティングを行っていたときに、非常に興味深いことに遭遇しました。以前...

speedykvm-$7/kvm/1g メモリ/500g ハードディスク/2.5T トラフィック/G ポート/Windows

Incero Computer Room の Speedykvm がリリースされてから、ほぼ 1 か...

Pinduoduo やその他の企業はなぜこれほど急速に成長できたのでしょうか?

Pinduoduo や Toutiao などの新興モバイル インターネット企業が急速に成長しているの...

#おすすめ# hostwinds: リソースは「言葉では言い表せない」ほど豊富/値下げ/ウィンドウはたったの5ドル/Alipay

Hostwinds はひっそりと VPS 製品をアップグレードしました。現在、1G メモリの最低構成...

コンテナが攻撃されたときの対処方法: インシデント対応計画

翻訳者 |趙青棠校正:孫淑娟コンテナは、コード、構成ファイル、ライブラリ、システム ツールなど、あら...

有能な人がウェブサイトの運営方法を教え、思想的に自分自身を向上させる

ホームページ運営は非常に知的な仕事ですが、ホームページ企画はさらに知的な職業であり、知恵をフル活用し...

Henghost: 香港CN2 GIAラインVPSの簡単なレビュー、実際のテストデータからHenghostがいかに優れているかがわかる

henghost(恒創科技)は、香港、韓国、日本、米国でクラウドサーバーと独立サーバー事業を運営し、...

新しい D0 ステッピング Core i7-975 の消費電力とオーバークロック性能に関する予備調査

AMD は Phenom II X4 955 Black Edition を発売しようとしており、I...

サプライチェーンが不安定な時代に、Oracle Cloudテクノロジーが倉庫管理の変革に貢献

2020年のコロナウイルスのパンデミックは世界のサプライチェーンに深刻な課題をもたらし、その波及効果...

市場はさらに細分化され、中国のビデオクラウド市場規模は2022年後半に49.8億米ドルに達する見込み

IDCは4月24日、 「中国ビデオクラウド市場追跡、2022年下半期」レポートを発表し、中国のビデオ...

Baiduウェブマスタープラットフォームは、サイトの構文について「Kステーション」は存在しないという声明を発表しました。

ウェブマスターネットワーク(www.admin5.com)が8月28日に発表したところによると、Ba...