我们使用 Drools 作为解决方案的一部分,在非常密集的处理应用程序中充当某种过滤器,可能在 500,000 多个工作内存对象上运行多达 100 条规则。事实证明它非常慢。还有其他人有在批处理应用程序中使用 Drools 的经验吗?

有帮助吗?

解决方案

我还没有使用过最新版本的 Drools(我上次使用它是大约一年前),但当时我们的高负载基准测试证明它非常慢。在我们的大部分架构基于它之后,我们感到非常失望。

至少我记得关于 drools 的一个好处是他们的开发团队可以在 IRC 上使用并且非常有帮助,你可以尝试一下,毕竟他们是专家: irc.codehaus.org #drools

其他提示

有点取决于你的规则 - 给定足够的内存,500K 对象是合理的(它必须在内存中填充 RETE 网络,因此内存使用量是 500K 对象的倍数 - 即对象空间 + 网络结构、索引等的空间) - 它可能您正在分页到磁盘,这会非常慢。

当然,如果您有匹配相同类型事实的组合的规则,这可能会导致要尝试的组合爆炸,即使您有 1 个规则也会非常非常慢。如果您对正在进行的分析有更多信息,可能会有助于找到可能的解决方案。

我使用的 Drools 具有包含超过 1M 事实的状态工作内存。通过对规则和底层 JVM 进行一些调整,在初始启动几分钟后,性能可能会非常好。如果您想了解更多详细信息,请告诉我。

我自己也在学流口水,所以也许我漏掉了一些东西,但是为什么一整批五十万个对象一下子就被添加到了工作记忆中呢?我能想到的唯一原因是,只有当批次中的两个或多个项目相关时,才会出现一些规则。

如果情况并非如此,那么也许您可以使用无状态会话并一次断言一个对象。我假设在这种情况下规则的运行速度会快 500k 倍。

即使是这样,您的所有规则都需要访问所有 500k 对象吗?您是否可以通过一次应用一项每一项规则,然后在处理的第二阶段使用不同的规则库和工作内存应用批处理级别规则来加快速度?这不会改变数据量,但 RETE 网络会更小,因为简单的规则将被删除。

另一种方法是尝试识别相关的对象组,并在第二阶段断言组中的对象,进一步减少工作内存中的数据量并分割 RETE 网络。

Drools 并不是真正设计用于在大量对象上运行的。它针对在几个对象上运行复杂规则进行了优化。

每个附加对象的工作内存初始化太慢,并且缓存策略被设计为针对每个工作内存对象工作。

在解析几千个对象后,我遇到了 OutOfMemory 错误的问题。设置不同的默认优化器解决了这个问题。

OptimizerFactory.setDefaultOptimizer(OptimizerFactory.SAFE_REFLECTIVE);

我们也在研究流口水,但对我们来说,对象的数量很少,所以这不是问题。我确实记得读过同一算法的替代版本,它们更多地考虑内存使用情况,并且在仍然基于相同算法的同时针对速度进行了优化。但不确定它们是否已成为真正可用的库。

使用无状态会话并一次添加一个对象?

也可以使用参数-dmvel2.disable.jit = true设置此优化器

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top