自己を見つめる質問:繰り返し消費、注文消費、分散取引

自己を見つめる質問:繰り返し消費、注文消費、分散取引

[[429685]]

こんにちは、みんな

私はあなたの学習と成長のパートナーですキャプテン

RocketMQの学習を続けましょう。前回の記事では、ブロードキャスト メッセージ、遅延メッセージ、バッチ メッセージ、フィルター処理されたメッセージについて学習しました。この記事では、開発においてスムーズに進められるよう、RocketMQ の奇妙な機能について引き続き学習します。

この記事では、メッセージ キューにおける 2 つの一般的な問題 (繰り返し消費と順次消費) と、メッセージ キューでの分散トランザクションの特性を完了できるトランザクション メッセージについて説明します。

これらの技術的なポイントに関する以前の記事をここに投稿しました。まずは読んでみてください。


  • RocketMQとは何かを理解する
  • RocketMQ プロデューサーにこれほど多くの用途があることをなぜ知らなかったのでしょうか? (写真は最後に載せておきます、ごめんなさい)
  • 面接官は私に尋ねました。「分散トランザクションとは何ですか?」

これらは面接で必ず言及しなければならない技術的なポイントです。面接官が忘れていない限り、これらの問題に関連するテクノロジー スタックについて質問される可能性が高くなります。次に、あなたの技術的なスキルと深さを実証する時が来ます。

01 繰り返し消費の問題

問題は始まる

メッセージ キューの繰り返し消費の問題についてお話ししましょう。

この問題は避けられないものであり、コンシューマー キューを使用する際に誰もが考慮しなければならない問題の 1 つでもあります。いずれにせよ、メッセージ キューを使用するときは常にこの問題を最初に考慮します。この問題を考慮しないと、ビジネスで許容できない問題が発生する可能性があるためです。

繰り返し消費されるため、誰もがその意味を理解しなければならない。つまり、同じメッセージが複数回消費される。

なぜこの問題が存在するはずだと言うのでしょうか?メッセージ キューには再試行メカニズム、つまりメッセージの再送信が必須であるためです。コンシューマー側で例外が発生すると、メッセージ キューはメッセージを再送信します。

メッセージを再送信して再処理することは問題ありませんが、通常、メッセージには複数のリスナーがあり、つまり、複数のシステムがメッセージをリッスンして処理している可能性があります。他のシステムが繰り返しの消費をサポートしていないとしたら、それはひどいことではないでしょうか?

他のシステムのデータが混乱し、システム間のデータに不整合が生じます。

たとえば、電子商取引システムでは、支払いが成功すると支払い成功メッセージが送信されます。ポイント システムと物流システムがこのメッセージを監視します。ポイントシステム処理で例外が発生した場合、支払い成功メッセージが再送信されます。物流システムがメッセージの再試行をサポートしていない場合、2 つの物流注文が表示され、顧客が 1 つの製品を購入して 1 つの製品に対して支払いを行う可能性があります。その結果、製品の複数のコピーがユーザーに送信されます。





​​​

ああこれ…

それはひどいことじゃないですか?荷物をまとめたほうがいいかもしれません。

実際、メッセージの再試行は非常に一般的な状況であり、ネットワーク ジッター、システム業務処理のバグなど、メッセージ キューを使用するときに誰もが考慮しなければならないことでもあります。この問題に対処しないと、システムに無限のトラブルが発生します。

繰り返し消費するというこの問題をどうやって回避すればいいのでしょうか?

解決策: 冪等性




​​​

簡単に言えば、べき等性は数学的な概念です。一般的な説明では、同じパラメータを使用して同じインターフェースを複数回呼び出し、呼び出しの結果は同じになるということです。つまり、支払い成功メッセージを何度送信しても、最終的に生成される物流データは同じです。

それはいいです。

では、どのようにしてべき等性を保証するのでしょうか?

私は通常、この種の質問に 2 つのシナリオで答えます。1 つはプロダクション側のべき等性、もう 1 つはコンシューマー側のべき等性です。

プロデューサー側のべき等性は、通常、Redis などのサードパーティのストレージやフロー テーブルによって実現されます。メッセージが送信されると、記録は一時的に保存されます。次のメッセージを送信する前に、Redis でメッセージが送信されたかどうかを確認します。ただし、多くのシナリオではこれは適切ではありません。これにより、プロデューサー側の再試行メカニズムが制限されます。

