Scala – the cost of creating actors in Akka

akkaperformancescala

Consider a scenario in which I am implementing a system that processes incoming tasks using Akka. I have a primary actor that receives tasks and dispatches them to some worker actors that process the tasks.

My first instinct is to implement this by having the dispatcher create an actor for each incoming task. After the worker actor processes the task it is stopped.

This seems to be the cleanest solution for me since it adheres to the principle of "one task, one actor". The other solution would be to reuse actors – but this involves the extra-complexity of cleanup and some pool management.

I know that actors in Akka are cheap. But I am wondering if there is an inherent cost associated with repeated creation and deletion of actors. Is there any hidden cost associated with the data structures Akka uses for the bookkeeping of actors ?

The load should be of the order of tens or hundreds of tasks per second – think of it as a production webserver that creates one actor per request.

Of course, the right answer lies in the profiling and fine tuning of the system based on the type of the incoming load.
But I wondered if anyone could tell me something from their own experience ?

LATER EDIT:

I should given more details about the task at hand:

  • Only N active tasks can run at some point. As @drexin pointed out – this would be easily solvable using routers. However, the execution of tasks isn't a simple run and be done type of thing.
  • Tasks may require information from other actors or services and thus may have to wait and become asleep. By doing so they release an execution slot. The slot can be taken by another waiting actor which now has the opportunity to run. You could make an analogy with the way processes are scheduled on one CPU.
  • Each worker actor needs to keep some state regarding the execution of the task.

Note: I appreciate alternative solutions to my problem, and I will certainly take them into consideration. However, I would also like an answer to the main question regarding the intensive creation and deletion of actors in Akka.

Best Answer

You should not create an actor for every request, you should rather use a router to dispatch the messages to a dynamic amount of actors. That's what routers are for. Read this part of the docs for more information: http://doc.akka.io/docs/akka/2.0.4/scala/routing.html

edit:

Creating top-level actors (system.actorOf) is expensive, because every top-level actor will initialize an error kernel as well and those are expensive. Creating child actors (inside an actor context.actorOf) is way cheaper.

But still I suggest you to rethink this, because depending on the frequency of the creation and deletion of actors you will also put afditional pressure on the GC.

edit2:

And most important, actors are not threads! So even if you create 1M actors, they will only run on as many threads as the pool has. So depending on the throughput setting in the config every actor will process n messages before the thread gets released to the pool again.

Note that blocking a thread (includes sleeping) will NOT return it to the pool!

Related Topic