akka: distributed by design
TRANSCRIPT
![Page 1: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/1.jpg)
Patrik Nordwall@patriknw
Distributed by Design
![Page 2: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/2.jpg)
actorsremote actors
rise of the clusterwhen the cluster grows up
outline
![Page 3: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/3.jpg)
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
![Page 4: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/4.jpg)
Event-drivenThread
Event-drivenThread
Behavior
State
Actor
![Page 5: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/5.jpg)
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);}
}}
Define ActorDefine the message(s) the Actor
should be able to respond to
Define the Actor class
Define the Actor’s behavior
![Page 6: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/6.jpg)
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");
Create Actor
Create an Actor system
Create the Actor
Actor configuration
Give it a nameYou get an ActorRef back
![Page 7: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/7.jpg)
A
B
BarFoo
C
B E
A
D
C
Guardian System Actor
system.actorOf( new Props(Foo.class), “Foo”);
getContext().actorOf( new Props(A.class), “A”);
Actors can form hierarchies
![Page 8: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/8.jpg)
A
B
BarFoo
C
B E
A
D
C
/Foo
/Foo/A
/Foo/A/B
/Foo/A/D
Guardian System Actor
Name resolution - like a file-system
![Page 9: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/9.jpg)
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 Message
Send the message
![Page 10: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/10.jpg)
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);
Full example
![Page 11: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/11.jpg)
Distributableby Design
![Page 12: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/12.jpg)
![Page 13: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/13.jpg)
ErrorKernel
Node 1 Node 2
![Page 14: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/14.jpg)
Create Actor
ActorRef greeter = system.actorOf(new Props( GreetingActor.class), "greeter");
![Page 15: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/15.jpg)
akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = } } }}
Just feed the ActorSystem with this configuration
Zero code changes
Configure a Remote Provider
Define Remote Path Protocol Actor System Hostname Port
For the Greeter actor
akka://MySystem@machine1:2552
Remote Deployment
![Page 16: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/16.jpg)
Remote Lookup
ActorRef greeter = system.actorFor( "akka://MySystem@machine1:2552/user/greeter" );
![Page 17: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/17.jpg)
Can you see the problem?
![Page 18: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/18.jpg)
Fixed Addresses
ActorRef greeter = system.actorFor( "akka://MySystem@machine1:2552/user/greeter" );
akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = akka://MySystem@machine1:2552
} } }}
![Page 19: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/19.jpg)
Akka Cluster
![Page 20: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/20.jpg)
Akka Cluster 2.1
• Gossip-based Cluster Membership
• Failure Detector
• Cluster DeathWatch
• Cluster-Aware Routers
Cluster is experimental preview in 2.1
![Page 21: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/21.jpg)
Cluster Membership
• Node ring à la Riak / Dynamo
• Gossip-protocol for state dissemination
• Vector Clocks to detect convergence
![Page 22: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/22.jpg)
Node ring with gossiping members
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
Gossip
![Page 23: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/23.jpg)
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
![Page 24: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/24.jpg)
Gossiping Protocol
Used for :– Cluster Membership– Configuration data– Leader Determination– Partitioning data– Naming Service
![Page 25: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/25.jpg)
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
![Page 26: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/26.jpg)
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
![Page 27: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/27.jpg)
Member States
• JOINING
• UP
• LEAVING
• EXITING
• DOWN
• REMOVED
![Page 28: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/28.jpg)
• 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
Leader
![Page 29: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/29.jpg)
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);
![Page 30: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/30.jpg)
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);
![Page 31: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/31.jpg)
Phi Accrual Failure Detector
• B monitors A
• Sample inter-arrival time to expect next beat
• B measures continuum of deadness of A
A Bregular messages
http://ddg.jaist.ac.jp/pub/HDY+04.pdf
![Page 32: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/32.jpg)
Selective Failure Detection
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
Heartbeat
![Page 33: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/33.jpg)
Selective Failure Detection
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
MemberNode
Heartbeat
![Page 34: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/34.jpg)
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»
![Page 35: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/35.jpg)
Enable clusteringakka { actor { provider = "akka.cluster.ClusterActorRefProvider" ... } extensions = ["akka.cluster.Cluster"] cluster { seed-nodes = [ "akka://[email protected]:2551", "akka://[email protected]:2552" ] }}
![Page 36: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/36.jpg)
Load Balancing
![Page 37: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/37.jpg)
Routers
ActorRef routerActor = getContext().actorOf( new Props(ExampleActor.class). withRouter(new RoundRobinRouter(nrOfInstances)) );
![Page 38: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/38.jpg)
…or from config
akka.actor.deployment { /path/to/actor { router = round-robin nr-of-instances = 5 } }
![Page 39: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/39.jpg)
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 } }}
![Page 40: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/40.jpg)
Multi Node Testingobject 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") }
}
![Page 41: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/41.jpg)
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") }
![Page 42: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/42.jpg)
… when the Cluster grows up
![Page 43: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/43.jpg)
Adaptive Load Balancing
• Metrics collected and spread– Heap memory– CPU, system load
• Adaptive Router– Biased random with weights based on capacity
![Page 44: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/44.jpg)
One tree to rule them all
• One Actor tree per node
• Cluster tree is mapped to local sub-trees
![Page 45: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/45.jpg)
One tree to rule them all
![Page 46: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/46.jpg)
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
![Page 47: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/47.jpg)
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
![Page 48: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/48.jpg)
doc.akka.io/docs/akka/snapshot/cluster/cluster.html
Cluster Specification
doc.akka.io/docs/akka/snapshot/cluster/cluster-usage-scala.htmldoc.akka.io/docs/akka/snapshot/cluster/cluster-usage-java.html
Cluster User Guide
github.com/akka/akka/tree/master/akka-cluster
Cluster Code
![Page 49: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/49.jpg)
get it and learn morehttp://akka.io
http://typesafe.com
http://letitcrash.com
![Page 50: Akka: Distributed by Design](https://reader034.vdocuments.net/reader034/viewer/2022052321/5549aa9db4c9050c708b56f6/html5/thumbnails/50.jpg)
E0F