Akka 流 - 将 IO 绑定流放在不同的调度程序上

Akka stream - putting an IO bound Flow on a different dispatcher

我的流均匀地混合了 CPU 绑定阶段和 IO 绑定阶段(每个 IO 阶段后跟一个 CPU 阶段)。我想要做的是将 IO 操作放在与流的其余部分不同的调度程序上。

在传统的基于 actor 的 Akka 应用程序中,我可以将我的 IO actor 放在具有大量线程的固定线程池调度程序上,同时将 CPU 绑定的 actor 放在具有少量线程的 fork join 池中线程(核心数量的一些倍数,理想情况下为 1 个)。这应该可以减少 CPU 绑定 actor 在线程切换中浪费的时间,同时通过在 IO 上阻塞大量线程来增加吞吐量。

这样理解对吗?如果不是,为什么?如果是,那么如何将我的 IO 绑定阶段(流)放在与流的其余部分分开的单独调度程序上?

我试过关闭自动融合,这确实有帮助。但它的吞吐量仍然比几乎相同的 Akka 对应物低很多。

默认情况下,流程中的所有阶段都 运行 在同一个参与者上,您可以使用属性将阶段标记为 运行 在单独的调度程序上,如下所示:

stage.withAttributes(ActorAttributes.dispatcher("dispatcher-name"))

这还将围绕该阶段引入异步边界,有效地运行将其固定在自己的 actor 中。为避免异步边界的成本变得过高,该阶段现在实际上会一次从上游发送对 16 个元素的需求,因此您必须注意这一点。

可以使用附加属性调整缓冲区大小,在这种情况下,它的行为类似于融合阶段,因为它一次请求一个元素,请注意,这可能会产生太多开销,具体取决于用例.

stage.withAttributes(Attributes.inputBuffer(1, 1))

文档的相关部分: