2009-07-06 14 views
3

私は、私たちのアプリケーションで新しい機能のためにワイヤフレーム上で作業しています。要件の1つは、各ユーザーが処理するもののリストを持っていることです。Sql server 2008サービスブローカー何百万ものキュー

SQL Server 2008サービスブローカーを使用して、ToDoアイテムの通知をユーザーに送信する予定です。

しかし、ブローカキューが動作している方法では、単一キュー内のユーザーのメッセージを分離できません。メッセージが取得された後にしか見ることができません。しかし、私はそれを呼び出しているユーザーのメッセージを取得したいだけです。

ブローカーサービスを使用する場合は、ユーザーごとに別のキューが必要です。

その後、私はブローカーサービスで何百万ものキューを持つことになります。

私は1つのキューを持つことができますが、フィルタを使用してメッセージを取得できるブローカサービスの機能がありませんか?

SQL Server 2008ブローカサービスは何百万ものキューを処理できますか?

答えて

7

一般的に、メッセージングアプリケーションはイベント駆動型です。メッセージが来たら、メッセージを処理する処理手順を起動する。 Service Brokerは、キューに関連付けられたアクティブ化メカニズムを通じてこれを実装します。この考え方では、処理が常にキュー内の「次のメッセージ」を処理するため、メッセージをフィルタ処理する必要はなく、キューは理想的には常に空です。その結果、RECEIVE動詞はフィルターを提供しません。 RECEIVEのWHERE句は、会話や会話グループに限定されています。これは、特定のメッセージをフィルタリングするのではなく、アプリケーションがconversation group lockingの概念を活用するのを助ける手段です。

キューは通常の(内部)テーブルは、彼らが何百万人も悪い考えを持つになるだろう暗黙のいくつかの荷物を運ぶの空想の名の下に装った以上のものではありませんが:各キューに関連付けられ、少なくともサービスを持っている必要があります

  • それ。サービスは、メッセージルーティングに関連付けられているため、起動時間(dbをスキャンしてtempdb隠しインスタンスのルーティングテーブルを作成する)、tempdbスペース(前記ルーティングテーブル)、およびランタイムメモリを消費するため、ランタイムコストは少し重くなります(ルーティングに関連するキャッシュメモリ構造)。また、(ルーティングアルゴリズムが何百万という候補者の間で決定するための)いくつかのCPUオーバーヘッドを誘発するだろう。
  • アクティブ化が関連付けられている場合、キューは「単独で」重くなります。各キューにはランタイムオブジェクト(キューモニター)があり、メモリとCPUを消費します。http://rusanu.com/2008/08/03/understanding-queue-monitors
  • キューに到達するために少なくとも1つの会話が必要で、ライブアクティブな会話にはオーバーヘッドが発生することがあります。
  • キューオブジェクトはRECEIVE動詞に関連付けられ、さらに重要なことにWAITFOR(RECEIVE)に関連付けられます。 WAITFORはサーバー上のワーカースレッドをブロックし、各キューにWAITFORを配置するよりもずっと前に、sp_configure 'max worker threads'を使い果たします。

また、キュー/サービスは、通常のテーブルよりも設定/監視の観点からもう少し「アクティブ」です。 poison message detectionはキューをトリガーして無効にすることができますが、100万のキューを監視するのは難しいでしょう(それは自動化する必要がありますが、それでもなお必要です)。第二に、何らかの理由でメッセージがtransmission queueで遅れている場合に起こりうる問題です。何百万回もの会話が再開されたときに再開するとかなり悪くなります(マイレージは異なるかもしれませんが、あなたのSQLバージョン/いくつかの問題がSQL 2K5 SP3の後に修正されたため)。

Service Brokerは、主に分散アプリケーションの問題(DCM/COM +、Corba、Remotingなどで扱われていない問題に対処すること)を考慮して設計されています。しかし、キューイングの動作とアクティベーションメカニズムを活用するために、ローカルに配置され、単一のSQL Serverインスタンスまたはデータベース内に完全に含まれることがよくあります。あなたがSSBを見ている唯一の理由は、キューを活用することだとすれば、SSBキューと独自のユーザーテーブルを使用するキューの間に50/50の分割があり、 (つまり、ユーザーテーブルに基づいたキューに付随する多くのデッドロックの問題を解決する方法を知っています)。アクティベーションを活用している場合、SSBにはもっと魅力があります。実際にリモートメッセージングを行っているのであれば、明らかに最良の選択肢です。

あなたのケースでは、何百万のキューを持つのが悪い考えであることを私が明確にしたいと思っています。あなたのメッセージはどこから発信されますか(ローカルかリモートか)、なぜService Brokerを使い始めることを検討していますか?すべての詳細を知っていれば、最善の選択肢は、1つのキューを持つことで、到着時にすべてのメッセージを処理し、各ユーザーの関連情報を適切なフィルタリングが可能な通常の表に格納するアクティブ化プロシージャです。各ユーザーは独自のデータを取得できます。

開示:私は同じキューに複数のリスナーのためのto-doキューを設定する方法はありService Broker team and maintain the SSB blog

+0

メッセージを他の企業に転送するシナリオ(1000 +など)はどうですか?理想的には、A社の通信に問題があるため、A社からB社へのメッセージをブロックすることは望ましくありません。私はこれに対する解決策が、複数のキューを持つのではなく、有害なメッセージの処理にあると仮定していますか? 特定のWebサービスインターフェイスを使用してこれらの企業と統合する必要があるため、サービスブローカーを使用してメッセージを企業キュー(ホストしている)またはそのようなものに転送することはできません。 – spooner

+0

@spooner:実際にService Brokerには転送機能が組み込まれており、サービスブローカーメッセージングスタック全体が公平に設計されているため、メッセージは他のメッセージをブロックできないだけでなく、大きなメッセージでもセッションから短いメッセージでインターリーブされます。有害なメッセージの処理とキューは**インフラストラクチャではなく**アプリケーション**です。メッセージを処理することができないユーザーコード、アプリケーションであり、常に定義上、コード内のバグです。 –

+0

@spooner:組み込みSSB転送を理解するにはhttp://msdn.microsoft.com/en-us/library/ms166098.aspxを参照してください。 –

1

の元メンバーです。これは、サービスブローカの会話を追跡するために補助テーブルを必要とし、RECEIVE句には会話ハンドルや会話グループによって制限されたフィルタ機能があるという事実を利用します。

このテーブルは、各リスナーの行を有するテーブルリスナー(ListenerCodeのVARCHAR(10)主キー、ConversationGroup一意識別子デフォルトNEWID())

を作成します。リスナーコードまたはその他のキーは、各リスナーのID /コードです。リスナーにメッセージを送信する必要がある場合は、会話グループを検索し、その会話グループに送信します。これは、BEGIN DIALOG ... RELATED_CONVERSATION_GROUP = ....で指定されています。

ConversationGroupは会話に付けることのできる単なるタグであり、参照テーブルはありません。 (http://msdn.microsoft.com/en-us/library/ms166131.aspxを参照してください)

リスナーは、会話ハンドルを検索し、その会話グループで受信します。彼らが聞いていない場合、彼らのメッセージは単にキューに入れられます。

一度消費されると、メッセージはデータベースから消えます。これがユーザーのために処理するもののリストであれば、おそらく永続的なリストが必要です。だから私はおそらくタスクテーブルを作成し、キュー内のメッセージは単にタスクテーブルへの参照になります - キューはストア自体ではなく新しいアイテムの通知です。

関連する問題