118
Dr. Roland Kuhn @rolandkuhn Distributed by Design onsdag 3 april 13

Akka cluster overview at 010dev

Embed Size (px)

Citation preview

Page 1: Akka cluster overview at 010dev

Dr. Roland Kuhn@rolandkuhn

Distributed by Design

onsdag 3 april 13

Page 2: Akka cluster overview at 010dev

actorsremote actors

rise of the clusterwhen the cluster grows up

adding types

outline

onsdag 3 april 13

Page 3: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 4: Akka cluster overview at 010dev

Behavior

State

Actor

onsdag 3 april 13

Page 5: Akka cluster overview at 010dev

Event-drivenThread

Behavior

State

Actor

onsdag 3 april 13

Page 6: Akka cluster overview at 010dev

Event-drivenThread

Behavior

State

Actor

onsdag 3 april 13

Page 7: Akka cluster overview at 010dev

Event-drivenThread

Behavior

State

Actor

onsdag 3 april 13

Page 8: Akka cluster overview at 010dev

Event-drivenThread

Behavior

State

Actor

onsdag 3 april 13

Page 9: Akka cluster overview at 010dev

Behavior

State

Actor

onsdag 3 april 13

Page 10: Akka cluster overview at 010dev

Event-drivenThread

Behavior

State

Actor

onsdag 3 april 13

Page 11: Akka cluster overview at 010dev

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 Actor

onsdag 3 april 13

Page 12: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 13: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 14: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 15: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 16: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 17: Akka cluster overview at 010dev

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 systemActor configuration

onsdag 3 april 13

Page 18: Akka cluster overview at 010dev

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 systemActor configuration

Give it a name

onsdag 3 april 13

Page 19: Akka cluster overview at 010dev

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 name

onsdag 3 april 13

Page 20: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 21: Akka cluster overview at 010dev

Guardian System Actor

Actors can form hierarchies

onsdag 3 april 13

Page 22: Akka cluster overview at 010dev

Guardian System Actor

system.actorOf( new Props(Foo.class), “Foo”);

Actors can form hierarchies

onsdag 3 april 13

Page 23: Akka cluster overview at 010dev

Foo

Guardian System Actor

system.actorOf( new Props(Foo.class), “Foo”);

Actors can form hierarchies

onsdag 3 april 13

Page 24: Akka cluster overview at 010dev

Foo

Guardian System Actor

getContext().actorOf( new Props(A.class), “A”);

Actors can form hierarchies

onsdag 3 april 13

Page 25: Akka cluster overview at 010dev

A

Foo

Guardian System Actor

getContext().actorOf( new Props(A.class), “A”);

Actors can form hierarchies

onsdag 3 april 13

Page 26: Akka cluster overview at 010dev

A

B

BarFoo

C

B E

A

D

C

Guardian System Actor

Actors can form hierarchies

onsdag 3 april 13

Page 27: Akka cluster overview at 010dev

A

B

BarFoo

C

B E

A

D

C

Guardian System Actor

Name resolution - like a file-system

onsdag 3 april 13

Page 28: Akka cluster overview at 010dev

A

B

BarFoo

C

B E

A

D

C

/Foo

Guardian System Actor

Name resolution - like a file-system

onsdag 3 april 13

Page 29: Akka cluster overview at 010dev

A

B

BarFoo

C

B E

A

D

C

/Foo

/Foo/A

Guardian System Actor

Name resolution - like a file-system

onsdag 3 april 13

Page 30: Akka cluster overview at 010dev

A

B

BarFoo

C

B E

A

D

C

/Foo

/Foo/A

/Foo/A/B

Guardian System Actor

Name resolution - like a file-system

onsdag 3 april 13

Page 31: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 32: Akka cluster overview at 010dev

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);

onsdag 3 april 13

Page 33: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 34: Akka cluster overview at 010dev

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);

Full example

onsdag 3 april 13

Page 35: Akka cluster overview at 010dev

Distributableby Design

onsdag 3 april 13

Page 36: Akka cluster overview at 010dev

onsdag 3 april 13

Page 37: Akka cluster overview at 010dev

ErrorKernel

onsdag 3 april 13

