Akka Cluster is a module in the Akka toolkit that allows you to build fault-tolerant, distributed systems by connecting multiple nodes (or instances) into a cluster. It enables nodes to communicate seamlessly with each other, providing resilience, scalability, and support for location transparency.
Distributed Systems Support:
Location Transparency:
Resilience:
Dynamic Membership:
Cluster Sharding:
Cluster Singleton:
Failure Detection:
Microservices:
Real-time Data Processing:
Scalable Systems:
Resilient Actor Systems:
Cluster Nodes:
Gossip Protocol:
Membership State:
Message Delivery:
import akka.actor.ActorSystem
import akka.cluster.Cluster
import com.typesafe.config.ConfigFactory
object ClusterNode extends App {
// Load cluster configuration
val config = ConfigFactory.load("application.conf")
// Create an ActorSystem
val system = ActorSystem("ClusterSystem", config)
// Join the cluster
val cluster = Cluster(system)
println(s"Node [${cluster.selfAddress}] started and joined the cluster.")
}?
application.conf
Configuration Example :akka {
actor.provider = cluster
remote.artery.canonical.hostname = "127.0.0.1"
remote.artery.canonical.port = 2551
cluster.seed-nodes = [
"akka://ClusterSystem@127.0.0.1:2551",
"akka://ClusterSystem@127.0.0.1:2552"
]
}?
A seed node in Akka Cluster is one or more designated nodes used to bootstrap and initialize the cluster. Seed nodes are responsible for helping other nodes discover and join the cluster.
When a node starts, it contacts one or more seed nodes (defined in the configuration) to obtain the current cluster membership information. Once the new node communicates with a seed node, it can successfully join the cluster and participate in distributed operations.
Discovery Mechanism:
Required for Initialization:
Redundancy:
Not Persistent:
Join
message to the first reachable seed node.Join
request to the cluster leader.Seed nodes are defined in the application.conf
file under the akka.cluster.seed-nodes
setting.
akka {
actor.provider = cluster
remote.artery.canonical.hostname = "127.0.0.1"
remote.artery.canonical.port = 2551
cluster {
seed-nodes = [
"akka://ClusterSystem@127.0.0.1:2551",
"akka://ClusterSystem@127.0.0.1:2552"
]
}
}
The gossip protocol in Akka Cluster is a key mechanism used to distribute cluster state information across all nodes in the cluster. It ensures that every node in the cluster has a consistent and up-to-date view of the cluster's current membership and health.
This decentralized approach is lightweight, scalable, and fault-tolerant, making it ideal for distributed systems.
Cluster State Propagation:
Randomized Communication:
Eventual Consistency:
Failure Detection:
Scalability:
The gossip protocol manages the states of nodes in the cluster:
Decentralized:
Fault Tolerance:
Scalable:
Resilient:
Consider a cluster with three nodes: NodeA
, NodeB
, and NodeC
.
Initial State:
NodeA
is aware of itself but knows nothing about NodeB
and NodeC
.Gossip Communication:
NodeA
gossips its state to NodeB
, and NodeB
updates its local view.NodeB
gossips to NodeC
, propagating the updated state.Convergence:
You can configure gossip settings in the application.conf
file :
akka {
cluster {
gossip-interval = 1s # Frequency of gossip messages
failure-detector {
threshold = 8.0 # Adjust failure detection sensitivity
heartbeat-interval = 1s # Frequency of heartbeat messages
}
}
}
Joining → Up
state after being approved by the cluster leader. Cluster(system).leave(Address)
API or the akka.cluster.jmx.enabled
JMX feature to notify the cluster that the node intends to leave. The node transitions from Leaving
to Exiting
.
A Cluster Singleton in Akka is a feature that ensures a single instance of an actor is running across the entire cluster at any given time. This is useful for scenarios where you need centralized processing or coordination within a distributed system, but still want fault tolerance and failover support.
Single Instance Across the Cluster:
Automatic Failover:
Cluster Membership Awareness:
Location Transparency:
Singleton Manager:
Singleton Proxy:
Leader Node:
You need to define a SingletonManager and (optionally) a SingletonProxy in your code.
Example : Cluster Singleton Implementationimport akka.actor.{Actor, ActorSystem, Props}
import akka.cluster.singleton._
import com.typesafe.config.ConfigFactory
object ClusterSingletonExample extends App {
// Actor to be used as a singleton
class SingletonActor extends Actor {
override def receive: Receive = {
case message => println(s"Singleton Actor received: $message")
}
}
// Create ActorSystem with cluster configuration
val config = ConfigFactory.load("application.conf")
val system = ActorSystem("ClusterSystem", config)
// SingletonManager definition
val singletonManager = system.actorOf(
ClusterSingletonManager.props(
singletonProps = Props[SingletonActor], // Props for the singleton actor
terminationMessage = PoisonPill, // Message to terminate the singleton
settings = ClusterSingletonManagerSettings(system)
),
name = "singletonManager"
)
// SingletonProxy definition
val singletonProxy = system.actorOf(
ClusterSingletonProxy.props(
singletonManagerPath = "/user/singletonManager", // Path to SingletonManager
settings = ClusterSingletonProxySettings(system)
),
name = "singletonProxy"
)
// Send a message to the singleton actor via the proxy
singletonProxy ! "Hello, Singleton!"
}
In Akka Cluster Sharding, the Shard Region plays a critical role in distributing and managing entities (actors) across a cluster. It is responsible for routing messages to the appropriate shard and, ultimately, to the specific entity (actor) within the shard, regardless of where the entity resides in the cluster.
This allows location transparency and dynamic scaling of actors across the cluster while simplifying actor management.
Message Routing:
Shard Management:
Entity Lifecycle Management:
Fault Tolerance:
Location Transparency:
Scaling and Rebalancing:
Akka Distributed Data is a module in Akka that provides a way to manage eventually consistent, replicated, and distributed data across nodes in a cluster. It is built on the foundation of Conflict-Free Replicated Data Types (CRDTs), which are data structures designed to resolve conflicts automatically when data is updated concurrently on different nodes.
This module is particularly useful in scenarios where strong consistency isn't required, but availability and partition tolerance are critical.
Eventual Consistency:
Conflict Resolution:
High Availability:
Scalability:
Distributed State Management:
Immutable and Persistent Data:
Conflict-Free Replicated Data Types (CRDTs) are special data structures designed for distributed systems. They allow for concurrent updates from multiple nodes and ensure eventual consistency by resolving conflicts automatically without requiring coordination between nodes.
Counters:
Sets:
Maps:
Registers:
Flags:
false
to true
(one-way toggle).A split-brain scenario in an Akka Cluster occurs when a network partition divides the cluster into two or more isolated sub-clusters that are unable to communicate with each other. Each partition may still function independently, but they are unaware of the other partitions. This situation can lead to inconsistent state, duplicate work, or data corruption, as multiple nodes may assume leadership or perform conflicting tasks simultaneously.
Split-brain can occur due to:
Duplicate Leadership:
Inconsistent State:
Data Corruption:
Service Downtime:
Akka provides mechanisms to detect and resolve split-brain scenarios automatically. These include: