Akka - 调度器

3

我一直在阅读文档,但不是很清楚每个演员是否只与一个Dispatcher相关联,还是只有一个。假设我有actor SendSmsActor和actor UpdateSmsActor,它们都会使用默认的dispatcher吗?还是每个演员都会得到自己的默认dispatcher实例?对我来说也不是很清楚,如果我有500个传入请求(作为批处理的一部分),并且我的parallelism-max设置为300,这300个线程会在SendSmsActor和UpdateSmsActor之间分配吗?


是的,除非您明确指定,否则两者都将使用默认调度程序。您可以说会有300个线程,但这不会并行工作,因为并行性取决于您拥有的核心数量,更多的是上下文切换。 - Raman Mishra
2个回答

1
默认情况下,Akka使用默认调度程序在线程上执行演员。一个dispatcher是整个Actor System中所有演员的共同点。Akka还提供编写自定义调度程序的选项。您可以在调度程序中指定执行器类型。
线程不会在演员之间分裂。调度程序中可用的任何空闲线程都将用于执行演员。
默认调度程序配置为:
default-dispatcher {
type = "Dispatcher"
executor = "fork-join-executor"

fork-join-executor {
    parallelism-min = 8
    parallelism-factor = 3.0
    parallelism-max = 64
}

thread-pool-executor {
    keep-alive-time = 60s
    core-pool-size-min = 8
    core-pool-size-factor = 3.0
    core-pool-size-max = 64
    max-pool-size-min = 8
    max-pool-size-factor  = 3.0
    max-pool-size-max = 64
    task-queue-size = -1
    task-queue-type = "linked"

    allow-core-timeout = on
}

}

参考资料:默认的Akka调度程序配置值是什么?

1

除非您显式为演员实例分配备用调度程序(无论是通过配置还是编程),否则两个演员都将在默认调度程序上执行。

默认的 fork-join 调度程序将在线程之间平衡负载。但是,throughput 选项将确定在切换到另一个演员之前每个演员应处理多少个消息。

根据您的工作负载,300 个调度程序线程可能是最优的,也可能不是最优的。如果您的演员完全非阻塞,则您可能希望从每个 CPU 核心开始大约有 1 个线程,然后进行一些基准测试以微调该数字。否则,您将浪费 CPU 周期进行不必要的上下文切换。如果您的演员阻塞,则您可能需要提供一个单独的调度程序,并将您的阻塞演员配置为使用该调度程序。请参见阻塞需要仔细管理


嗨Eric,感谢回复。我有一些正在使用REST API(因此是阻塞操作)的SendNotificationActor,我正在考虑为此创建一个新的调度程序。它必须是具有固定池大小的线程池执行器吗?还是可以使用fork-join-executor?感谢回复。 - Diego Ramos
@DiegoRamos,你应该确认你的http客户端是阻塞还是非阻塞的。如果是非阻塞的,只需使用默认调度程序。如果是阻塞的,你可能想要使用一个固定大小的线程池执行器来限制启动的线程数量。 - Eric
它是阻塞的,为什么我们应该使用线程池执行器而不是分支/合并? - Diego Ramos
线程池执行器将限制生成的线程数量,因此适用于具有任意长任务延迟的I/O绑定任务。分叉/合并池主要用于CPU绑定任务。 - Eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接