在大量处理中使用Drools
我们使用Drools作为解决方案的一部分,在非常紧张的处理应用程序中充当某种过滤器,也许可以在500,000个以上的工作内存对象上运行多达100条规则。
事实证明,它非常慢。
其他人是否有在批处理处理应用程序中使用Drools的经验?
解决方案
我没有使用最新版本的Drools(我上次使用它大约是一年前),但是那时我们的高负载基准测试证明它完全慢。在将我们的许多架构作为基础之后,这非常令人失望。
至少我记得关于流口水的一些好处是他们的开发团队可以在IRC上使用,并且非常有帮助,我们可以尝试一下,毕竟他们是专家:irc.codehaus.org #drools
Drools并非真正设计为可以在大量对象上运行。它针对在几个对象上运行复杂的规则进行了优化。
每个其他对象的工作内存初始化太慢,并且将缓存策略设计为对每个工作内存对象都起作用。
我们也在看流口水,但是对我们来说,对象的数量很少,所以这不是问题。我确实记得读过同一算法的替代版本,这些替代版本更多地考虑了内存使用情况,并且针对速度进行了优化,同时仍基于同一算法。不确定是否有任何一个使它成为一个真正可用的库。
取决于规则的种类如果给定足够的内存,则500K个对象是合理的(它必须在内存中填充一个RETE网络,因此内存使用量是500K个对象的倍数,即对象空间+网络结构,索引空间等)分页到磁盘,这真的很慢。
当然,如果我们具有匹配同一类型事实的组合的规则,则可能导致尝试组合的爆炸式增长,即使我们只有1条规则也将非常慢。
如果我们有更多有关分析的信息,则可能会有助于找到可能的解决方案。
我只是在学习自己流口水,所以也许我错过了一些东西,但是为什么将整批的五十万个对象一次添加到工作内存中呢?我能想到的唯一原因是,只有当批次中的两个或者多个项目相关时,规则才会生效。
如果不是这种情况,那么也许我们可以使用无状态会话并一次声明一个对象。我认为规则在这种情况下的运行速度将提高500k倍。
即使是这种情况,我们所有的规则都需要访问所有500k对象吗?我们能否通过一次应用一个项目规则来加快处理速度,然后在处理的第二阶段中使用不同的规则库和工作内存来应用批处理级别规则?这不会改变数据量,但是RETE网络会更小,因为简单的规则将被删除。
另一种方法是尝试在第二阶段中识别对象的相关组并在组中声明这些对象,从而进一步减少工作内存中的数据量以及拆分RETE网络。
使用无状态会话并一次添加一个对象?
我使用了Drools,其中包含超过1M个事实的有状态工作内存。通过对规则和基础JVM进行一些调整,在最初启动几分钟后,性能可能会非常好。如果我们需要更多详细信息,请告诉我。