2. outline
actors
remote actors
rise of the cluster
when the cluster grows up
3. What is an Actor?
• Akka's unit of computation is called an Actor
• Actors are purely reactive components:
– a mailbox
– behavior & state
– scheduled to run when sent a message
• Each actor has a parent, handling its failures
5. Define Actor
Define the message(s) the Actor
should be able to respond to
public class Greeting implements Serializable {
public final String who;
public Greeting(String who)the Actor class = who; }
Define { this.who
}
public class GreetingActor extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
int counter = 0;
public void onReceive(Object message) {
if (message instanceof Greeting) {
counter++;
log.info("Hello #" + counter + " " + ((Greeting) message).who);
}
} Define the Actor’s behavior
}
6. Create Actor
public class Greeting implements Serializable {
public final String who;
public Greeting(String who) { this.who = who; }
}
public class GreetingActor extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
int counter = 0;
public void onReceive(Object message) {
if (message instanceof Greeting) {
counter++;
log.info("Hello #" + counter + " " + ((Greeting) message).who);
Actor configuration
} Create an Actor system
}
}
ActorSystem system = ActorSystem.create("MySystem");
ActorRef greeter = system.actorOf(new Props(GreetingActor.class), "greeter");
You get an ActorRef back Create the Actor Give it a name
7. Actors can form hierarchies
Guardian System Actor
system.actorOf(
Foo Bar
new Props(Foo.class), “Foo”);
getContext().actorOf( A
A C
new Props(A.class), “A”);
B E C
B
D
8. Name resolution - like a file-system
Guardian System Actor
/Foo
Foo Bar
/Foo/A
A C A
/Foo/A/B
B E C
B
D /Foo/A/D
9. Send Message
public class Greeting implements Serializable {
public final String who;
public Greeting(String who) { this.who = who; }
}
public class GreetingActor extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
int counter = 0;
public void onReceive(Object message) {
if (message instanceof Greeting) {
counter++;
log.info("Hello #" + counter + " " + ((Greeting) message).who);
}
}
}
ActorSystem system = ActorSystem.create("MySystem");
ActorRef greeter = system.actorOf(new Props(GreetingActor.class), "greeter");
greeter.tell(new Greeting("Charlie Parker"), null);
Send the message
10. Full example
public class Greeting implements Serializable {
public final String who;
public Greeting(String who) { this.who = who; }
}
public class GreetingActor extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
int counter = 0;
public void onReceive(Object message) {
if (message instanceof Greeting) {
counter++;
log.info("Hello #" + counter + " " + ((Greeting) message).who);
} else {
unhandled(message);
}
}
}
ActorSystem system = ActorSystem.create("MySystem");
ActorRef greeter = system.actorOf(new Props(GreetingActor.class), "greeter");
greeter.tell(new Greeting("Charlie Parker"), null);
15. Remote Deployment
Just feed the ActorSystem with this configuration
Configure a Remote Provider
akka {
For the Greeter actor {
actor
provider = akka.remote.RemoteActorRefProvider
deployment {
/greeter {
remote = akka://MySystem@machine1:2552
}
}
Define Remote Path
} Protocol Actor System Hostname Port
}
Zero code changes
20. Akka Cluster 2.1
rimental p review in 2.1
Cluster is expe
• Gossip-based Cluster Membership
• Failure Detector
• Cluster DeathWatch
• Cluster-Aware Routers
21. Cluster Membership
• Node ring à la Riak / Dynamo
• Gossip-protocol for state dissemination
• Vector Clocks to detect convergence
22. Node ring with gossiping members
Member
Node
Member Member
Node Node
Member Member
Node Node
Gossip
Member Member
Node Node
Member Member
Node Node
Member
Node
23. Vector Clock
• Vector Clocks are used to:
- Generate a partial ordering of events in
a distributed system
- Detecting causality violations
• We use Vector Clocks to to reconcile and
merge differences in cluster state
24. Gossiping Protocol
Used for:
– Cluster Membership
– Configuration data
– Leader Determination
– Partitioning data
– Naming Service
25. Push/Pull Gossip
• Push
– sender only sends versions (Vector Clock)
• Pull
– receiver only asks for information for which it has
an outdated version
• Partly biased
– send fraction of gossip to nodes with older state
26. Cluster Convergence
• When each Node has seen the same Vector Clock
• unreachable nodes will fail this
• mark nodes DOWN to proceed
– manual Ops intervention
– automatic action
28. Leader
• Any node can be the leader
• Just takes the role of being a leader
• Is deterministically recognized by all nodes
– always the first member in the sorted
membership ring
29. Cluster Events
public class Listener extends UntypedActor {
public void onReceive(Object message) {
if (message instanceof MemberUp) {
// ...
}
}
}
ActorRef listener =
system.actorOf(new Props(Listener.class),
"listener");
Cluster.get(system).subscribe(listener,
MemberEvent.class);
30. Cluster Events
public class Listener extends UntypedActor {
public void onReceive(Object message) {
if (message instanceof MemberUp) {
MemberUp mUp = (MemberUp) message;
getContext().actorFor(mUp.address() +
"/user/greeter").tell(
new Greeting("Charlie Parker"), getSelf());
}
}
}
ActorRef listener =
system.actorOf(new Props(Listener.class),
"listener");
Cluster.get(system).subscribe(listener,
MemberEvent.class);
31. Phi Accrual Failure Detector
regular messages
A B
• B monitors A
• Sample inter-arrival time to expect next beat
• B measures continuum of deadness of A
http://ddg.jaist.ac.jp/pub/HDY+04.pdf
32. Selective Failure Detection
Member
Node
Member Member
Node Node
Member Member
Node Node
Heartbeat
Member Member
Node Node
Member
Member
Node
Member Node
Node
33. Selective Failure Detection
Member
Node
Member Member
Node Node
Member Member
Node Node
Heartbeat
Member Member
Node Node
Member
Member
Node
Member Node
Node
34. Cluster DeathWatch
• Triggered by marking node «A» DOWN
– Tell parents of their lost children on «A»
– Kill all children of actors on «A»
– Send Terminated for actors on «A»
39. Configure a clustered router
akka.actor.deployment {
/statsService/workerRouter {
router = consistent-hashing
nr-of-instances = 100
cluster {
enabled = on
max-nr-of-instances-per-node = 3
allow-local-routees = on
}
}
}
40. Multi Node Testing
object MultiNodeSampleConfig extends MultiNodeConfig {
val node1 = role("node1")
val node2 = role("node2")
}
"A MultiNodeSample" must {
"wait for all nodes to enter a barrier" in {
enterBarrier("startup")
}
}
41. Multi Node Testing
"send to and receive from a remote node" in {
runOn(node1) {
enterBarrier("deployed")
val ponger =
system.actorFor(node(node2) / "user" / "ponger")
ponger ! "ping"
expectMsg("pong")
}
runOn(node2) {
system.actorOf(Props(new Actor {
def receive = {
case "ping" => sender ! "pong"
}
}), "ponger")
enterBarrier("deployed")
}
43. Adaptive Load Balancing
• Metrics collected and spread
– Heap memory
– CPU, system load
• Adaptive Router
– Biased random with weights based on capacity
44. One tree to rule them all
• One Actor tree per node
• Cluster tree is mapped to local sub-trees
46. The Magic Sauce
• User code only sees cluster://... names
• ActorRef becomes repointable
– local
– remote
• Can now move actors around transparently
– Actor encapsulation makes it possible
47. What does this enable?
• Actor migration
• Actor replication
• Automatic cluster partitioning
– later also based on runtime metrics
• Node fail-over
– first for stateless actors
– later for stateful actors using event sourcing
➾ Fault Tolerance & Distribution