プロデューサーがメッセージを正常に送信したが、コンシューマーが失敗した場合、メッセージは再送信されません。

消費者側における別のタイプのべき等性が最も一般的です。プロデューサーが同じメッセージを何度送信しても、最終的な実行結果は同じになります。強いべき等性と弱いべき等性に分けられます。

強いべき等性は、べき等性が要求され、エラーが許されないビジネス シナリオで実際に使用されます。これはより慎重です。たとえば、上記の支払い成功のメッセージは、強いべき等性を持つ物流コンシューマーによって処理される必要があります。

ここでは、キャッシュフローテーブルや Redis などのサードパーティのストレージを導入できます。支払いが成功すると、キャッシュフロー表に記録されます。ここで Redis を使用すると損失が発生する可能性があります。支払いの成功とキャッシュフロー テーブルのレコードを同じトランザクションに配置して、両方が同時に成功または失敗するようにします。

メッセージが届くたびに、注文番号に応じてトランザクション テーブルをチェックして、このトランザクションがあるかどうかを確認します。取引がある場合はそのまま返品してください。

データベースの一意制約を使用して直接挿入操作を実行することもできます。

弱い冪等性もあり、これは 100% のケースで冪等性を保証できるわけではありません。たとえば、Redis を使用してビジネス ID を一意のキーとして保存する場合、Redis のダウンタイムによって SMS 送信が失われる可能性がありますが、これは大きな問題ではなく、ユーザーはそれを許容できます。サンプルコードを見てみましょう


 文字列 idempotentValue = RedisUtil.get(RedisConstant.IDEMPOTENT.concat(msgId), String.class); if (!StringUtils.isEmpty(idempotentValue)) { log.info("========メッセージは消費されました: [{}]", msgBody); ConsumeConcurrentlyStatus.CONSUME_SUCCESS を返します。 } //ビジネス コード //べき等処理 RedisUtil.setEx(RedisConstant.IDEMPOTENT.concat(msgId), "1", 5, TimeUnit.DAYS);

02 連続消費

それでは、連続消費のシナリオに遭遇したことがあるかどうか教えてください。

順次消費シナリオは特に一般的ではありませんが、一部のビジネス シナリオでは順序が非常に重要であり、メッセージの消費順序を確保することも非常に重要であるため、不可欠です。

たとえば、データの削除、追加、変更を必要とする操作があるとします。一般的なシステムでは、この操作を実行するために SQL を使用します。ただし、データ量が多い場合、データのバックアップと同期を行うと、メッセージ キューを介して同期が遅くなることがあります。このとき、メッセージの順序を確保することが非常に重要です。上記の 3 つの操作が変更、削除、追加の順序になった場合、望む効果にはなりません。

通常のメッセージを消費するための固定の順序はありません。デフォルトでは、メッセージはラウンドロビン方式で異なるパーティションに送信されます。




​​​

コンシューマー側で消費する場合は、複数のパーティションに割り当てられます。複数のパーティションが同時にプルされ、消費のために送信されます。同じパーティション キューでは、FIFO は保証されますが、通常のメッセージを順番に消費することはできません。メッセージを同じキューに配信するだけで済みます。




​​​

前述のように、順序どおりに保つ必要があるメッセージが同じキューに配信されるようにするだけで、同じキュー内のメッセージは確実に同じコンシューマー インスタンスに配信され、同じコンシューマー インスタンスは確実にメッセージを順番にプルし、順番に消費するようになります。

並べ替えがトリガーされ、キューが別のコンシューマーに割り当てられても、問題にはなりません。キュー内のメッセージは常に FIFO であるため、メッセージの繰り返し消費の冪等性を確保するだけでよく、キューの内部順序は問題ありません。

順次消費はグローバル順序とパーティション順序を割り当てます


  • グローバル順序: 指定されたトピックの場合、すべてのメッセージは厳密な先入れ先出し (FIFO) 順序で公開および消費されます。
  • パーティション順序: 指定されたトピックの場合、すべてのメッセージはシャーディング キーに基づいてブロックにパーティション分割されます。同じパーティション内のメッセージは、厳密な FIFO 順序で公開および消費されます。シャーディング キーは、連続したメッセージ内の異なるパーティションを区別するために使用されるキー フィールドであり、通常のメッセージのキーとはまったく異なる概念です。

