6

我有一个连续的消息流进行分析。分析返回不同的变量,如作者、主题、情绪、字数和一组不同的单词。系统中的用户能够定义规则,当匹配时应该触发警报。规则应存储在 sql 数据库中。规则是来自消息分析的单个标准的组合,即word-count > 15 && topic = 'StackOverflow' && sentiment > 2.0 && word-set contains 'great'。在消息分析结束时提供每个允许的规则标准,之后将触发规则验证并在 Java 中实现。

每条消息都必须检查系统中所有用户定义的所有规则,这会占用大量计算能力(目前每秒有 10+ 条消息,将有 10.000+ 条规则要检查)。是否有一个共同的模式来加速匹配过程,也许这样规则可以并行检查,除了一个一个?是否有可能在纯 SQL 中做到这一点,不同类型规则的模式会是什么样子?

4

2 回答 2

2

您的考虑可能不仅仅是匹配的吞吐量。例如,您需要维护规则。

但是,让我们假设一组静态规则和消息,其中包含满足所有规则所需的所有字段。使用 SQL,该结构将从message表开始。该表将有一个insert触发器。插入触发器将负责匹配规则。做这个的最好方式是什么?

每秒有 10 多条消息,您的处理本质上是并行的,即使每个匹配都是单线程的。我不确定您需要多少努力才能并行化匹配。数据库中的并行性通常出现在 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 中是可行的。而且,您可以并行进行匹配。您只需要努力以适合数据库比较的格式获取您的规则。

于 2013-01-09T16:46:33.717 回答
1

尽管没有使用 SQL,但我在 C# 中解决了类似的问题。

出于可移植性的目的,我将规则作为序列化 XML 存储在数据库中。

在应用程序启动时,或者当规则表更改(强制刷新规则缓存)时,我从数据库中加载所有规则并将它们反序列化到相应的类中。

然后当数据进入每个应用服务器时,我对传入的数据执行规则,并为传递规则执行适当的操作。(当时我正在应用服务器上的 proc 中执行操作,但现在我将其转储到队列中。)

这样做的好处是可以将计算分散到您的应用程序集群中,并且不会让所有计算都占用数据库机器上的周期。

于 2013-01-09T16:47:32.723 回答