Akka framework supports ZeroMQ in its ZeroMQ extensions module. Akka is a great framework and we have our product built on its version 1.3x. We were looking at ZeroMQ support in our product and we stumbled on this issue. We found that ZeroMQ applications built on Akka extensions are running slower than an application built in plain scala.
Please read about our discussion thread on Akka user list. The issue is now accepted issue no #1963 you can view it here in assembla. The bug is now resolved great work by typesafe guys especially Roland Kuhn. This blog will deal with workaround till it is pushed in the new release. The workaround has a caveat that the Subscriber hangs on to the thread that created it. It is like the pinned dispatcher with allocated thread to the subscriber. Please look at the comment below.
I will create two simple PUB/SUB application one by using Akka based extension and one without it and then measure their throughput in order to compare their performance.
Let’s start the project by creating a sbt based project. Here is my build.sbt. It contains Akka 2.0 dependencies and that of ZeroMQ scala binding.
I use eclipse IDE so here is the entry for sbteclipse plugin in my project/plugin.sbt
Let’s start with the Publisher. It will create a publisher socket and then bind to it. But we want it to be wrapped in Akka based Actor. I will use its lifecycle method preStart to create publisher socket and bind to it. Here is the code.
When we fire message to publisher; the receive block becomes active and message is sent on to publisher socket.
We also need a Subscriber that reads messages published by the publisher. Subscriber also needs to be an akka actor. Subscriber will create a Subscriber socket and then do a connect followed by subscribing to it. We will add this code in preStart lifecycle method. In the receive block it calls a recv method on the socket created; it is then capable of receiving messages from the publisher. Here is the code.
We wanted to measure its throughput so lets have a DiagnosticsActor which simply mentions throughput and elapsed time after all messages are processed by Subscriber. Number of messages are in ZMQWithoutAkkaExtensionApp object.
ZMQWithoutAkkaExtensionApp instantiates Publisher, Subscriber and DiagnosticsActor. It then loops on number of messages and sends messages to publisher. The publisher then in its receive block writes on the socket. Here is the code for DiagnosticsActor and ZMQWithoutAkkaExtensionApp.
Here is the complete code listing of the Application:
Here is the Akka extension based version for ZeroMQ. Please read some documentation here if you find following the code difficult. Here, we have ZMQApplication: it starts publisher, subscriber and diagnostics as before and fires messages to publisher socket. Here is the complete code listing.
Complete code listing is on our github. It is a sbt based project. After you have the code on your box descend in the directory and execute following commands.
here are my runs for both versions:
There is a significant difference in throughput as you will notice. The Akka extension based version is giving me around 3300 msgs/sec and the one without around 18,300 msgs/sec.