DUICUO

この記事は、オープンソースのメッセージ ミドルウェアの選択に役立ちます。

[[285486]]

最新のオープンソース メッセージ ミドルウェアの比較:

  • NATS
  • ラビットMQ
  • アパッチカフカ、
  • シナプス、
  • NSQ
  • パルサー

#NATS:

https://nats.io/

元々Rubyで構築されたNatsStreamingServer(https://github.com/nats-io/nats-streaming-serverNATS)は、1秒あたり15万件のメッセージを処理できました。チームはこれをGo言語で書き直し、今では魔法のように1秒あたり800万~1100万件のメッセージを送信できるようになりました。パブリッシュ・サブスクライブエンジンとして使用できるだけでなく、包括的なキューイングにも使用できます。

利点: スローガン: 常に利用可能、シンプルなダイヤル トーン、CPU 消費量の少ない設計、高速: 高速通信バス、高可用性、高スケーラビリティ、軽量: サイズが非常に小さい、わずか 3 MB の Docker イメージ!

デメリット:忘れやすさ、持続性の欠如:NATSは永続的なメッセージングを実行しません。オフラインの場合はメッセージを受信できません。トランザクション、拡張配信方法、エンタープライズキューイングはサポートされません。

一般的に、NATSとRedisは、レイテンシが通常1ミリ秒未満で49に達するような小さなメッセージ(1MBをはるかに下回る)に適しています。NATSはHTTPではなく、RPCに似た非常にシンプルなテキストベースの独自のプロトコルです。そのため、メールエンベロープにヘッダーは追加されません。

NATSは、完全な複製、シャーディング、サブスクライブを行うわけではありません。NATSでは、キューをノードごとに効率的にシャーディングできます。ノードが停止した場合、そのノードのメッセージは失われます。アクティブなノードへの受信メッセージは、接続されたサブスクライバーに配信され、サブスクライバーは利用可能なノードのプールに再接続する必要があります。停止していたノードが再び参加すると、メッセージの受信を開始します。この場合、NATSは、バックエンドへのリクエスト用のシンプルなインメモリルーターであるHAProxyなどの機能を置き換えます。

NATSのユーザーには、Buzzfeed、Tinder、Stripe、Rakutan、Ericsson、HTC、Siemens、VMware、Pivo​​tal、GE、Baiduなどが挙げられます。あるユースケースでは、「当社では同期通信にNATSを使用しており、1秒あたり約1万件のメッセージを送信しています。高負荷時(10MB/秒以上)でも非常に高い安定性を実現しています。数週間にわたり本番環境で運用していますが、問題は発生していません。主な制約は、大規模クラスタが不足していることです。非常に強力なクラスタを構築できますが、各ノードは1回しか転送できないため、制約があります。」と述べています。

#RabbitMQ:

RabbitMQは、AMQP 0.9.1標準に準拠したブローカー型メッセージングエンジンです。標準的なストアアンドフォワードパターンを採用しており、データをRAM、ディスク、またはその両方に保存できます。様々なメッセージルーティングパラダイムをサポートしています。RabbitMQは、パフォーマンス向上のためにクラスターに導入することも、高可用性のためにミラーリング方式で導入することもできます。コンシューマーはキューを直接リッスンしますが、パブリッシャーは「エクスチェンジ」についてのみ認識します。これらのエクスチェンジは、バインディング(ルーティングパラダイムを指定する)を介してキューにリンクされます。バインディングキューとトランザクション配信セマンティクスが存在します。そのため、RabbitMQはより「ヘビーウェイト」なキューイングソリューションであり、そのため追加コストがかかります。

デメリット:RabbitMQの高可用性サポートは非​​常に貧弱です。パーティショニングによって発生したキューの競合をマージできないため、どのようにローテーションさせても単一障害点となります。パーティショニングはネットワーク障害時だけでなく、高負荷時にも発生する可能性があります。RabbitMQはメッセージをディスクに永続化しません。

#カフカ:

Scalaベース

Kafka では、リアルタイム処理とバッチ処理の両方を実行できます。Kafka は JVM(具体的には Scala)上で動作します。パブリッシュ・サブスクライブ(またはキューイング)ルーティングを介して大量のデータを取り込みます。ブローカーはコンシューマーについてほとんど何も知りません。実際に保存されるのは、ログ内でコンシューマーが保持される場所を指定する「オフセット」値のみです。コンシューマーが主にオンラインであることを前提とする多くの統合ブローカーとは異なり、Kafka は大量のデータを正常に保存し、「リプレイ」シナリオをサポートします。そのアーキテクチャは非常に独特です。トピックはパーティションごとに整理され(並列処理のため)、パーティションはノード間で複製されます(高可用性のため)。

Kafkaと比較すると、NATSははるかに小規模なインフラストラクチャであり、ユニコーンスタートアップ、IoT、ヘルスケア、大手金融機関(LinkedIn、Facebook、Netflix、GE、Bank of America、Fannie Mae、Chaseなど)で使用されています。KafkaはNATSよりも成熟しており、大規模なデータストリームでも優れたパフォーマンスを発揮します。NATSServerは、限られたユースケースに特化しているため、Kafkaと比較して機能の一部しか提供していません。NATSは、高パフォーマンスと低レイテンシが不可欠であるものの、データフローのペースに対応するために多少のデータ損失が許容されるシナリオ向けに設計されています。NATSのドキュメントでは、これを「一度きりで完了」と説明しています。構造的には、NATSには永続データストレージ用の永続化レイヤーがないのに対し、Kafkaには永続化レイヤー(クラスター内のストレージを使用)があるためです。メッセージが失われないようにするには、キューを永続化として宣言し、メッセージを永続化としてマークし、パブリッシャー確認応答を使用する必要があるようです。これにより、数百ミリ秒のレイテンシが発生します。

パーティショニングにおいて、比較的安全で信頼性の高いキューまたはパブリッシュ/サブスクライブシステムはKafkaだけです。5~50台のサーバーが必要な場合、Kafkaは非常に信頼性の高いソリューションです。これだけの台数のサーバーがあれば、1秒あたり数百万件ものメッセージを処理でき、中規模企業であれば通常は十分な処理能力です。

いくつかの理由から、Kafka は RPC に適していません。まず、Kafka のデータモデルはキュー内のデータをシャーディングし、各パーティションは 1 つのコンシューマーのみが使用できます。パーティション 1 と 2 があるとします。P1 は空で、P2 には多数のメッセージがあります。C2 が動作している間、アイドル状態のコンシューマー C1 が存在します。C1 は自身のパーティションしか処理できないため、C2 からの処理を引き継ぐことはできません。つまり、低速なコンシューマーはキューの大部分をブロックする可能性があります。Kafka は高速な(または少なくとも均一なパフォーマンスを発揮する)コンシューマー向けに設計されています。

  • NATSとKafkaの関係

NATS は最近、CNCF プロトコルに参加しました(Kubernetes、Prometheus などのプロジェクトがホストされています。Golang の利点については、こちらでご確認ください)。Kafka は TCP ベースのバイナリですが、NATS はシンプルなテキストベース(これも TCP ベース)のメッセージング パターンです。どちらもパブリッシュ/サブスクライブとキューをサポートしていますが、NATS は要求/応答(同期と非同期)もサポートしています。NATS にはキューの概念(もちろん一意の名前を持つ)があり、同じキューに接続されたすべてのサブスクライバーは、最終的に同じキュー グループの一部になります。(複数の場合もある)サブスクライバーのうち 1 つだけがメッセージを受信します。このような複数のキュー グループも同じメッセージ セットを受信します。つまり、パブリッシュ/サブスクライブ(1 対多)とキュー(ポイントツーポイント)のハイブリッドです。Kafka は、1 つ以上のトピックからデータを取得できるコンシューマー グループを通じて同じ機能をサポートしています。ストリーミング - NATS は Kafka の Kafka Streams と同じ最上位レベルの機能を提供しないため、ストリーミングをサポートしていません。 NATSがメッセージをプルする方法は、サーバー自体がクライアントにメッセージをルーティングするNATS(内部的にインタレストグラフを維持)とは対照的です。NATSは、本番環境の速度を満たさないコンシューマーやハートビート要求に応答しないクライアントを遮断するなど、細心の注意を払った対策を講じることができます。コンシューマーのアクティビティチェックはKafkaによっても実行されます。これはクライアント自身から実行/開始されるため、複雑な状況が発生する可能性があります(例:メッセージ処理ループ中にポーリングが行われていない場合など)。この動作を調整できる(クライアント側の)設定パラメータは多数あります。

  • 配信セマンティクス - NATSは最大1回(NATSストリーミングは少なくとも1回)をサポートしますが、Kafkaは正確に1回をサポートします。(NATSにはKafkaのような分割/シャーディングされたメッセージの概念がなく、NATSには外部依存関係もありません。KafkaはZookeeperを必要とし、NATSストリーミングはKafkaの機能セットに似ていますが、Goで構築されており、セットアップがより簡単であるようです。)NATSは現在、レプリケーションをサポートしていません(または、実質的に高可用性設定がありません)。これは、Kafkaと比較して欠けている主要な機能です。

#NSQ:

NSQはセットアップの容易さから、より柔軟性が高いように見えます。メッセージの永続性をサポートし、永続性要件がそれほど高くないアプリケーション向けに、NATSと同様の一時的なチャネルを提供します。また、NATSにはない洗練された管理ダッシュボードも備えています。NATSは、パフォーマンスを重視する場合に便利です。NATSとNSQのキューはどちらも、時間的制約のあるメッセージをプルーニングするためのメッセージごとのTTLをサポートしています。

Kafka は複雑ですが、データ損失がないことを保証します。ログの順序付けに適しています。NSQ には永続性とレプリケーション機能がありません。大規模な操作は非常にシンプルです。Kafka のパフォーマンスと強化された保証は、運用の複雑さの増加を犠牲にして実現されています。Kafka を使用する場合は、Kafka ブローカーに加えて、Zookeeper クラスターが必要です。Kafka ではパーティションとオフセットを考慮する必要があります。Kafka はメッセージブローカーではなく、分散ログサービス、つまり printf ステートメントではなくデータベースの先行書き込みログのようなものと考えるのが適切です。

NSQは、より伝統的なバッファリング型メッセージングシステムです。ファイルの永続性はありますが、これはメモリ不足によるメッセージ損失を防ぐための最適化と、コンシューマのアーカイブとしてのみ機能します。しかし、深刻なノード損失が発生すると、まだ配信されていないメッセージが失われる可能性があります。これは、それらのメッセージが他の場所に公開される保証がないためです。さらに、トピックやチャネルに公開されたメッセージの順序が、コンシューマが受信する順序と一致する保証もありません。NSQには、組み込みユーティリティnsq_to_fileがあり、これは各メッセージトピックをディスクにアーカイブする際に便利なツールとなります。シンプルなメールアーカイブ機能は備えていますが、ローカル再生機能は備えていません。

#Apache Pulsar(pulsar.incubator.apache.org):

Javaベース

Yahoo! によって設計された Apache Pulsar は、パブリッシュ/サブスクライブ型メッセージングとメッセージキューイングのための、高性能、低レイテンシ、スケーラブルな永続ソリューションです。Apache Kafka による高性能ストリーミングと、RabbitMQ による柔軟な従来型キューイングを統合した、統一されたメッセージングモデルと API です。Pulsar は、統一された API を用いて、ストリーミングシステムとキューイングシステムの両方で同等の高性能を実現します。つまり、Kafka は高スループットを、Pulsar は低レイテンシを目標としているのです。

パルサーの利点

  • 豊富な機能には、永続/非永続テーマ、マルチテナント、ACL、マルチ DC レプリケーションなどが含まれます。
  • よりユーザーフレンドリーで柔軟なクライアント API (CompletableFutures、流れるようなインターフェースなどを含む)。
  • Java クライアント コンポーネントはスレッドセーフであり、コンシューマーは異なるスレッドからのメッセージを確認できます。

パルサーの欠点

  • Java クライアントには Javadoc がほとんどありません。
  • 小規模コミュニティ - 現在 Stack Overflow の質問が 8 件あります
  • BookKeeper にバインドされた MessageId
  • 連続した数値シーケンスを表すKafkaオフセットと比較すると、コンシューマーはトピック上での位置を簡単に特定できません。また、リーダーはトピックの最後のメッセージを簡単に読むことができません。
  • トランザクションはサポートされていません。
  • 運用の複雑さが増す(Zookeeper + Broker ノード + BookKeeper) - すべてのクラスターのレイテンシが疑問視される - Broker ノードと BookKeeper の間に追加のリモート呼び出しがある(Kafka と比較)。

Kafkaの利点

  • 非常に包括的で便利なJavaDoc
  • Kafka Streams には成熟した大規模なコミュニティがあります。
  • 運用時の操作が簡単 - コンポーネントが少ない - プロキシノードはストレージも提供
  • トランザクション – トピック内のアトミックな読み取りおよび書き込みオフセットが連続したシーケンスを形成し、コンシューマーが最後のメッセージを簡単に見つけられるようにします。

Kafkaの欠点

  • コンシューマーは他のスレッドからのメッセージを確認できません。
  • マルチテナントなし
  • 堅牢なマルチ DC レプリケーションなし - (Confluent Enterprise で利用可能)
  • クラウド環境の管理は困難です。