グローバルシーケンシャルメッセージ消費パフォーマンスが平均的であるのはなぜですか?

グローバル シーケンシャル メッセージは FIFO メッセージ ブロッキング原則に厳密に従います。つまり、前のメッセージが正常に消費されない場合、次のメッセージはトピック キューに格納されます。グローバル シーケンシャル メッセージの TPS を向上させるには、インスタンス構成をアップグレードし、同時に、メッセージ クライアント アプリケーションでローカル ビジネス ロジックの処理に費やす時間を最小限に抑える必要があります。

RocketMQ では、1 つのトピックの下に複数のキューが存在します。したがって、メッセージの順序を保証するために、メッセージは同じキューに送信されます。 RocketMQ は、次の 3 つの実装を備えた MessageQueueSelector キュー選択メカニズムを提供します。




​​​

ハッシュ係数方式を使用して、順番に使用する必要のあるメッセージを同じキューに送信し、同期送信を使用します。もちろん、この係数はこれらのメッセージの共通属性に基づいています。

RocketMQ は送信順序のみを保証します。最終的な消費順序については、消費者ビジネスが確保することになります。つまり、私があなたに送信したメッセージが順序どおりであることは保証しますが、あなたが自分で順序を間違えた場合は、それは RocketMQ の問題ではなく、あなた自身のコードの問題です。

実際、マスタークラッシュなど、書き込みキューの数の変化を引き起こす異常なシナリオがまだいくつかあります。上記のハッシュ係数を使用すると、メッセージが他のキューに分散されるため、順序が保証されず、マスターを選択しない限り、クラッシュすると次のメッセージを送信できません。

03 分散トランザクション

分散トランザクションについて話しましょう

この面接官が私にこう質問しているのを見てみましょう。「分散トランザクションとは何ですか?」

簡単に言えば、トランザクションは完全に正常に実行されるか、完全に実行されるかのどちらかです。分散トランザクションは、マシン間、サービス間、およびシステム間のトランザクション保証です。現在のシステムは多くのサービスに分割されており、各サービスは少なくとも 2 回デプロイされ、異なるマシンにデプロイされます。

このようにして、システム間のトランザクションは分散トランザクションであることが保証されます。

RocketMQのトランザクションメッセージは、分散トランザクションを自然にサポートします。

トランザクションメッセージ: 最終的な一貫性を実現するために、X または Open XA に類似した分散トランザクション機能を実装します。

RocketMQ バージョンのメッセージ キューは、X または Open XA に類似した分散トランザクション機能を提供します。 RocketMQ バージョンのメッセージ キューのトランザクション メッセージを通じて、分散トランザクションの最終的な一貫性を実現できます。

セミトランザクション メッセージ:一時的に配信できないメッセージ。送信者はメッセージをメッセージ キュー RocketMQ サーバーに正常に送信しましたが、サーバーはプロデューサーからのメッセージの 2 次確認を受信して​​いません。この時点で、メッセージは「一時的に配信できません」と表示されます。この状態のメッセージはセミトランザクション メッセージです。

メッセージの再確認:ネットワークの中断、プロデューサー アプリケーションの再起動などの理由により、トランザクション メッセージの二次確認が失われます。 RocketMQ バージョンのメッセージ キュー サーバーは、スキャンによってメッセージが「セミトランザクション メッセージ」に長時間含まれていることを検出すると、メッセージの最終ステータス (コミットまたはロールバック) についてメッセージ プロデューサーに積極的に問い合わせる必要があります。この問い合わせプロセスはメッセージの再確認です。




​​​

キャプテンに従って、トランザクション メッセージを送信する手順を確認しましょう。

1. 送信者は、セミトランザクション メッセージをサーバー ブローカーに送信します。サーバーはメッセージを保持し、メッセージが正常に送信されたことを確認するために ACK を返します。この時点で、メッセージはセミトランザクション メッセージです。

