Akka: Distributed by Design
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
3,436
On Slideshare
3,422
From Embeds
14
Number of Embeds
1

Actions

Shares
Downloads
136
Comments
0
Likes
10

Embeds 14

https://twitter.com 14

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Distributed by Design Patrik Nordwall @patriknw
  • 2. outline actors remote actors rise of the clusterwhen the cluster grows up
  • 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. Event-driven Thread Actor Behavior State
  • 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. 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. 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 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. 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. Distributa ble by Design
  • 12. Node 1 Node 2ErrorKernel
  • 13. Create ActorActorRef greeter = system.actorOf(new Props( GreetingActor.class), "greeter");
  • 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. Remote LookupActorRef greeter = system.actorFor( "akka://MySystem@machine1:2552/user/greeter" );
  • 16. Can you see the problem?
  • 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. Akka Cluster
  • 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. Cluster Membership• Node ring à la Riak / Dynamo• Gossip-protocol for state dissemination• Vector Clocks to detect convergence
  • 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. 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. Gossiping Protocol Used for: – Cluster Membership – Configuration data – Leader Determination – Partitioning data – Naming Service
  • 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. 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. Member States• JOINING• UP• LEAVING• EXITING• DOWN• REMOVED
  • 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. 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. 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. 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. Selective Failure Detection Member Node Member Member Node Node Member Member Node Node HeartbeatMember Member Node Node Member Member Node Member Node Node
  • 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. 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. 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. Load Balancing
  • 36. RoutersActorRef routerActor = getContext().actorOf( new Props(ExampleActor.class). withRouter(new RoundRobinRouter(nrOfInstances)) );
  • 37. …or from config akka.actor.deployment { /path/to/actor { router = round-robin nr-of-instances = 5 } }
  • 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. 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. 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. … when the Cluster grows up
  • 42. Adaptive Load Balancing• Metrics collected and spread – Heap memory – CPU, system load• Adaptive Router – Biased random with weights based on capacity
  • 43. One tree to rule them all • One Actor tree per node • Cluster tree is mapped to local sub-trees
  • 44. One tree to rule them all
  • 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. 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. 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. get it and learn more http://akka.io http://letitcrash.com http://typesafe.com
  • 49. E0F