2013-01-09 9 views
6

私は、分析されるメッセージの連続ストリームを持っています。この分析では、著者、トピック、感想、単語数、別個の単語のセットなど、さまざまな変数が返されます。システム内のユーザーはルールを定義することができ、ルールが一致するとアラートをトリガーする必要があります。ルールはSQLデータベースに格納する必要があります。ルールは、メッセージ分析の単一の基準、すなわちword-count > 15 && topic = 'StackOverflow' && sentiment > 2.0 && word-set contains 'great'を組み合わせたものです。許可された各ルール基準は、メッセージ分析の最後に提供されます。その後、ルールの検証がトリガーされ、Javaで実装されます。連続ルールマッチングのパターン

システム内のすべてのユーザによって定義されたすべてのルールについて、すべてのメッセージをチェックする必要があります。これは多くの計算能力を必要とします(現在10 +メッセージ/秒があり、チェックするルールは10.000+になります)。マッチング処理を高速化する共通のパターンはありますか?1つ1つを除いて、ルールを並行してチェックすることができるでしょうか?純粋なSQLでこれを行うことは可能ですか?異なるタイプのルールのスキーマはどのように見えますか?

+0

SQLは、通常、リレーショナルデータベース用です。このシステムのリレーショナルデータベースはどこにありますか? –

+0

ユーザが定義したルールはどこに保存されていますか? – sourcecode

+0

各メッセージには、すべてのルールを解決するために必要なすべてのフィールドが含まれていますか? –

答えて

2

あなたの考慮事項は、マッチングのスループットだけではありません。たとえば、ルールを維持する必要があります。

しかし、すべてのルールを満たすために必要なすべてのフィールドを含む静的なルールとメッセージがあるとします。 SQLを使用すると、構造はmessageテーブルから始まります。このテーブルのトリガーはinsertです。挿入トリガは、ルールとのマッチングを担当します。これを行う最善の方法は何ですか?

1秒あたり10以上のメッセージで、各マッチがシングルスレッドの場合でも、処理は本質的にパラレルになります。マッチを並列化するためにどれだけの労力が必要かはわかりません。データベースの並列性は一般に、SQL文の中ではなくSQL文の中にあります。

さまざまなソリューションがあります。たとえば、巨大なストアドプロシージャでコードとしてコードをエンコードすることができます。これは維持する悪夢であり、ストアドプロシージャの長さ制限を超え、痛いほど遅くなる可能性があります。

別の夢のようなアイデア。ルールの一致するメッセージをそのルールのテーブルに格納し、一致するメッセージのみをロードするように制約を設定します。あなたのプロセスは、膨大な数の挿入文のように見えます。一致規則を持っているでしょう

select * 
from rules 
where . . . 

結果セット:

はもっと真剣に、次のようなコードで、さらに移動します。すべてのルールのため、すべての可能な比較はwhere節になり、ある

select * 
from rules r 
where @wordcount > coalesce(r.wordcount, 0) and 
     @topic = coalesce(r.topic, @topic) and 
     . . . 

where句のようなものである可能性があります。そして、ルールは必要な句を特定するために事前処理されます。

あなたも、外部変数を省略し、クエリを直接アクセスすることができます。

select * 
from rules r cross join inserted i 
where i.wordcount > coalesce(r.wordcount, 0) and 
     i.topic = coalesce(r.topic, @topic) and 
     . . . 

だから、はい、これはSQLで実現可能です。そして、あなたは並行してマッチングを行うことができます。ルールをデータベースの比較に適した形式で取得する作業が必要です。

+0

これらの提案をいただきありがとうございます。最大の問題は、それらが本質的に非常に異なる可能性があるため(実際には異なる演算子、数値、または比較などのために)、ルールを共通データベース形式に適合させることです。 – Thomas

+0

@Thomas。 。 。これがコンサルタントが存在する理由です。 –

1

SQLを使用していないのにC#で同様の問題を解決しました。

移植性のために、データベースにシリアル化されたXMLとしてルールを格納しました。

アプリケーションの起動時、またはルールテーブルが変更されたとき(ルールキャッシュを強制的にフラッシュする)、データベースからすべてのルールをロードし、それらを適切なクラスにデシリアライズしました。

各アプリケーションサーバーでデータが入力されると、受信データに対してルールが実行され、ルールを渡すために適切なアクションが実行されました。 (当時、私はアプリケーションサーバー上でprocでアクションを実行していましたが、今はキューにダンプします)

これは、アプリケーションクラスター全体で計算を広げ、データベース・マシン上のサイクルを吸い上げる。