I've found that my Akka Streams program had unexpected CPU usage.
Here is a simple example:
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()
The code piece above will let source and sink runs in the same actor.
It uses about 105% CPU usage on my laptop. Works as expected.
And after I was added an async boundary:
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()
This code piece now will use about 600% of CPU usage on my 4c8t laptop.
I was expecting by adding an async boundary this stream will run in 2 separate actors and will cost a little more than 200% CPU. But it costs a lot more than 200%.
What may causes async boundary to use that much CPU?
Default akka.actor.default-dispatcher
parameter is Java's ForkJoinPool
. It's initialized via call to ThreadPoolConfig.scaledPoolSize
. Thus it defaults to starting pool of size (number of processors * 3) and max = parallelism-max
(64).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With