2. 送信者はローカルトランザクションのロジックの実行を開始する

3. 送信者は、ローカル トランザクションの実行結果に基づいて 2 番目の確認をサーバーに送信し、コミットするかロールバックするかを決定します。コミットを受信すると、サーバーはメッセージを配信可能としてマークし、コンシューマーに送信します。ロールバックを受信すると、サーバーはセミトランザクション メッセージを削除します。サーバーはそれを送信せず、消費者はそれを受信しません。

しかし、ネットワークが切断されたり、アプリケーションが再起動されたりすると、上記の手順の二次確認情報がサーバーに届かなくなります。どうすればいいでしょうか?

実際にはここにはチェックバック メカニズムが存在します。送信者がメッセージを送信した後、トランザクションをローカルで実行する必要があります。トランザクション実行プロセスが停止した場合、またはネットワークの問題によりトランザクション実行結果をサーバーに送信できない場合、サーバーはチェックバック メカニズムを実行して、セミトランザクション メッセージの最終送信を確認します。

この記事はWeChatのパブリックアカウント「Java Pirate Ship」から転載したものです。

​​​


<<:  さまざまなエッジ クラスタ管理ソリューションの比較と選択

>>:  Kafka の代替となる KubeMQ

推薦する

大学入試の「クラウド得点チェック」を開始しました。その背後にあるブラックテクノロジーとは何でしょうか?

7月23日、全国各省の大学入試成績が相次いで発表された。このうち湖北省、甘粛省、雲南省、広西チワン族...

モノのインターネットにおけるクラウドコンピューティングの応用の分析

モノのインターネットは、インターネットの発展から生まれたネットワーク概念です。モノのインターネット技...

Webmaster Network からの毎日のレポート: 垂直型電子商取引は苦境に陥り、ブラウザ市場は変化している

1. STOエクスプレスとJD.comの「決裂」:JD.comのスペアパーツ倉庫物流入札が原因1社は...

アリババは、次世代のインターネットカーを定義する5つの大きな進化を遂げたAliOS 2.0システムをリリースしました。

想像してみてください。車のドアを開けると、車があなたの身元を認識し、シート、バックミラー、エアコンの...

Baidu Index Tool のアップグレードが正式に開始され、新しいカスタムクエリ機能が追加

A5ウェブマスターネットワークは11月26日に次のように報告した。「一定期間の内部テストを経て、Ba...

杭州警察、恐喝容疑で悪質な悪質レビュー投稿者7人を逮捕

北京ニュース(劉霞記者)昨日午前、淘宝網と杭州市公安局は共同で記者会見を開き、国内初の「悪質な悪質レ...

医療SEOと一般産業SEOの違い

著者は医療分野の SEO に携わるようになってまだ 1 年ちょっとですが、それ以前は一般産業の SE...

A局は倒産寸前、B局はアメリカで株式公開中。同じ二次元世界なのに、なぜこんなにも差があるのか​​?

諺にあるように、三日月が九つの州を照らし、喜ぶ人もいれば悲しむ人もいます。どちらも二次元の世界ですが...

国内主要7データベースを比較すると、セコイア分散データベースはアリババやファーウェイよりも早く商用化されました!

過去 30 年間、国内のデータベースは常に海外のデータベースに追随してきました。 Oracle、My...

ビッグデータに関する誤解: 統計 ≠ ビッグデータ

ビッグデータに関する誤解: データ統計はすでに起こったことに関するものですが、ビッグデータは多くの場...

2023 年に注目すべき 3 つのデータ インフラストラクチャ トレンド

データ インフラストラクチャは、IT 環境において中心的な位置を占めるようになっています。データ ウ...

SEO はそれほど難しいことではないということをお伝えしておきます。

SEO 業界で働き始めてから、最初は本当に混乱しました。フォーラムの方法に従って継続的に学習し、今で...

box.comは50Gの無料ストレージを永久に提供、1ファイルあたり250M

box.com/net は 2005 年に設立されたストレージ サービス プロバイダーです。現在 1...

ブラックテクノロジーの解明:眼科医は5G+8Kをどのように活用して遠隔診療を行っているのか?

秋にアップルが発表した新製品では、iPhone にこれまでで最高のディスプレイが搭載されました。 S...