我有一项任务可以很容易地分成可以并且应该并行处理以优化性能的部分。
我写了一个制作人演员,它准备了可以独立处理的任务的每个部分。这种准备相对便宜。
我写了一个处理每个独立任务的消费者Actor。根据参数,每个独立任务可能需要几秒钟才能处理。所有任务都完全相同。它们都处理相同的算法,具有相同数量的数据(但当然是不同的值),导致大致相同的处理时间。
因此,制作人比消费者快得多。因此,很快就可以准备200或2000个任务(取决于参数)。所有这些都消耗内存,而其中只有几个可以同时执行。
现在我看到两种简单的策略来消费和处理任务:
为每项任务创建一个新的消费者角色实例。
另一种策略是使用消费者角色的N个实例,并将任务作为消息发送给他们。
我可以想象一个更复杂的解决方案,在生产者和消费者之间进行更多的协调,但如果不了解调度程序,我就无法做出正确的决定。
如果手动解决方案不会带来明显更好的性能,我宁愿使用默认解决方案(由Scala世界的某些部分提供),其中调度任务不会由我决定(如策略1)。
问题综述:
我担心,像前两个这样的问题无法得到绝对的回答,但这次也许这是可能的,因为我试图尽可能具体地说明案例。
我认为其他问题可以在没有多少讨论的情况下得到解答。有了这些答案,就应该可以选择最符合要求的策略。
我自己做了一些研究和思考,并提出了一些假设。如果这些假设有任何错误,请告诉我。
答案 0 :(得分:0)
如果我是你,我会继续使用2
nd选项。每个任务的新actor实例太繁琐了。此外,通过N
的智能决策,可以使用完整的系统资源。
虽然这不是一个完整的解决方案。但是一个可能的选择是,生产者不能停止/减慢生产任务的速度吗?这将是理想的。只有当有消费者或其他东西时,生产者才会产生更多的任务。
答案 1 :(得分:0)
假设你正在使用Akka(如果你没有,你应该;-)),你可以使用SmallestMailboxRouter
来启动一些演员(你也可以添加一个Resizer
)和消息分发将根据一些规则处理。您可以阅读有关路由器here的所有信息。
答案 2 :(得分:0)
对于这样一个简单的任务,演员完全没有利润。将生产者实现为Thread,将每个任务实现为Runnable。使用java.util.concurrent中的线程池来运行任务。使用java.util.concurrent。信号量限制准备和运行任务的数量:在创建下一个任务之前,生产者获取sempahore,每个任务在执行结束时释放信号量。