Akka调度程序线程创建

ryoqjall  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(262)

我一直在研究Akka Actor模型。我有一个用例,其中超过1000个Actor将处于活动状态,我必须处理这些Actor。我想通过在application. conf中定义的配置来控制线程计数。
但是在我的应用程序中创建的调度器线程的数量使我在调整调度器配置时无能为力。每次当我重新启动我的应用程序时,我看到创建的调度器线程的数量不同(我已经在每次启动应用程序后通过线程转储检查过了)。
甚至线程数也不等于我在parallelism-min中定义的线程数。由于线程数较低,我的应用程序处理速度非常慢。通过以下代码检查我机器中的内核数:
运行时.getRuntime().可用处理器();
它显示40。但是,即使我将并行度配置为500,创建的分派程序线程数仍小于300。
下面是我的应用程序.conf文件:

consumer-dispatcher {
  type = "Dispatcher"

  executor = "fork-join-executor"

  fork-join-executor {
    parallelism-min = 500
    parallelism-factor = 20.0
    parallelism-max = 1000
  }

  shutdown-timeout = 1s

  throughput = 1
}

我可以知道akka将在什么基础上在内部创建调度器线程,以及我如何增加我的调度器线程计数来增加参与者的并行处理吗?

yqhsw0fo

yqhsw0fo1#

首先让我直接回答这个问题。
fork-join-executor将由java.util.concurrent.forkJoinPool池支持,其并行度设置为调度程序配置中的隐式并行度(并行度因子 * 处理器,但不大于最大值或小于最小值)。因此,在您的情况下,为800。
虽然我不是ForkJoinPool实现方面的Maven,但ForkJoinPool的Java实现的源代码说:“所有工作线程的创建都是按需的,由任务提交、替换被终止的工作线程和/或补偿被阻塞的工作线程来触发。”而且它有像getActiveThreads()这样的方法,所以很明显,ForkJoinPool并不只是天真地创建一个巨大的工作线程池。
换句话说,您看到的是预期的结果:它只会在需要的时候创建线程。如果你真的需要一个巨大的工作线程池,你可以创建一个固定池大小为800的线程池执行器。这将为你提供你所需要的实现。
但在你这么做之前,我认为你完全没有理解actor和Akka的意义。人们喜欢actor的原因之一是它们比线程轻得多,可以给予你比线程多得多的并发性。(另请注意,concurrency!= parallelism,如概念文档中所述。)因此,试图创建一个800个线程的池来支持1000个演员是非常浪费的。在X1 E1 F1 X中,它强调了“数百万演员可以在十几个线程上高效地调度”。
在不了解应用程序的情况下(例如,如果您有阻塞行为),我无法准确告诉您需要多少线程,但默认值(并行度因子为20)可能就足够了。基准测试可以确定,但我真的不认为线程太少会有问题。(您所观察到的ForkJoinPool行为似乎证实了这一点。)

相关问题