我正在开发一个接受100k +唯一输入的应用程序 - 为简单起见,假设每个输入都是浮点值(a,b,c ......等) - 尽管它们也可以是字符串等。应用程序具有许多与这些输入相关的规则/事件/触发器。
示例1:
Rule[(a > b) and (c <= d)] --> [execute EventX]
定义1:以上规则说:当输入'a'的值大于'b'的值且输入'c'的值小于或等于''的值时d'执行EventX
示例2:
Rule[x != x.prev] --> [execute EventZ]
定义2:上述规则说明:如果值更新后,输入'x'的当前值不等于其先前值(值已更改)。执行EventZ
我发现,随着输入数量的增加,随着规则数量的增加,评估“特定”规则并确定是否应该触发事件所需的总计算量正在逐渐减少控制 - 在问题上投掷更快,更多的h / w没有按预期进行扩展。
目前,每次新的输入更新时,都会在哈希表中查找关联的输入/变量,该哈希表将变量映射到包含它的规则。随后对每个规则进行评估,如果结果为真或可操作,则异步触发相关事件。
这个问题属于复杂事件处理领域,不幸的是,这个领域中的大多数架构使用了上述相同的死角方法 - 可能还有一些与评估/重新评估事物的频率有关的改进。我们的想法是拥有一个能够近乎实时地做出反应的系统。在多个节点上分配规则和输入似乎也不能很好地工作,因为在某些情况下,超过95%的活动规则中存在少数输入。
我希望在那里有任何SO同伴,知道更好的方法来解决这个问题,数据/结构或算法。
我想到的一个简单的想法是,可以构建一个依赖逻辑推理的列表。
如果有两个规则如下:
Rule[a < b] --> [exec E1]
Rule[b >= a] --> [exec E2]
然后对'a'或'b'的更新不应该要求对两者等进行评估,但我发现构建这样的逻辑推理结构非常复杂且容易出错,并且难以完全和严格地测试。 / p>
输入可以代表股票价格,温度传感器等等。
进一步注意,一些输入在时间上受到限制,这意味着规则可能要求变量的状态在特定位置/状态下持续一段时间(例如:MSFT的价格> 20美元最后30秒),目前这是通过使用值为0或1 / false或true的'代表变量'(facade)来实现的(变量的值由单独的机制决定,通常是由被触发的规则。)
还应该注意的是,由于近实时约束和每秒产生的数据量,使用带有触发器和存储过程的数据库的选项是不可能的。
答案 0 :(得分:8)
一些想法。
如果规则的条件是连词,则为每个未满足的条件保持不满足的条件。将规则仅放在该术语的检查列表中。如果该术语满足,则扫描其他术语以确定是否触发了条件或是否存在另一个未满足的术语。 (我想我在SAT求解器的背景下了解了这个技巧。)
如果你有10&lt; = x&lt; = 50这样的术语,请快速使用interval tree代替哈希来找到x更新和不满意条款即将变得不满意的满意条款即将变得满意的。 (O(log n)要搜索,加上每个结果返回O(1)。如果一次考虑一个变量产生过多的虚假命中,则存在多维概括,但维护它们的成本会更高。
如果您没有这样的术语(例如,&lt; = b),请创建派生输入(b - a)并使用您的哈希策略使其保持最新。
答案 1 :(得分:0)
尝试对常用表达式进行分解,对它们进行分组和缓存:这可能会加速,特别是那些最常用的表达式,所以表演可能会增长。
可行性如何,取决于表达逻辑时必须使用的语言。 我看到您的流程可能被模型化为电子表格,其中计算是数据驱动程序。一个拓扑式的公式WRT单元参考足以进行基本评估,但事情变得复杂很快......
在C ++中,您可以尝试使用模板表达式来解决逻辑问题。为您的语言建模的帮助者可以是Boost.proto
ETALIS在Prolog中做CEPS。
我还没(尝试过)(唉),但我相信它非常好。肯定会实现你所追求的,甚至更多。
在SWI-Prolog中运行,应该易于访问,易于设置和操作,SWI-Prolog C ++界面非常便于实际数据交换。
答案 2 :(得分:0)
似乎没有在多个节点上分配规则和输入 工作也很好,因为在某些情况下存在少数投入 超过95%的活跃规则。
分发规则,并将输入提供给所有计算机。然后,您可以线性扩展规则数量...如果您在局域网上,您可以将事件/输入作为多播发送,因此网络流量不会增加。