Blog

December 16, 2011

Akka 2.0 Pre-Release Milestone 1

December 16, 2011

by Jonas Bonér

We are proud to announce the first pre-release milestone of Akka 2.0, which will be part of the upcoming Typesafe Stack 2.0.

Akka is an event-driven middleware framework, for building high performance and reliable distributed applications in Java and Scala. Akka decouples business logic from low-level mechanisms such as threads, locks and non-blocking IO. Your Scala or Java program logic lives in lightweight actor objects which send and receive messages. With Akka, you can easily configure how actors will be created, destroyed, scheduled, and restarted upon failure.

Typesafe and the Akka open source community have been hard at work laying the foundation for Akka 2.0 for many months now. In this post, we’d like to highlight some of the changes made relative to Akka 1.x, and look a bit behind the scenes at why we made those changes, and how you can benefit from them.

Modular Configuration

In Akka 1.x, configuration, registry, and logging settings are all global, which poses challenges when running multiple Akka applications with different settings within the same class loader. In Akka 2.0, all global shared state has been removed so that multiple actor systems can co-exist. An Akka application is now contained within an ActorSystem class. This allows more flexibility in deploying Akka applications and is particularly useful for testing actor systems.

Mandatory Supervisor Hierarchies

Akka achieves fault tolerance in large part by using a supervisor hierarchies, inspired by Erlang’s OTP framework. Fault tolerance and error recovery strategies are fundamental to the success of Erlang systems. In the supervisor hierarchy model, a supervisor actor is responsible for starting, stopping and monitoring its child actors.

Akka has always had support for supervision hierarchies but now includes this supervision automatically. Error recovery is built-in to all actor systems and can be configured and refined easily. Actors naturally form tree structures based on parent actors creating child actors. Parent actors are now the supervisor for any children created, handling all errors and failures in the children.

Actor systems get much simpler to reason about when every actor has a supervisor. Among other benefits, this removes the need for maintaining a central registry—a global point of contention—and replaces it with local registries arranged in a hierarchy. If this sounds like a file system to you, you are on the right track: with these features, every actor in a system can be identified by giving the names of its ancestors, with the root provided by the ActorSystem itself. This enables path look-ups of actors, even relative to a reference point (i.e. “../joe” would be the current actor’s brother named “joe”). One positive side effect is that instead of opaque UUIDs, you will find meaningful names in your log messages.

The “Error Kernel” or ”Onion Layer” pattern has been used to great effect in platforms like Erlang to structure applications in a fault-tolerant way, and with Akka’s new mandatory parental supervision this design comes naturally. With mandatory supervisor hierarchies, you’re encouraged to design for fault tolerance from the beginning, rather than as an afterthought in your application.

Location Transparency

One of the key features of actor-based programming is that actors are naturally distributable. Actor-based systems are distributed systems by design. A lot of restructuring has taken place in Akka to make the most of this “distributed by default” approach. The internals of Akka have been completely reworked so that they only use asynchronous message exchanges, laying the foundations for improved remote and distributed actors. With every actor identified by a URI—with remote protocol, host, port and path—it becomes very easy to refer to actors across node boundaries. The implementation of actor supervision has been simplified so that it works the same whether parent and child are on the same or different nodes. And since this distributed approach lends itself so well to scaling out, we made it even easier by allowing the deployment of actors to be specified purely by configuration, instead of through APIs as was the case in Akka 1.x. Consider the following example:

akka {
  actor {
    deployment {
      /serviceA/retrieval {
        remote = “akka://app@10.0.0.1:2552”
         # “app” is the ActorSystem’s name
      }
      /serviceA/aggregation {
        router = “round-robin”
        nr-of-instances = 10
        target {
          nodes = [“akka://app@10.0.0.2:2552”, “akka://app@10.0.0.3:2552”]
        }
      }
    }
  }
}

With a configuration snippet like this, given an actor named “serviceA”, the child named “retrieval” will be deployed on a specific host, while the child named “aggregation” will be cloned 10 times, and evenly distributed across the two given target nodes. (The ability to be routed needs to be declared in the code to avoid surprises, but the configuration can override all properties).  To support the new configuration model, configuration file handling has been split out into a no-dependencies Java library which you can also use for your own projects; it is also used also by Play 2.0 so that you can configure an Akka & Play application with a single configuration file.

Additional Refinements

The three big features mentioned above have spawned a lot of other changes to make them possible. For example, the “ask” operation was reimplemented by creating a one-off actor for handling the reply so that replies to Futures work like normal message sends. All these changes have made the API more consistent, generally removing methods while adding features. We also made an effort to make actors even more light-weight: currently the overhead is around 350 bytes per instance, which translates to about 2.7 million actors per GB in heap size. We also invested in removing blocking synchronization wherever possible, making Akka more scalable than ever: there is not a single “synchronized” in the Akka hot paths and current benchmarks yield 24 million messages processed per second on a standard quad-core MacBook Pro.

With Akka 2.0, Futures and Promises have also received a major overhaul. This effort has been in coordination with the Scala team from EPFL in order to unify these concepts between Akka and the Scala libraries, with the aim of moving towards one common interface and implementation for these important constructs.

In summary, this release represents a true version 2 of Akka. While adding new capabilities, the Akka development team took advantage of the clear version step to weed out code which would impede future improvement. The improvements were done especially with cluster support in mind, which will be the primary focus for the subsequent 2.1 release.

This pre-release milestone presents the new face of Akka in a mostly feature-complete form, but without all of the refinement that will be present in the final release. For example, we will provide a migration helper kit which contains bridges in the form of a global default ActorSystem to ease the transition from Akka 1.x. At the same time, we hope that you will try out the this early pre-release of Akka 2.0 and provide your feedback via the Akka project issue tracker and mailing list. You can download the pre-release milestone from the Akka project Maven repository or download page, and documentation for this release is on the Akka project site. Happy hAkking!

comments powered by Disqus
Browse Recent Blog Posts