Skip to Content
Course content

71: Akka Cluster Basics

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've seen a lot of developers make the same mistake when they first move from a single-node Akka application to a distributed one. They treat "remote" and "cluster" as the same thing. They start by using akka.remote, hardcoding a few IP addresses into a config file, and using ActorSelection to send messages across the wire. It works fine when you have two servers and a stable network, but the moment you try to scale or a server crashes, the whole thing falls apart.

The Trap of Manual Remote Addressing

Imagine we're building a distributed game session manager. You have "GameRoom" actors that hold the state of a match. In the naive approach, you might maintain a list of your server IPs and just pick one at random to host a new game. You'd use something like "akka://GameSystem@10.0.0.5:2552/user/room-123" to find your actor.

The problem here is that your application is blind. If the server at 10.0.0.5 crashes, the rest of your system has no idea. You'll keep trying to send messages to a dead node, and your "session manager" will be throwing DeathPledge exceptions or simply timing out. You end up writing a massive amount of boilerplate code just to track which servers are actually alive—essentially trying to build your own membership service on top of Akka. Trust me, you don't want to do that. It's a rabbit hole of edge cases and race conditions.

// The "Naive" way: Manual remote lookups
// This is fragile. If this node goes down, we're just shouting into the void.
val roomActor = system.actorSelection("akka://GameSystem@10.0.0.5:2552/user/room-123")
roomActor ! StartGame(gameId = "match-1")

Letting the Gossip Protocol Do the Heavy Lifting

This is where Akka Cluster comes in. Instead of you managing a list of IPs, Akka Cluster introduces the concept of a "Cluster" where nodes talk to each other using a gossip protocol. When a node joins the cluster, it tells a few other nodes it's there, and that information spreads organically across the network. Every node eventually knows the status of every other node without you having to write a single line of "heartbeat" logic.

In our game session example, you stop thinking about 10.0.0.5 and start thinking about Member objects. You can use the Cluster extension to track the state of the cluster. If a node is marked as Unreachable, the cluster knows. You can then write logic that says, "If the node hosting GameRoom-123 is unreachable, let's spin up a replacement on a healthy node."

import akka.cluster.Cluster

val cluster = Cluster(system)
// Instead of a hardcoded IP, we can check if a member is actually Up
val member = cluster.member(MemberAddress("akka://GameSystem@10.0.0.5:2552"))
if (member.status == MemberStatus.Up) {
  // Now we know the node is actually healthy before we send a request
}


The Cost of Agreement and the Split-Brain Headache

Now, I should be honest with you: moving to a cluster isn't a free lunch. The trade-off for this automation is the "Split Brain" scenario. In a distributed system, there's a big difference between a node being dead and a node being disconnected.

If your network cable gets unplugged between two halves of your cluster, both sides might decide that the other side is dead. They'll both try to take over the same responsibilities—like hosting the same GameRoom actor. Suddenly, you have two different versions of the same game state running on two different sets of servers. This is the nightmare scenario for consistency. Akka provides strategies to handle this (like the SBR - Split Brain Resolver), but it's something you have to think about upfront. You're trading the simplicity of a single machine for the complexity of distributed consensus.




📋 Practical Task

Build a Cluster Membership Monitor

Create a Scala application using Akka Cluster that implements a ClusterMonitor actor. Your goal is to build a system that proactively logs the health of the cluster rather than waiting for a request to fail.

  • Initialize a Cluster extension within your ActorSystem.
  • The ClusterMonitor actor should subscribe to MemberUp and MemberRemoved events from the ClusterEventPublisher.
  • Whenever a new node joins the cluster, the actor should print: "Welcome to the party: [Member Address]".
  • Whenever a node leaves or is removed, it should print: "Node has left the building: [Member Address]".
  • Test this by spinning up three separate instances of your application on different ports (using a config file or system properties) and shutting one down to see the monitor react in real-time.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.