4

EventHubClientを使用して、C# で複数のスレッドからAzure イベント ハブにメッセージを発行するコードを書いています。EventHubClient のドキュメントには、かなり標準的なボイラー プレートが含まれています。

「この型の public static (Visual Basic では共有) メンバーはスレッド セーフです。インスタンス メンバーは、スレッド セーフであるとは限りません。」

スレッドセーフであると私が最も期待する4 つの send メソッドのいずれにも、スレッドセーフに関する追加のドキュメントはありません。send メソッドがスレッドセーフではないと信じていたら、メッセージを送信するたびに新しい EventHubClient インスタンスを作成することになります。基礎となる tcp 接続は明らかに再利用されるため、手順を実行しない限り、オーバーヘッドはそれほど大きくない可能性があります。分割された送信者でも同様の問題が発生しますが、送信者を作成する非同期メソッドがある場合、独自の AMQP 接続が存在する可能性があります。

ドキュメントにもかかわらず、すべてではないにしても、EventHubClient のインスタンス メソッドの一部はスレッド セーフですか?

また、Azure の関係者にとって、これをドキュメントで明確にすることは可能でしょうか? この種のドキュメントの問題 (間違っている可能性が高いと仮定) は、Azure テーブルにも影響を与えるようであり、MSDN ドキュメント内では一般的に一般的です。EventHub に関しては、これはKafkaの明確なスレッド セーフ ステートメントとは対照的であり、AWS Kinesisは少なくともすべてを安全でないと明示的にラベル付けしていません。SDK のオープン ソース部分に EventHubs が見つからなかったため、自分で確認できませんでした。

4

1 に答える 1

7

TLDR :

  1. .NET SDK のすべての重要なランタイム操作 (別名データ プレーン) は、スレッド セーフです。
  2. 一度オブジェクトを作成EventHubClientして再利用する

物語

ServiceBus SDK は、送信者を作成する 2 つのパターンを公開します。

  1. 基本
  2. 高度

Basic バージョンの場合、開発者は API を直接使用し、オブジェクト (接続 gu) のEventHubClient.CreateFromConnectionString()管理について心配する必要はありません。SDK は、この再利用のために SDK で が同じである限り(すべてのキーと値の文字どおりの一致)、すべてのインスタンスでMessagingFactoryの の再利用を処理します。MessagingFactoryEventHubClientconnection string

接続レベルでもう少し制御が必要な上級開発者には、SB SDK が提供MessagingFactory.CreateFromConnectionString()し、この開発者からEventHubClientインスタンスを作成できます。

EventHubClient- to send to EventHubsのすべてのインスタンス メソッドは、厳密にスレッド セーフです。一般に、すべてのデータ プレーン操作は... ただし、EventHubs からの読み取り中、API はこのパターンに最適化されています。 while(true) { var events = eventHubPartitionReceiver.receive(100); processMyEvents(events); } したがって、例: のようなプロパティは、同期なしEventHubReceiver.RuntimeInformationですべての呼び出しの後に入力されます。receiveそのため、実際のreceiveAPI はスレッド セーフですが (RuntimeInformation への後続の呼び出しはスレッド セーフではありませんreceive)、1 つのインスタンスで複数の呼び出しをパークすることはめったにありませんPartitionReceiver

メッセージの送信を開始するために、各コンポーネントで の新しいインスタンスを作成するのEventHubClientがデフォルトのパターンです。ServiceBus SDK は、同じ物理ソケットを再利用する基礎となる MessagingFactory を再利用します (接続文字列が同じ場合)。

実際に高スループットのシナリオを探している場合は、複数の MessagingFactory オブジェクトを作成してから、それぞれ EventHubClient を作成する戦略を設計する必要があります。ただし、これを試す前に、Portal で EventHub のスループット ユニットをすでに増やしていることを確認してください。これは、デフォルトが 1 MBPS (16 パーティションすべての累積) であるためです。

また、使用している送信パターンがパーティション化された送信者である場合、同じeventHubClient (.CreatePartitionedSender()) インスタンスからすべての送信者を作成すると、それらはすべて同じ基になる MessagingFactory も使用します。

于 2014-11-13T23:07:07.120 に答える