Page 38: Akka cluster overview at 010dev

ErrorKernel

Node 1 Node 2

onsdag 3 april 13

Page 39: Akka cluster overview at 010dev

Create Actor

ActorRef greeter = system.actorOf(new Props( GreetingActor.class), "greeter");

onsdag 3 april 13

Page 40: Akka cluster overview at 010dev

akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = } } }}

Just feed the ActorSystem with this configuration

Remote Deployment

onsdag 3 april 13

Page 41: Akka cluster overview at 010dev

akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = } } }}

Just feed the ActorSystem with this configuration

Configure a Remote Provider

Remote Deployment

onsdag 3 april 13

Page 42: Akka cluster overview at 010dev

akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = } } }}

Just feed the ActorSystem with this configuration

Configure a Remote Provider

For the Greeter actor

Remote Deployment

onsdag 3 april 13

Page 43: Akka cluster overview at 010dev

akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = } } }}

Just feed the ActorSystem with this configuration

Configure a Remote Provider

Define Remote Path

For the Greeter actor

Remote Deployment

onsdag 3 april 13

Page 44: Akka cluster overview at 010dev

akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = } } }}

Just feed the ActorSystem with this configuration

Configure a Remote Provider

Define Remote Path Protocol

For the Greeter actor

akka://

Remote Deployment

onsdag 3 april 13

Page 45: Akka cluster overview at 010dev

akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = } } }}

Just feed the ActorSystem with this configuration

Configure a Remote Provider

Define Remote Path Protocol Actor System

For the Greeter actor

akka://MySystem

Remote Deployment

onsdag 3 april 13

Page 46: Akka cluster overview at 010dev

akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = } } }}

Just feed the ActorSystem with this configuration

Configure a Remote Provider

Define Remote Path Protocol Actor System Hostname

For the Greeter actor

akka://MySystem@machine1

Remote Deployment

onsdag 3 april 13

Page 47: Akka cluster overview at 010dev

akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = } } }}

Just feed the ActorSystem with this configuration

Configure a Remote Provider

Define Remote Path Protocol Actor System Hostname Port

For the Greeter actor

akka://MySystem@machine1:2552

Remote Deployment

onsdag 3 april 13

Page 48: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 49: Akka cluster overview at 010dev

Remote Lookup

ActorRef greeter = system.actorFor( "akka://MySystem@machine1:2552/user/greeter" );

onsdag 3 april 13

Page 50: Akka cluster overview at 010dev

Can you see the problem?

onsdag 3 april 13

Page 51: Akka cluster overview at 010dev

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

} } }}

onsdag 3 april 13

Page 52: Akka cluster overview at 010dev

Akka Cluster

onsdag 3 april 13

Page 53: Akka cluster overview at 010dev

Akka Cluster 2.1

• Gossip-based Cluster Membership

• Failure Detector

• Cluster DeathWatch

• Cluster-Aware Routers

Cluster is experim

ental preview in 2.1

onsdag 3 april 13

Page 54: Akka cluster overview at 010dev

Cluster Membership

• Node ring à la Riak / Dynamo

• Gossip-protocol for state dissemination

• Vector Clocks to detect convergence

onsdag 3 april 13

Page 55: Akka cluster overview at 010dev

Node ring with gossiping members

MemberNode

onsdag 3 april 13

Page 56: Akka cluster overview at 010dev

Node ring with gossiping members

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

onsdag 3 april 13

Page 57: Akka cluster overview at 010dev

Node ring with gossiping members

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

onsdag 3 april 13

Page 58: Akka cluster overview at 010dev

Node ring with gossiping members

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

onsdag 3 april 13

Page 59: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 60: Akka cluster overview at 010dev

Gossiping Protocol

onsdag 3 april 13

Page 61: Akka cluster overview at 010dev

Gossiping Protocol

Used for :

onsdag 3 april 13

Page 62: Akka cluster overview at 010dev

Gossiping Protocol

Used for :– Cluster Membership

onsdag 3 april 13

Page 63: Akka cluster overview at 010dev

Gossiping Protocol

Used for :– Cluster Membership– Configuration data

onsdag 3 april 13

Page 64: Akka cluster overview at 010dev

