[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します

メッセージミドルウェアと言えば、インターネット上の子供用シューズは、無意識のうちに高い同時実行性、高性能のioスケジューリングなどを念頭に置く必要がありますが、アプリケーションの場合、特にトランザクションの場合、それは単なるパフォーマンス以上のものになる可能性があります。金融を扱うビジネスプラットフォーム向け。

さて、金融取引プラットフォームで紹介させてください。メッセージミドルウェアを使用する必要があるシナリオはどれですか。なぜそれを使うのですか?開発をより楽しくするためにミドルウェアプライベートクラウドを設計するにはどうすればよいですか?(学生ごとの言語スキルの違いを考慮して、ここでは設計の原則とメカニズムの内容のみを示します。この記事では、activemq、rabbitmq、kafka、metaqなどの市場で人気のあるオープンソース製品を取り上げます。)

メッセージミドルウェアの役割は、非同期同時実行のキャリアとして使用することです。それだけでなく、アーキテクチャ、高可用性、高同時実行、スケーラビリティ、信頼性、整合性、保証順序などの多くの機能を確保する必要があります。これらはすでにさまざまな設計者に頭痛の種を引き起こしています。また、消費が遅い、再現性がないなどの異常な要件もあります。設計のコストは非常に高いため、オープンソースの専門家を盲目的に信じないでください。多くのメカニズムでは、ほとんど再構築する必要があります。すべてのビジネスに対応する、ユーザーフレンドリーでユニバーサルなプライベートクラウドを構築するのはそれほど簡単ではありません。

支払いシステムが毎日数十億のビジネス注文を処理する必要がある場合、多くのシステムはミドルウェアのクラスタリング機能に依存し、エラーがないことを確認する必要があるため、メッセージミドルウェアの処理能力は少なくとも100億近くに達する必要があります。ミドルウェアがアーキテクチャのいくつかの側面からそれをどのように行うかを分析してみましょう。

高可用性

高可用性は永遠のトピックです。これは、金融業界で信頼できるかどうかの尺度でもあります。金融業界のアーキテクトは、データの一部であっても、データの損失を防ぐ方法を見つけることを知っておく必要がありますが、実際には、これは理論的には、それは性格に依存します。これはばかではありません。

たとえば、インターネットデータアーキテクチャでは、データの少なくとも3つのコピーが高保証と呼ばれますが、実際には、データセンターの0.000001%である8.13に雷が発生した後、Googleのベルギーのデータセンターは永久に失われました。0.05未満%ディスクを修復できませんでした。ここで言いたいのは、適切な時間と場所が非常に重要であるということです。極端な条件下で不可能なことは何もありません。アーキテクチャの脆弱性が存在する必要があります
。mqの高可用性の一般的な方法を見てみましょう。次の図はactivemqHAです。プログラム:
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します

ActivemqのHAは、マスター/スレーブフェイルオーバーによって管理されます。マスター/スレーブの切り替えは、さまざまな方法で切り替えることができます
。1:共有ロックはnfsまたは他の共有ディスクデバイスを介して実行され、マスターは共有ファイルロックの所有によってマークされます。 mが電話を切ると、対応するスレーブがshared_lockを占有し、マスターに変換します

2:
zookeeperによるクラスター管理の方が一般的です。次の図はここは紹介しません。metaqのHAスキームは
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します
上の図のようになります。まったく同じであり、zkによるブローカー管理のマスタースレーブノードでもあります。

もちろん、これはフェイルオーバーメカニズムの1つにすぎず、ブローカーがハングしたときにメッセージがスレーブに転送されることを保証することしかできませんが、中間プロセスでのメッセージの損失を保証することはできません。

メッセージがブローカーを通過する場合、ダウンタイムやその他のハードウェア障害が原因でメッセージが失われる可能性があります。現時点では、メッセージを保証するために関連する記憶媒体が必要です。

次に、Kafkaのストレージメカニズムを参照します。メッセージミドルウェアをストレージに依存させるには、高速であるだけでなく、IO要件のコストも非常に低い必要があることを知っておく必要があります。Kafkaは、上記の要件を満たすための一連のストレージメカニズムを設計しました。これは、ここでは簡単です。導入する。

まず、Kafkaのトピックは、分散展開で複数のパーティションに分割されます。パーティションは、メッセージのロードと複数のマシンによるルーティングに相当します。例:トピック、debit_account_msgは、debit_account_msg_0、debit_account_msg_1に分割されます。 、debit_account_msg_2。N個のパーティションを待機すると、各パーティションは/ debit_account_msg / topicなどのディレクトリをローカルに生成します。

内部のファイルは多くのセグメントに分割され、各セグメントは500mbのセグメントなどのサイズを定義し、ファイルは2つの部分に分割されます:インデックスとログ
00000000000000000.index
00000000000000000.log
00000000000065535.index
00000000000065535.log
ここで、番号はmsgIdの値を表しますインデックスの開始点である対応するデータ構造は次のとおりです
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します
。1,0はmsgIdが1のメッセージを表し、0はこのファイルのオフセットを表します。このファイルを読み取った後、対応するセグメントログファイルを見つけて読み取ります。対応するメッセージ情報、対応する情報は固定形式のメッセージ本文です。
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します
明らかに、このメカニズムの単純なアプリケーションでは、高い同時IOを満たすには十分ではありません。最初に、セグメントファイルバイナリを検索し、次にオフセットを介して対応するデータを見つけ、次にmsgsizeを読み取ります。新聞の本文を読むには、少なくとも4ディスクio回必要であり、これは高価ですが、引っ張るときに順次読み取りが使用されるため、基本的にほとんど効果がありません。

上記のクエリに加えて。実際、ディスクに書き込む前に、すべての読み取りと書き込みがosのページキャッシュで実行され、その後、非同期スレッドを介してハードディスクが定期的にフラッシュされます(LRU戦略)が、実際には、osがダウンすると、このリスクが非常に大きくなります。特に消費が遅く、データのバックログが多い場合のデータ損失ですが、Kafkaの兄弟metaqはこの領域で多くの変換を行い、レプリケーションメカニズム(Aliが使用)はこれらのパーティションファイルで実行されるため、このレベルではどんなに稲妻が当たっても、メッセージを失う可能性は低くなります。もちろん、ホストルームの光ケーブルを掘ったときに何が起こるかを除外するものではありません。

とにかく完璧で綺麗なようですが、実は運営・維持管理費が高額なようです。これらはすべてファイルであるため、問題が発生すると、手動で処理するのは非常に面倒であり、1台のマシン上にあるため、一部の操作および保守仕様とapi呼び出し機能を作成するには比較的大きな操作および保守コストが必要です。

したがって、この領域では、mongoDBなどの一部のnosqlにデータを格納できます。もちろん、mysqlも可能ですが、強力なトランザクション処理メカニズムがない限り、io機能とnosqldbは同じレベルではありません。 Liはこの要件に非常に厳しいです。たとえば、metaqはAlipayの背後で使用されます。これは、以前のミドルウェアtbnotifyは、消費が遅い場合に非常に受動的であり、metaqはこの領域で大きな利点があるため、後で分解を聞いてください。

高い同時実行性

当初、ほとんどのエンジニアはmqを使用してパフォーマンスと非同期の問題を解決していましたが、実際、同じ点で、ioスケジューリングはそれほどリソースを消費しません。mqの高い部分をいくつか見てみましょう。並行性、最初にいくつかの有名なミドルウェアの背景を紹介します。

Activemqは、当時のエンタープライズレベルの特殊なソリューションであり、jeeのjms仕様に準拠していました。実際、パフォーマンスは良好でしたが、インターネットに接続されたときにスイカを持ったウサギでした。

Rabbitmqはerlang言語で記述されており、AMQPプロトコル仕様に準拠しており、クロスプラットフォームの性質を備えています。モード転送モードは、より豊富で分散型である必要があります。

Rocketmq(metaq3.0の最新バージョンであるkafkaはmetaqの前身でもあり、元々はlinkedInによってオープンソース化されたログメッセージシステムです)、metaqは基本的にkafkaの原理とメカニズムをjavaで記述します。多くの変更を加えた後、トランザクションをサポートします。開発速度は非常に速く、アリと中国にはこのメンテナンスを行うのに非常に優れたコミュニティがあります。

パフォーマンスの比較。参考のために、インターネットからのデータをいくつか示します。
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します

正直なところ、これらのデータレベルに関しては、違いはそれほど法外ではありませんが、いくつかの共通点を分析できます。これらの主なパフォーマンスの違いはどこにありますか?
Rocketmqはmetaqの後継です。いくつかの新しい機能とメカニズムの改善を除いて、パフォーマンスの原則は似ています。これらの高性能のハイライトは次のとおりです。

  • rocketmqの消費は主にプルメカニズムを使用するため、ブローカーの場合、多くの消費機能をブローカーに実装する必要はありません。関連するデータをコンシューマーからプルするだけで済みます。activemqやrabbitmqと同様に、すべて古いものを使用します。もちろん、ブローカーにメッセージをディスパッチさせる方法、jmsまたはamqpの標準的な配信方法のいくつか

  • ファイルストレージは順番に保存されるため、メッセージをプルするときはセグメントデータを呼び出すだけで済み、消費者は消費を行うときに情報を最大限に消費し、バックログを生成する可能性は低く、ioを設定できます。 noopモードなどのスケジューリングアルゴリズムは、一部の順次読み取りのパフォーマンスを向上させることができます。

  • pagecacheを使用してosキャッシュ内のデータをヒットし、ホットな消費に到達します

  • MetaqのバッチディスクIOとネットワークIOは、データを1つのioで実行しようとします。メッセージはすべてバッチであるため、ioのスケジューリングで多くのリソースを消費する必要はありません。

  • 次の図に示すように、NIO送信は、元のmetaqのアーキテクチャです。当初、metaqは、geckoおよびTaobao内のnotify-remotingと統合されたいくつかの高性能NIOフレームワークを使用して、メッセージを配信していました。
    [システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します
  • 消費キューが軽量であるため、メッセージ機能がキューを介して取得されることを知っておく必要があります

次の図を見てください
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します
。Metaqは、消費のために物理キューに論理キューを追加します。キューに対応するディスクデータはシリアル化されます。キューの追加は、ディスクiowaitの負担を追加しません。書き込みはシーケンシャルにすることができますが、読み取り時それでもランダム読み取り、最初の論理キュー、次にディスクの読み取りを使用する必要があるため、ページキャッシュは非常に重要です。メモリを大きくしてみてください。この割り当ては完全に利用されます。

実際、上記を達成することで、基本的にパフォーマンスを比較的高いレベルに保つことができますが、パフォーマンスが最も重要でない場合もあります。最も重要なことは、他のアーキテクチャ機能との最適なバランスをとることです。他のメカニズムが満たされなければなりません。基本的に、業界で最も難しい3つの問題、つまり、高い同時実行性、高い可用性、および一貫性が互いに競合するためです。

スケーラブル

これは昔ながらの質問です。一般的なシステムやミドルウェアの場合は、より適切に拡張できますが、メッセージミドルウェアの分野では、常に厄介な問題でした。なぜですか。

activemqの拡張にはビジネスの性質が必要なため、activemqの拡張の制限について説明します。ブローカーとして、最初に送信元と宛先を知る必要がありますが、これらのメッセージが分散送信である場合、複雑になります。activemqを見てみましょう。負荷の操作方法。
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します
プロデューサーがtopicAメッセージを送信すると想定します。通常の状況ですべてのコンシューマーが各ブローカーに接続している場合、何がホットですか?ブローカーにプロデューサーからのメッセージがある場合は、対応するに転送できます。消費者について。
しかし、broker2に対応するメッセージ送信者が接続されていない場合、この場合はどうすればよいでしょうか。同じトピックのアプリケーションシステム(プロデューサー)と依存システム(コンシューマー)には多くのノードがあるので、容量を拡張するにはどうすればよいですか?Activemqは上の図の通常の部分を実行できますが、プロデューサー、ブローカー、およびコンシューマーの対応する構成を変更するのは非常に面倒です。
もちろん、activemqはマルチキャストを介して動的検索を実行することもできます(ロードにlvsまたはf5を使用することについても言及している人もいますが、消費者にとって大きな問題があり、このロード構成はトピックの配布に実質的な影響を与えません)ただし、まだ問題があります。トピックが大きすぎる場合は、各ブローカーがすべてのプロデューサーまたはコンシューマーに接続する必要があります。そうしないと、前述の状況が発生します。Activemqの拡張は非常に面倒です。

metaqがこれを行う方法について説明しましょう。図を見てください
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します
。Metaqはトピックをパーティションとして使用します。このレベルでは、トピックパーティションの数を構成するだけでよいため、パーティションは1つだけになります。 「ビジネス」の概念はルーティングルールとして使用されます。通常、ブローカーマシンでは複数のトピックが構成され、各トピックには通常、マシン上に1つのパーティションしかありません。マシンが十分でない場合は、複数のパーティションをサポートすることもできます。送信ゾーンのパラメータを取得するだけで、ビジネスIDの係数を取得してパーティションをカスタマイズできます。
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します
metaqのコンシューマーは、グループロード方式(このグループは通常、パーティションの機能に従って構成されます)を使用して、パーティションからメッセージをプルします。コンシューマーが多い場合は、コンシューマーに参加する必要はありません。結局のところ、アプリケーションサーバーはメッセージサーバーよりもはるかに大きいため、これは一般的にオンラインの場合です。
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します
また、下図のようにパーティションが多すぎる場合
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します
、負荷がコアメッセージに大きく依存している場合でも、サーバーブローカーの要件は比較的高いです。結局のところ、依存度は比較的大きいです。また、メッセージにブロードキャスト特性がある場合は、大きいため、ブローカーの場合、ページキャッシュにはhigh-ioハードディスクと大容量メモリが必要であり、実際に必要な計算は大きすぎる必要はありません。
[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します

信頼性

信頼性はメッセージミドルウェアの重要な機能です。mqがこれらのメッセージを転送する方法を見てみましょう。最初にactivemqを参照してください。これは、プッシュ&プッシュメカニズムに基づいています。

送信されたすべてのメッセージが確実に消費されるようにするにはどうすればよいですか?Activemqプロデューサーがメッセージを送信した後、受信を確認するためにブローカーからackを受信する必要があります。同じ保証がブローカーからコンシューマーにも当てはまります。

Metaqのメカニズムは同じですが、ブローカーはプル方式でコンシューマーに到達するため、その到着保証はコンシューマーの能力に依存しますが、一般に、アプリケーションサーバークラスターが雪崩効果をもたらす可能性は低いです。

メッセージの同一性を確保する方法は?現在、基本的にActivemqもMetaqもメッセージの同一性を保証することはできず、保証するためにいくつかのビジネスが必要です。ブローカーがタイムアウトすると再試行します。再試行すると、新しいメッセージが生成されます。ブローカーがすでにメッセージを送信している可能性があります。この場合、同じビジネストランザクションで2つのメッセージが生成されることを保証することはできません。

メッセージの信頼性を確保する方法は?この時点で、activemqとmetaqのメカニズムは基本的に同じです。
プロデューサー保証:データを生成した後、ブローカーに到達した後、ソース
ブローカーにACKを返す前に永続化する必要があります。保証:メッセージを受信した後、metaqサーバーはメッセージを定期的にハードディスクに更新し、次にデータを更新します。ダウンタイム後に消費に影響が及ばないように、すべてが同期/非同期を介してスレーブに複製されます
。Activemqは、ローカルリカバリ用にデータベースまたはファイルを介してローカルに保存されます。

消費者保証:メッセージの消費者はメッセージを次々に消費し、1つのメッセージを正常に消費した後にのみ次のメッセージを消費します。メッセージの消費に失敗した場合(例外など)、メッセージの消費を再試行します(デフォルトの最大回数は5回です)。それでも最大回数を消費できない場合、メッセージはコンシューマーのローカルディスクとバックグラウンドスレッドに保存されます。もう一度やり直してください。メインスレッドは戻り続け、後続のメッセージを消費します。したがって、MessageListenerがメッセージが正常に消費されたことを確認した後でのみ、メタコンシューマーは別のメッセージを消費し続けます。これにより、メッセージを確実に消費できます。

一貫性

mqの一貫性について、2つのシナリオについて説明します
。1:メッセージが複数回送信/消費されないようにするため

2:トランザクションを
保証します。上記の一部のmqは、一貫性を保証できません。なぜ保証しないのですか?コストは比較的高く、ソースコードを変更することで保証できるとしか言えず、スキームも比較的複雑ではありませんが、追加のキャッシュクラスタで一定期間確保するなど、追加のオーバーヘッドは比較的大きくなります。再現性、私は後でこの関数でいくつかのmqがあるはずだと思います。

Activemqは2種類のトランザクションをサポートします。1つはJMSトランザクションで、もう1つはXA分散トランザクションです。トランザクションを取得すると、対話時にtransactionIdがブローカーに生成されます。ブローカーはトランザクション処理を割り当てるためにいくつかのTMを実装します。MetaqはローカルトランザクションとXA、JTA標準に準拠。activemqとmetaqのトランザクション保証はすべて、基本的に同じREDOログ方式で実行されます。

ここでの分散トランザクションは、ブローカーフェーズ後にのみ保証されます。準備されたメッセージは、ブローカーがコミットする前にローカルファイルに格納され、メッセージはコミットフェーズでキューに書き込まれ、最後に2フェーズコミットがTMを介して実現されます。

概要

たとえば、同社には非常に優れたパフォーマンスを備えたメッセージミドルウェアもいくつかあります。将来的には、オープンソースでより多くの人々が使用できるようになることを願っています。一部の一般的なメッセージングミドルウェアでは、さまざまなアプリケーション、さまざまなコスト、さまざまな開発に合わせてさまざまなアーキテクチャをカスタマイズできます。もちろん、これらのアーキテクチャはさまざまな方法で検討する必要があります。

推奨読書:

注意深く整理された| 2017年後半の記事カタログ
。キャッシュとデータベース間の強力な一貫性のための実行可能なソリューション。
ユーザープロセスバッファーとカーネルバッファー
は、金鉱の物語を通して動的プログラミングを導入します(パート1)

サーバーのバックグラウンドテクノロジースタックの知識の概要の共有に焦点を当てる

コミュニケーションと共通の進歩に注意を払うことを歓迎します

[システムアーキテクチャ]オープンソースメッセージングミドルウェアのアーキテクチャと原則について話します

コーディング

コードファーマーには、テクノロジーを簡単にするためのわかりやすい技術記事を提供する正しい方法があります。

おすすめ

転載: blog.51cto.com/15006953/2552096