Akka: Distributed by Design

4,154 views

Published on

0 Comments
13 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,154
On SlideShare
0
From Embeds
0
Number of Embeds
40
Actions
Shares
0
Downloads
166
Comments
0
Likes
13
Embeds 0
No embeds

No notes for slide

Akka: Distributed by Design

  1. 1. Distributed by Design Patrik Nordwall @patriknw
  2. 2. outline actors remote actors rise of the clusterwhen the cluster grows up
  3. 3. What is an Actor?• Akkas 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
  4. 4. Event-driven Thread Actor Behavior State
  5. 5. Define Actor Define the message(s) the Actor should be able to respond topublic 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. 6. Create Actorpublic 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. 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. 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. 9. Send Messagepublic 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. 10. Full examplepublic 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);
  11. 11. Distributa ble by Design
  12. 12. Node 1 Node 2ErrorKernel
  13. 13. Create ActorActorRef greeter = system.actorOf(new Props( GreetingActor.class), "greeter");
  14. 14. 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
  15. 15. Remote LookupActorRef greeter = system.actorFor( "akka://MySystem@machine1:2552/user/greeter" );
  16. 16. Can you see the problem?
  17. 17. Fixed Addressesakka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = akka://MySystem@machine1:2552 } } }}ActorRef greeter = system.actorFor( "akka://MySystem@machine1:2552/user/greeter" );
  18. 18. Akka Cluster
  19. 19. Akka Cluster 2.1 rimental p review in 2.1 Cluster is expe• Gossip-based Cluster Membership• Failure Detector• Cluster DeathWatch• Cluster-Aware Routers
  20. 20. Cluster Membership• Node ring à la Riak / Dynamo• Gossip-protocol for state dissemination• Vector Clocks to detect convergence
  21. 21. 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
  22. 22. 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
  23. 23. Gossiping Protocol Used for: – Cluster Membership – Configuration data – Leader Determination – Partitioning data – Naming Service
  24. 24. 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
  25. 25. 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
  26. 26. Member States• JOINING• UP• LEAVING• EXITING• DOWN• REMOVED
  27. 27. 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
  28. 28. Cluster Eventspublic 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);
  29. 29. Cluster Eventspublic 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);
  30. 30. 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
  31. 31. Selective Failure Detection Member Node Member Member Node Node Member Member Node Node HeartbeatMember Member Node Node Member Member Node Member Node Node
  32. 32. Selective Failure Detection Member Node Member Member Node Node Member Member Node Node HeartbeatMember Member Node Node Member Member Node Member Node Node
  33. 33. 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»
  34. 34. Enable clusteringakka { actor { provider = "akka.cluster.ClusterActorRefProvider" ... }  extensions = ["akka.cluster.Cluster"]  cluster { seed-nodes = [ "akka://ClusterSystem@127.0.0.1:2551", "akka://ClusterSystem@127.0.0.1:2552" ] }}
  35. 35. Load Balancing
  36. 36. RoutersActorRef routerActor = getContext().actorOf( new Props(ExampleActor.class). withRouter(new RoundRobinRouter(nrOfInstances)) );
  37. 37. …or from config akka.actor.deployment { /path/to/actor { router = round-robin nr-of-instances = 5 } }
  38. 38. 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 } } }
  39. 39. 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") }}
  40. 40. 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") }
  41. 41. … when the Cluster grows up
  42. 42. Adaptive Load Balancing• Metrics collected and spread – Heap memory – CPU, system load• Adaptive Router – Biased random with weights based on capacity
  43. 43. One tree to rule them all • One Actor tree per node • Cluster tree is mapped to local sub-trees
  44. 44. One tree to rule them all
  45. 45. 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
  46. 46. 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
  47. 47. Cluster Specification doc.akka.io/docs/akka/snapshot/cluster/cluster.html Cluster User Guidedoc.akka.io/docs/akka/snapshot/cluster/cluster-usage-scala.htmldoc.akka.io/docs/akka/snapshot/cluster/cluster-usage-java.html Cluster Code github.com/akka/akka/tree/master/akka-cluster
  48. 48. get it and learn more http://akka.io http://letitcrash.com http://typesafe.com
  49. 49. E0F

×