Gossiping Protocol

Used for :– Cluster Membership– Configuration data– Leader Determination

onsdag 3 april 13

Page 65: Akka cluster overview at 010dev

Gossiping Protocol

Used for :– Cluster Membership– Configuration data– Leader Determination– Partitioning data

onsdag 3 april 13

Page 66: Akka cluster overview at 010dev

Gossiping Protocol

Used for :– Cluster Membership– Configuration data– Leader Determination– Partitioning data– Naming Service

onsdag 3 april 13

Page 67: Akka cluster overview at 010dev

Push/Pull Gossip

f u ture opt imizat ion in 2 . 3+• 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

onsdag 3 april 13

Page 68: Akka cluster overview at 010dev

Cluster Convergence

onsdag 3 april 13

Page 69: Akka cluster overview at 010dev

Cluster Convergence

• When each Node has seen the same Vector Clock

onsdag 3 april 13

Page 70: Akka cluster overview at 010dev

Cluster Convergence

• When each Node has seen the same Vector Clock

• unreachable nodes will fail this

onsdag 3 april 13

Page 71: Akka cluster overview at 010dev

Cluster Convergence

• When each Node has seen the same Vector Clock

• unreachable nodes will fail this

• mark nodes DOWN to proceed

onsdag 3 april 13

Page 72: Akka cluster overview at 010dev

Cluster Convergence

• When each Node has seen the same Vector Clock

• unreachable nodes will fail this

• mark nodes DOWN to proceed

– manual Ops intervention

onsdag 3 april 13

Page 73: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 74: Akka cluster overview at 010dev

Member States

onsdag 3 april 13

Page 75: Akka cluster overview at 010dev

Member States

• JOINING

• UP

• LEAVING

• EXITING

• DOWN

• REMOVED

onsdag 3 april 13

Page 76: Akka cluster overview at 010dev

Member States

• JOINING

• UP

• LEAVING

• EXITING

• DOWN

• REMOVED

onsdag 3 april 13

Page 77: Akka cluster overview at 010dev

Leader

onsdag 3 april 13

Page 78: Akka cluster overview at 010dev

• Any node can be the leader

Leader

onsdag 3 april 13

Page 79: Akka cluster overview at 010dev

• Any node can be the leader

• Just takes the role of being a leader

Leader

onsdag 3 april 13

Page 80: Akka cluster overview at 010dev

• Any node can be the leader

• Just takes the role of being a leader

• Is deterministically recognized by all nodes

Leader

onsdag 3 april 13

Page 81: Akka cluster overview at 010dev

• 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

onsdag 3 april 13

Page 82: Akka cluster overview at 010dev

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);

onsdag 3 april 13

Page 83: Akka cluster overview at 010dev

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);

onsdag 3 april 13

Page 84: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 85: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 86: Akka cluster overview at 010dev

Selective Failure Detection

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

Heartbeat

onsdag 3 april 13

Page 87: Akka cluster overview at 010dev

Selective Failure Detection

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

MemberNode

Heartbeat

onsdag 3 april 13

Page 88: Akka cluster overview at 010dev

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»

onsdag 3 april 13

Page 89: Akka cluster overview at 010dev

Enable clusteringakka { actor { provider = "akka.cluster.ClusterActorRefProvider" ... }  extensions = ["akka.cluster.Cluster"]  cluster { seed-nodes = [ "akka://[email protected]:2551", "akka://[email protected]:2552" ] }}

onsdag 3 april 13

Page 90: Akka cluster overview at 010dev

Load Balancingonsdag 3 april 13

Page 91: Akka cluster overview at 010dev

Routers

ActorRef routerActor = getContext().actorOf( new Props(ExampleActor.class). withRouter(new RoundRobinRouter(nrOfInstances)) );

onsdag 3 april 13

Page 92: Akka cluster overview at 010dev

…or from config

akka.actor.deployment { /path/to/actor { router = round-robin nr-of-instances = 5 } }

onsdag 3 april 13

Page 93: Akka cluster overview at 010dev

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 } }}

onsdag 3 april 13

Page 94: Akka cluster overview at 010dev

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") }

}

onsdag 3 april 13

