为什么在 Akka Streams 中添加异步边界会花费很多 CPU?
Why adding async boundary in Akka Streams costs a lot of CPU?
我发现我的 Akka Streams 程序有意外的 CPU 使用。
这是一个简单的例子:
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
implicit val system: ActorSystem = ActorSystem.create("QuickStart")
implicit val materializer: ActorMaterializer = ActorMaterializer()
Source.repeat(Unit)
.to(Sink.ignore)
.run()
上面的代码片段会让 source 和 sink 在同一个 actor 中 运行s。
它在我的笔记本电脑上使用了大约 105% CPU。按预期工作。
在我添加异步边界之后:
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
implicit val system: ActorSystem = ActorSystem.create("QuickStart")
implicit val materializer: ActorMaterializer = ActorMaterializer()
Source.repeat(Unit)
.async // <------ async boundary here
.to(Sink.ignore)
.run()
这段代码现在将在我的 4c8t 笔记本电脑上使用 CPU 的大约 600%。
我原以为通过添加异步边界,此流将 运行 在 2 个独立的 actor 中,成本将略高于 200% CPU。但是比200%贵很多。
什么可能导致异步边界使用那么多CPU?
默认 akka.actor.default-dispatcher
参数是 Java 的 ForkJoinPool
。它通过调用 ThreadPoolConfig.scaledPoolSize
进行初始化。因此它默认为起始池大小(处理器数量 * 3)和 max = parallelism-max
(64).
我发现我的 Akka Streams 程序有意外的 CPU 使用。
这是一个简单的例子:
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
implicit val system: ActorSystem = ActorSystem.create("QuickStart")
implicit val materializer: ActorMaterializer = ActorMaterializer()
Source.repeat(Unit)
.to(Sink.ignore)
.run()
上面的代码片段会让 source 和 sink 在同一个 actor 中 运行s。
它在我的笔记本电脑上使用了大约 105% CPU。按预期工作。
在我添加异步边界之后:
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
implicit val system: ActorSystem = ActorSystem.create("QuickStart")
implicit val materializer: ActorMaterializer = ActorMaterializer()
Source.repeat(Unit)
.async // <------ async boundary here
.to(Sink.ignore)
.run()
这段代码现在将在我的 4c8t 笔记本电脑上使用 CPU 的大约 600%。
我原以为通过添加异步边界,此流将 运行 在 2 个独立的 actor 中,成本将略高于 200% CPU。但是比200%贵很多。
什么可能导致异步边界使用那么多CPU?
默认 akka.actor.default-dispatcher
参数是 Java 的 ForkJoinPool
。它通过调用 ThreadPoolConfig.scaledPoolSize
进行初始化。因此它默认为起始池大小(处理器数量 * 3)和 max = parallelism-max
(64).