在短时间内用Java执行数百万个任务?

时间:2014-08-26 03:31:41

标签: java multithreading performance

我需要用Java执行大约8,000,000个任务。每个任务在1到50毫秒之间运行。我尝试使用循环并使用ThreadPoolExecutor并行地连续执行这些任务。显然,在循环中串行运行它们要慢得多,然后通过ThreadPoolExecutor运行它们会显着提高性能。但是,我仍然不满意ThreadPoolExecutor的效果。

我能够在4个核心上使用15个线程运行所有8,000,000个任务。在向ThreadPoolExecutor提交任务时,我正在批处理50,000个任务。我允许ExecutorCompletionService超时1000毫秒来返回结果。使用这些参数调整我的应用程序后,我需要大约25分钟来处理所有8,000,000个任务。

有没有办法让我以超过25分钟的速度运行我的应用程序,也许是Hadoop(使用多台机器的分布式系统)?我愿意使用其他一些技术或框架。

2 个答案:

答案 0 :(得分:1)

这个Akka tutorial显示了Akka如何帮助完成并行任务。

我对Akka没有任何动手经验,但我的理解是它负责根据部署时的配置扩展应用程序(例如,线程数,进程数,集群中的主机数......),对任务实施几乎没有任何改变。

有关维基百科的更多信息:The key points distinguishing applications based on Akka actors

答案 1 :(得分:0)

为了找到最佳线程数,您必须查看单个任务。

如果任务专门使用核心,则任何其他任务都无法在同一核心上执行。但是,大多数任务都有IO的一些元素,例如读取数据以进行处理和写回结果(假设您的任务是例如一些复杂的计算)。

主题计数应约为'amount of cores' x 'utilization percentage' 其中利用率百分比是您在0和1之间的调整参数。使用以下命令动态查找核心数:

int cores = Runtime.getRuntime().availableProcessors();

所以

int poolcount = Math.round( cores * utilizationFactor);

如果您随后需要缩放,则可以水平或垂直缩放。

水平地,更多核心将调整吞吐量,但如果任务之间的同步太多,则在这种情况下利用率可能不是线性的。

垂直地,更多的计算机,肯定会为您提供更多的核心来计算。因此,由于水平扩展的成本,处理农场一直很有趣。但是,分发成本和分配数据以进行计算的成本一直是瓶颈。

Hadoop,如评论所述,通过在分区中分发数据并将计算结果发送到数据来解决问题。这对于简单合并的分而治之的任务类型非常有用。

Cassandra也评论说,它提供了一个分布式数据库,通过提交日志和选择性读/写一致性来处理分区写入。这基本上可以更快地移动您的数据,但我怀疑您不太依赖于此。

除了这些笔记之外,你真的需要查看你的任务,看看它们是如何构思的,以及它们应该实现什么,特别是在分而治之的性质或顺序/管道性质上。如同建议的那样,Akka在吞吐异步任务方面提供了很多帮助,并且对同步障碍有所帮助。

最后,我的最后一条建议是查看LMAX Disruptor(http://lmax-exchange.github.io/disruptor/)。这应该允许您以非常高的吞吐量在阶段之间传递工作负载。 (与最佳核心控制一起)可能会提高您的速度,而无需过多地重新考虑场景。