Page 95: Akka cluster overview at 010dev

Multi Node TestingrunOn(node2) { system.actorOf(Props(new Actor { def receive = { case "ping" => sender ! "pong" } }), "ponger")}

enterBarrier("deployed")

runOn(node1) { val ponger = system.actorFor(node(node2) / "user" / "ponger") ponger ! "ping" expectMsg("pong")}

enterBarrier("finished")

onsdag 3 april 13

Page 96: Akka cluster overview at 010dev

… when the Cluster grows up

onsdag 3 april 13

Page 97: Akka cluster overview at 010dev

Adaptive Load Balancing

• Metrics collected and spread– Heap memory– CPU, system load

• Adaptive Router– Biased random with weights based on capacity

onsdag 3 april 13

Page 98: Akka cluster overview at 010dev

One tree to rule them all

• One Actor tree per node

• Cluster tree is mapped to local sub-trees

onsdag 3 april 13

Page 99: Akka cluster overview at 010dev

One tree to rule them all

onsdag 3 april 13

Page 100: Akka cluster overview at 010dev

One tree to rule them all

onsdag 3 april 13

Page 101: Akka cluster overview at 010dev

One tree to rule them all

onsdag 3 april 13

Page 102: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 103: Akka cluster overview at 010dev

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

onsdag 3 april 13

Page 104: Akka cluster overview at 010dev

Typed ChannelsExperimental in 2.2

onsdag 3 april 13

Page 105: Akka cluster overview at 010dev

someActor ! CommandOne

The Problem

onsdag 3 april 13

Page 106: Akka cluster overview at 010dev

trait Commandcase class CommandOne(param: String) extends Command

someActor ! CommandOne

The Problem

onsdag 3 april 13

Page 107: Akka cluster overview at 010dev

because the other does not compile

someActor <-!- CommandOne(”msg”)

The Vision

onsdag 3 april 13

Page 108: Akka cluster overview at 010dev

But How?

• ActorRef must know about message types– Actor type must be parameterized

• Message type is verified against that

onsdag 3 april 13

Page 109: Akka cluster overview at 010dev

val f: Future[Response] =

someActor <-?- CommandOne(”hello”)

because the compiler knows

And the replies?

onsdag 3 april 13

Page 110: Akka cluster overview at 010dev

And How This?

• ActorRef must know reply types– Actor must be parameterized with them

• Reply types are extracted at call site

onsdag 3 april 13

Page 111: Akka cluster overview at 010dev

No Type Pollution

• Generic Filter/Transform Actors– accept management commands– pass on generic other type

• Using just one type is not enough!

• Need to use type unions and allow multiple possible reply types for one input

onsdag 3 april 13

Page 112: Akka cluster overview at 010dev

The Implementation

• Tagged type union with:+:[(In, Out), ChannelList] <: ChannelList

• Value class ChannelRef[…](val a: ActorRef)

• Actor mixin Channels[…]

• WrappedMessage[…, LUB](val m: LUB)

• ops desugar to tell/ask after type check

onsdag 3 april 13

Page 113: Akka cluster overview at 010dev

msg -?-> firstActor -?-> secondActor -!-> client

msg -?-> someService -*-> (_ map httpOk) -!-> client

Process wiring from the outside

Actors Do Compose

onsdag 3 april 13

Page 114: Akka cluster overview at 010dev

class OpinionatedEcho extends Actor with Channels[TNil, (String, String) :+: TNil] {

channel[String] { (str, sender) ⇒ sender <-!- str } // or channel[String] { case (”hello”, sender) ⇒ sender <-!- ”world” case (x, sender) ⇒ sender <-!- s”dunno: $x” }

}

“sender” will accept only String messages

How to Declare it?

onsdag 3 april 13

Page 115: Akka cluster overview at 010dev

The Result:

onsdag 3 april 13

Page 116: Akka cluster overview at 010dev

Type-Safe Composability

of

Actor Systems

onsdag 3 april 13

Page 117: Akka cluster overview at 010dev

get it and learn morehttp://akka.io

http://typesafe.com

http://letitcrash.com

onsdag 3 april 13

Page 118: Akka cluster overview at 010dev

E0Fonsdag 3 april 13