UP UP AND OUT: SCALING SOFTWARE WITH AKKA Jonas Bonr CTO Typesafe - - PowerPoint PPT Presentation

up up and out scaling software with akka
SMART_READER_LITE
LIVE PREVIEW

UP UP AND OUT: SCALING SOFTWARE WITH AKKA Jonas Bonr CTO Typesafe - - PowerPoint PPT Presentation

UP UP AND OUT: SCALING SOFTWARE WITH AKKA Jonas Bonr CTO Typesafe @jboner Scaling software with Jonas Bonr CTO Typesafe @jboner Scaling Scaling software with software with Scaling Scaling software with software with Akka


slide-1
SLIDE 1

UP UP AND OUT: SCALING SOFTWARE WITH AKKA

Jonas Bonér CTO Typesafe @jboner
slide-2
SLIDE 2

Jonas Bonér

CTO Typesafe @jboner

Scaling

software with

slide-3
SLIDE 3

Scaling software with Scaling

software with

slide-4
SLIDE 4

Scaling software with Scaling

software with Akka (Áhkká)

The name comes from the goddess in the Sami (native swedes) mythology that represented all the wisdom and beauty in the world. It is also the name of a beautiful mountain in Laponia in the north part of Sweden
slide-5
SLIDE 5

Scaling software with Scaling

software with

slide-6
SLIDE 6

Manage System Overload

slide-7
SLIDE 7

Scale UP & Scale OUT

slide-8
SLIDE 8

How

can we achieve this?

slide-9
SLIDE 9

How

can we achieve this?

slide-10
SLIDE 10

How

can we achieve this?

Let’s use Actors

slide-11
SLIDE 11

What is an Actor?

slide-12
SLIDE 12

What is an Actor?

slide-13
SLIDE 13

What is an Actor?

  • Akka's unit of code organization is called an Actor
slide-14
SLIDE 14

What is an Actor?

  • Akka's unit of code organization is called an Actor
  • Like Java EE servlets and session beans, Actors is a
model for organizing your code that keeps many “policy decisions” separate from the business logic
slide-15
SLIDE 15

What is an Actor?

  • Akka's unit of code organization is called an Actor
  • Like Java EE servlets and session beans, Actors is a
model for organizing your code that keeps many “policy decisions” separate from the business logic
  • Actors may be new to many in the Java community,
but they are a tried-and-true concept (Hewitt 1973) used for many years in telecom systems with 9 nines uptime
slide-16
SLIDE 16

Program at a Higher Level

slide-17
SLIDE 17

Program at a Higher Level

slide-18
SLIDE 18

Program at a Higher Level

  • Never think in terms of shared state, state
visibility, threads, locks, concurrent collections, thread notifications etc.
slide-19
SLIDE 19

Program at a Higher Level

  • Never think in terms of shared state, state
visibility, threads, locks, concurrent collections, thread notifications etc.
  • Low level concurrency plumbing BECOMES
SIMPLE WORKFLOW - you only think about how messages flow in the system
slide-20
SLIDE 20

Program at a Higher Level

  • Never think in terms of shared state, state
visibility, threads, locks, concurrent collections, thread notifications etc.
  • Low level concurrency plumbing BECOMES
SIMPLE WORKFLOW - you only think about how messages flow in the system
  • You get high CPU utilization, low latency, high
throughput and scalability - FOR FREE as part of the model
slide-21
SLIDE 21

Program at a Higher Level

  • Never think in terms of shared state, state
visibility, threads, locks, concurrent collections, thread notifications etc.
  • Low level concurrency plumbing BECOMES
SIMPLE WORKFLOW - you only think about how messages flow in the system
  • You get high CPU utilization, low latency, high
throughput and scalability - FOR FREE as part of the model
  • Proven and superior model for detecting and
recovering from errors
slide-22
SLIDE 22

Distributable by Design

slide-23
SLIDE 23

Distributable by Design

slide-24
SLIDE 24

Distributable by Design

  • Actors are location transparent & distributable by design
slide-25
SLIDE 25

Distributable by Design

  • Actors are location transparent & distributable by design
  • Scale UP and OUT for free as part of the model
slide-26
SLIDE 26

Distributable by Design

  • Actors are location transparent & distributable by design
  • Scale UP and OUT for free as part of the model
  • You get the PERFECT FABRIC for the CLOUD
slide-27
SLIDE 27

Distributable by Design

  • Actors are location transparent & distributable by design
  • Scale UP and OUT for free as part of the model
  • You get the PERFECT FABRIC for the CLOUD
  • elastic & dynamic
slide-28
SLIDE 28

Distributable by Design

  • Actors are location transparent & distributable by design
  • Scale UP and OUT for free as part of the model
  • You get the PERFECT FABRIC for the CLOUD
  • elastic & dynamic
  • fault-tolerant & self-healing
slide-29
SLIDE 29

Distributable by Design

  • Actors are location transparent & distributable by design
  • Scale UP and OUT for free as part of the model
  • You get the PERFECT FABRIC for the CLOUD
  • elastic & dynamic
  • fault-tolerant & self-healing
  • adaptive load-balancing, cluster rebalancing & actor migration
slide-30
SLIDE 30

Distributable by Design

  • Actors are location transparent & distributable by design
  • Scale UP and OUT for free as part of the model
  • You get the PERFECT FABRIC for the CLOUD
  • elastic & dynamic
  • fault-tolerant & self-healing
  • adaptive load-balancing, cluster rebalancing & actor migration
  • build extremely loosely coupled and dynamic systems that can
change and adapt at runtime
slide-31
SLIDE 31

Selection of Akka Production Users

slide-32
SLIDE 32
slide-33
SLIDE 33

What can I use Actors for?

slide-34
SLIDE 34

What can I use Actors for?

In different scenarios, an Actor may be an alternative to:

slide-35
SLIDE 35

What can I use Actors for?

In different scenarios, an Actor may be an alternative to:

  • a thread
slide-36
SLIDE 36

What can I use Actors for?

In different scenarios, an Actor may be an alternative to:

  • a thread
  • an object instance or component
slide-37
SLIDE 37

What can I use Actors for?

In different scenarios, an Actor may be an alternative to:

  • a thread
  • an object instance or component
  • a callback or listener
slide-38
SLIDE 38

What can I use Actors for?

In different scenarios, an Actor may be an alternative to:

  • a thread
  • an object instance or component
  • a callback or listener
  • a singleton or service
slide-39
SLIDE 39

What can I use Actors for?

In different scenarios, an Actor may be an alternative to:

  • a thread
  • an object instance or component
  • a callback or listener
  • a singleton or service
  • a router, load-balancer or pool
slide-40
SLIDE 40

What can I use Actors for?

In different scenarios, an Actor may be an alternative to:

  • a thread
  • an object instance or component
  • a callback or listener
  • a singleton or service
  • a router, load-balancer or pool
  • a Java EE Session Bean or Message-Driven Bean
slide-41
SLIDE 41

What can I use Actors for?

In different scenarios, an Actor may be an alternative to:

  • a thread
  • an object instance or component
  • a callback or listener
  • a singleton or service
  • a router, load-balancer or pool
  • a Java EE Session Bean or Message-Driven Bean
  • an out-of-process service
slide-42
SLIDE 42

What can I use Actors for?

In different scenarios, an Actor may be an alternative to:

  • a thread
  • an object instance or component
  • a callback or listener
  • a singleton or service
  • a router, load-balancer or pool
  • a Java EE Session Bean or Message-Driven Bean
  • an out-of-process service
  • a Finite State Machine (FSM)
slide-43
SLIDE 43

So, what is the

Actor Model?

slide-44
SLIDE 44

Carl Hewitt’s definition

http://bit.ly/hewitt-on-actors

slide-45
SLIDE 45

Carl Hewitt’s definition

http://bit.ly/hewitt-on-actors

  • The fundamental unit of computation that embodies:
slide-46
SLIDE 46

Carl Hewitt’s definition

http://bit.ly/hewitt-on-actors

  • The fundamental unit of computation that embodies:
  • Processing
slide-47
SLIDE 47

Carl Hewitt’s definition

http://bit.ly/hewitt-on-actors

  • The fundamental unit of computation that embodies:
  • Processing
  • Storage
slide-48
SLIDE 48

Carl Hewitt’s definition

http://bit.ly/hewitt-on-actors

  • The fundamental unit of computation that embodies:
  • Processing
  • Storage
  • Communication
slide-49
SLIDE 49

Carl Hewitt’s definition

http://bit.ly/hewitt-on-actors

  • The fundamental unit of computation that embodies:
  • Processing
  • Storage
  • Communication
  • 3 axioms - When an Actor receives a message it can:
slide-50
SLIDE 50

Carl Hewitt’s definition

http://bit.ly/hewitt-on-actors

  • The fundamental unit of computation that embodies:
  • Processing
  • Storage
  • Communication
  • 3 axioms - When an Actor receives a message it can:
  • Create new Actors
slide-51
SLIDE 51

Carl Hewitt’s definition

http://bit.ly/hewitt-on-actors

  • The fundamental unit of computation that embodies:
  • Processing
  • Storage
  • Communication
  • 3 axioms - When an Actor receives a message it can:
  • Create new Actors
  • Send messages to Actors it knows
slide-52
SLIDE 52

Carl Hewitt’s definition

http://bit.ly/hewitt-on-actors

  • The fundamental unit of computation that embodies:
  • Processing
  • Storage
  • Communication
  • 3 axioms - When an Actor receives a message it can:
  • Create new Actors
  • Send messages to Actors it knows
  • Designate how it should handle the next message it receives
slide-53
SLIDE 53

4 core Actor operations

  • 0. DEFINE
  • 1. CREATE
  • 2. SEND
  • 3. BECOME
  • 4. SUPERVISE
slide-54
SLIDE 54 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((Greeting) message).who); } } }
  • 0. DEFINE
slide-55
SLIDE 55 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((Greeting) message).who); } } }
  • 0. DEFINE
Define the message(s) the Actor should be able to respond to
slide-56
SLIDE 56 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((Greeting) message).who); } } }
  • 0. DEFINE
Define the message(s) the Actor should be able to respond to Define the Actor class
slide-57
SLIDE 57 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((Greeting) message).who); } } }
  • 0. DEFINE
Define the message(s) the Actor should be able to respond to Define the Actor class Define the Actor’s behavior
slide-58
SLIDE 58
  • 1. CREATE
  • CREATE - creates a new instance of an Actor
  • Extremely lightweight (2.7 Million per Gb RAM)
  • Very strong encapsulation - encapsulates:
  • state
  • behavior
  • message queue
  • State & behavior is indistinguishable from each other
  • Only way to observe state is by sending an actor a

message and see how it reacts

slide-59
SLIDE 59 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((Greeting) message).who); } } } ActorSystem system = ActorSystem.create("MySystem"); ActorRef greeter = system.actorOf(new Props(GreetingActor.class), "greeter");

CREATE Actor

slide-60
SLIDE 60 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((Greeting) message).who); } } } ActorSystem system = ActorSystem.create("MySystem"); ActorRef greeter = system.actorOf(new Props(GreetingActor.class), "greeter");

CREATE Actor

Create an Actor system
slide-61
SLIDE 61 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((Greeting) message).who); } } } ActorSystem system = ActorSystem.create("MySystem"); ActorRef greeter = system.actorOf(new Props(GreetingActor.class), "greeter");

CREATE Actor

Create an Actor system Actor configuration
slide-62
SLIDE 62 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((Greeting) message).who); } } } ActorSystem system = ActorSystem.create("MySystem"); ActorRef greeter = system.actorOf(new Props(GreetingActor.class), "greeter");

CREATE Actor

Create an Actor system Actor configuration Give it a name
slide-63
SLIDE 63 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((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
slide-64
SLIDE 64 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((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 You get an ActorRef back
slide-65
SLIDE 65 Guardian System Actor

Actors can form hierarchies

slide-66
SLIDE 66 Guardian System Actor system.actorOf(Props[Foo], “Foo”)

Actors can form hierarchies

slide-67
SLIDE 67 Foo Guardian System Actor system.actorOf(Props[Foo], “Foo”)

Actors can form hierarchies

slide-68
SLIDE 68 Foo Guardian System Actor context.actorOf(Props[A], “A”)

Actors can form hierarchies

slide-69
SLIDE 69 A Foo Guardian System Actor context.actorOf(Props[A], “A”)

Actors can form hierarchies

slide-70
SLIDE 70 A B Bar Foo C B E A D C Guardian System Actor

Actors can form hierarchies

slide-71
SLIDE 71 A B Bar Foo C B E A D C Guardian System Actor

Name resolution - like a file-system

slide-72
SLIDE 72 A B Bar Foo C B E A D C /Foo Guardian System Actor

Name resolution - like a file-system

slide-73
SLIDE 73 A B Bar Foo C B E A D C /Foo /Foo/A Guardian System Actor

Name resolution - like a file-system

slide-74
SLIDE 74 A B Bar Foo C B E A D C /Foo /Foo/A /Foo/A/B Guardian System Actor

Name resolution - like a file-system

slide-75
SLIDE 75 A B Bar Foo C B E A D C /Foo /Foo/A /Foo/A/B /Foo/A/D Guardian System Actor

Name resolution - like a file-system

slide-76
SLIDE 76
  • 2. SEND
slide-77
SLIDE 77
  • 2. SEND
  • SEND - sends a message to an Actor
slide-78
SLIDE 78
  • 2. SEND
  • SEND - sends a message to an Actor
  • Asynchronous and Non-blocking - Fire-forget
slide-79
SLIDE 79
  • 2. SEND
  • SEND - sends a message to an Actor
  • Asynchronous and Non-blocking - Fire-forget
  • EVERYTHING is asynchronous and lockless
slide-80
SLIDE 80
  • 2. SEND
  • SEND - sends a message to an Actor
  • Asynchronous and Non-blocking - Fire-forget
  • EVERYTHING is asynchronous and lockless
  • Everything happens REACTIVELY
slide-81
SLIDE 81
  • 2. SEND
  • SEND - sends a message to an Actor
  • Asynchronous and Non-blocking - Fire-forget
  • EVERYTHING is asynchronous and lockless
  • Everything happens REACTIVELY
  • An Actor is passive until a message is sent to it,
which triggers something within the Actor
slide-82
SLIDE 82
  • 2. SEND
  • SEND - sends a message to an Actor
  • Asynchronous and Non-blocking - Fire-forget
  • EVERYTHING is asynchronous and lockless
  • Everything happens REACTIVELY
  • An Actor is passive until a message is sent to it,
which triggers something within the Actor
  • Messages is the Kinetic Energy in an Actor system
slide-83
SLIDE 83
  • 2. SEND
  • SEND - sends a message to an Actor
  • Asynchronous and Non-blocking - Fire-forget
  • EVERYTHING is asynchronous and lockless
  • Everything happens REACTIVELY
  • An Actor is passive until a message is sent to it,
which triggers something within the Actor
  • Messages is the Kinetic Energy in an Actor system
  • Actors can have lots of buffered Potential Energy
but can't do anything with it until it is triggered by a message
slide-84
SLIDE 84 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((Greeting) message).who); } } } ActorSystem system = ActorSystem.create("MySystem"); ActorRef greeter = system.actorOf(new Props(GreetingActor.class), "greeter"); greeter.tell(new Greeting("Charlie Parker"));

SEND message

slide-85
SLIDE 85 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((Greeting) message).who); } } } ActorSystem system = ActorSystem.create("MySystem"); ActorRef greeter = system.actorOf(new Props(GreetingActor.class), "greeter"); greeter.tell(new Greeting("Charlie Parker"));

SEND message

Send the message
slide-86
SLIDE 86 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); public void onReceive(Object message) throws Exception { if (message instanceof Greeting) log.info("Hello " + ((Greeting) message).who); } } } ActorSystem system = ActorSystem.create("MySystem"); ActorRef greeter = system.actorOf(new Props(GreetingActor.class), "greeter"); greeter.tell(new Greeting("Charlie Parker"));

Full example

slide-87
SLIDE 87 akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = } } } }

Just feed the ActorSystem with this configuration

Remote deployment

slide-88
SLIDE 88 akka { actor { provider = akka.remote.RemoteActorRefProvider deployment { /greeter { remote = } } } }

Just feed the ActorSystem with this configuration

Configure a Remote Provider

Remote deployment

slide-89
SLIDE 89 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

slide-90
SLIDE 90 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

slide-91
SLIDE 91 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

slide-92
SLIDE 92 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

slide-93
SLIDE 93 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

slide-94
SLIDE 94 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

slide-95
SLIDE 95 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

slide-96
SLIDE 96
  • 3. BECOME
slide-97
SLIDE 97
  • 3. BECOME
  • BECOME - dynamically redefines Actor’s behavior
slide-98
SLIDE 98
  • 3. BECOME
  • BECOME - dynamically redefines Actor’s behavior
  • Triggered reactively by receive of message
slide-99
SLIDE 99
  • 3. BECOME
  • BECOME - dynamically redefines Actor’s behavior
  • Triggered reactively by receive of message
  • In a type system analogy it is as if the object changed

type - changed interface, protocol & implementation

slide-100
SLIDE 100
  • 3. BECOME
  • BECOME - dynamically redefines Actor’s behavior
  • Triggered reactively by receive of message
  • In a type system analogy it is as if the object changed

type - changed interface, protocol & implementation

  • Will now react differently to the messages it receives
slide-101
SLIDE 101
  • 3. BECOME
  • BECOME - dynamically redefines Actor’s behavior
  • Triggered reactively by receive of message
  • In a type system analogy it is as if the object changed

type - changed interface, protocol & implementation

  • Will now react differently to the messages it receives
  • Behaviors are stacked & can be pushed and popped
slide-102
SLIDE 102

Why would I want to do that?

slide-103
SLIDE 103

Why would I want to do that?

  • Let a highly contended Actor adaptively transform

himself into an Actor Pool or a Router

slide-104
SLIDE 104

Why would I want to do that?

  • Let a highly contended Actor adaptively transform

himself into an Actor Pool or a Router

  • Implement an FSM (Finite State Machine)
slide-105
SLIDE 105

Why would I want to do that?

  • Let a highly contended Actor adaptively transform

himself into an Actor Pool or a Router

  • Implement an FSM (Finite State Machine)
  • Implement graceful degradation
slide-106
SLIDE 106

Why would I want to do that?

  • Let a highly contended Actor adaptively transform

himself into an Actor Pool or a Router

  • Implement an FSM (Finite State Machine)
  • Implement graceful degradation
  • Spawn up (empty) generic Worker processes that

can become whatever the Master currently needs

slide-107
SLIDE 107

Why would I want to do that?

  • Let a highly contended Actor adaptively transform

himself into an Actor Pool or a Router

  • Implement an FSM (Finite State Machine)
  • Implement graceful degradation
  • Spawn up (empty) generic Worker processes that

can become whatever the Master currently needs

  • etc. use your imagination
slide-108
SLIDE 108

Why would I want to do that?

  • Let a highly contended Actor adaptively transform

himself into an Actor Pool or a Router

  • Implement an FSM (Finite State Machine)
  • Implement graceful degradation
  • Spawn up (empty) generic Worker processes that

can become whatever the Master currently needs

  • etc. use your imagination
  • Very useful once you get the used to it
slide-109
SLIDE 109

become

context.become(new Procedure[Object]() { void apply(Object msg) { // new body if (msg instanceof NewMessage) { NewMessage newMsg = (NewMessage)msg; ... } } });
slide-110
SLIDE 110

become

context.become(new Procedure[Object]() { void apply(Object msg) { // new body if (msg instanceof NewMessage) { NewMessage newMsg = (NewMessage)msg; ... } } }); Actor context available from within an Actor
slide-111
SLIDE 111

Load Balancing

slide-112
SLIDE 112

Routers

ActorRef router = system.actorOf( new Props(SomeActor.class).withRouter( new RoundRobinRouter(5)));
slide-113
SLIDE 113

Router + Resizer

int lowerBound = 5; int upperBound = 20; ActorRef router = system.actorOf( new Props(ExampleActor1.class).withRouter( new RoundRobinRouter( new DefaultResizer( lowerBound, upperBound))));
slide-114
SLIDE 114

Java7 concurrency

slide-115
SLIDE 115

New concurrency utilities in Java 7

  • Fork/Join framework
  • For parallelizing divide and conquer algorithms
  • ThreadLocalRandom
  • For minimizing contention using random numbers
  • Phaser
  • More flexible CyclicBarrier
slide-116
SLIDE 116

Fork/Join

slide-117
SLIDE 117

Algorithm

Fork:

Recursively decompose large tasks into sub tasks

Join:

Await results of recursive tasks and combine

slide-118
SLIDE 118

Algorithm

Fork:

Recursively decompose large tasks into sub tasks

Join:

Await results of recursive tasks and combine

slide-119
SLIDE 119

Algorithm

Fork:

Recursively decompose large tasks into sub tasks

Join:

Await results of recursive tasks and combine

slide-120
SLIDE 120

Algorithm

Fork:

Recursively decompose large tasks into sub tasks

Join:

Await results of recursive tasks and combine

slide-121
SLIDE 121

Using Work Stealing

slide-122
SLIDE 122

ParallelArray

ParallelArray<Student> ¡students ¡= ¡ new ¡ParallelArray<Student>(fjPool, ¡data) double ¡bestGpa ¡= ¡students ¡ ¡ ¡ ¡.withFilter(isSenior) ¡ ¡ ¡ ¡.withMapping(selectGpa) ¡ ¡ ¡ ¡.max();
slide-123
SLIDE 123

Other uses of Fork/Join

  • Scala Parallel Collections
  • ­‑ collection.par ¡foreach ¡print
  • ­‑ collection.par ¡map ¡(_ ¡+ ¡1)
  • Upcoming Java Parallel Collections?
  • Akka
  • ForkJoinPool-based Dispactcher
  • ThreadLocalRandom
slide-124
SLIDE 124

How does Akka use Fork/Join?

slide-125
SLIDE 125

It started with a benchmark on our single 48-core box

slide-126
SLIDE 126

Default dispatcher using ThreadPoolExecutor

slide-127
SLIDE 127

This doesn’t look to good

slide-128
SLIDE 128

new ForkJoinPool

slide-129
SLIDE 129

This looks much better

slide-130
SLIDE 130

After tweaking it some more...

+50 million messages per second

slide-131
SLIDE 131

Failure Recovery

slide-132
SLIDE 132

Failure Recovery in Java/C/C# etc.

slide-133
SLIDE 133
  • You are given a SINGLE thread of control

Failure Recovery in Java/C/C# etc.

slide-134
SLIDE 134
  • You are given a SINGLE thread of control
  • If this thread blows up you are screwed

Failure Recovery in Java/C/C# etc.

slide-135
SLIDE 135
  • You are given a SINGLE thread of control
  • If this thread blows up you are screwed
  • So you need to do all explicit error handling
WITHIN this single thread

Failure Recovery in Java/C/C# etc.

slide-136
SLIDE 136
  • You are given a SINGLE thread of control
  • If this thread blows up you are screwed
  • So you need to do all explicit error handling
WITHIN this single thread
  • To make things worse - errors do not propagate
between threads so there is NO WAY OF EVEN FINDING OUT that something have failed

Failure Recovery in Java/C/C# etc.

slide-137
SLIDE 137
  • You are given a SINGLE thread of control
  • If this thread blows up you are screwed
  • So you need to do all explicit error handling
WITHIN this single thread
  • To make things worse - errors do not propagate
between threads so there is NO WAY OF EVEN FINDING OUT that something have failed
  • This leads to DEFENSIVE programming with:

Failure Recovery in Java/C/C# etc.

slide-138
SLIDE 138
  • You are given a SINGLE thread of control
  • If this thread blows up you are screwed
  • So you need to do all explicit error handling
WITHIN this single thread
  • To make things worse - errors do not propagate
between threads so there is NO WAY OF EVEN FINDING OUT that something have failed
  • This leads to DEFENSIVE programming with:
  • Error handling TANGLED with business logic

Failure Recovery in Java/C/C# etc.

slide-139
SLIDE 139
  • You are given a SINGLE thread of control
  • If this thread blows up you are screwed
  • So you need to do all explicit error handling
WITHIN this single thread
  • To make things worse - errors do not propagate
between threads so there is NO WAY OF EVEN FINDING OUT that something have failed
  • This leads to DEFENSIVE programming with:
  • Error handling TANGLED with business logic
  • SCATTERED all over the code base

Failure Recovery in Java/C/C# etc.

slide-140
SLIDE 140
  • You are given a SINGLE thread of control
  • If this thread blows up you are screwed
  • So you need to do all explicit error handling
WITHIN this single thread
  • To make things worse - errors do not propagate
between threads so there is NO WAY OF EVEN FINDING OUT that something have failed
  • This leads to DEFENSIVE programming with:
  • Error handling TANGLED with business logic
  • SCATTERED all over the code base

We can do better than this!!!

Failure Recovery in Java/C/C# etc.

slide-141
SLIDE 141

Just

LET IT CRASH

slide-142
SLIDE 142
slide-143
SLIDE 143
  • 4. SUPERVISE
slide-144
SLIDE 144
  • 4. SUPERVISE
  • SUPERVISE - manage another Actor’s failures
slide-145
SLIDE 145
  • 4. SUPERVISE
  • SUPERVISE - manage another Actor’s failures
  • Error handling in actors is handle by letting

Actors monitor (supervise) each other for failure

slide-146
SLIDE 146
  • 4. SUPERVISE
  • SUPERVISE - manage another Actor’s failures
  • Error handling in actors is handle by letting

Actors monitor (supervise) each other for failure

  • This means that if an Actor crashes, a

notification will be sent to his supervisor, who can react upon the failure

slide-147
SLIDE 147
  • 4. SUPERVISE
  • SUPERVISE - manage another Actor’s failures
  • Error handling in actors is handle by letting

Actors monitor (supervise) each other for failure

  • This means that if an Actor crashes, a

notification will be sent to his supervisor, who can react upon the failure

  • This provides clean separation of processing

and error handling

slide-148
SLIDE 148

Fault-tolerant

  • nion-layered

Error Kernel

slide-149
SLIDE 149 Error Kernel
slide-150
SLIDE 150 Error Kernel
slide-151
SLIDE 151 Error Kernel
slide-152
SLIDE 152 Error Kernel
slide-153
SLIDE 153 Error Kernel
slide-154
SLIDE 154 Error Kernel
slide-155
SLIDE 155 Error Kernel Node 1 Node 2
slide-156
SLIDE 156

SUPERVISE Actor

Every single actor has a default supervisor strategy. Which is usually sufficient. But it can be overridden.

slide-157
SLIDE 157 class Supervisor extends UntypedActor { private SupervisorStrategy strategy = new OneForOneStrategy( 10, Duration.parse("1 minute"), new Function<Throwable, Directive>() { @Override public Directive apply(Throwable t) { if (t instanceof ArithmeticException) return resume(); else if (t instanceof NullPointerException) return restart(); else return escalate(); } }); @Override public SupervisorStrategy supervisorStrategy() { return strategy;

SUPERVISE Actor

Every single actor has a default supervisor strategy. Which is usually sufficient. But it can be overridden.

slide-158
SLIDE 158 class Supervisor extends UntypedActor { private SupervisorStrategy strategy = new OneForOneStrategy( 10, Duration.parse("1 minute"), new Function<Throwable, Directive>() { @Override public Directive apply(Throwable t) { if (t instanceof ArithmeticException) return resume(); else if (t instanceof NullPointerException) return restart(); else return escalate(); } }); @Override public SupervisorStrategy supervisorStrategy() { return strategy; } ActorRef worker = context.actorOf(new Props(Worker.class)); public void onReceive(Object message) throws Exception { if (message instanceof Integer) worker.forward(message); } }

SUPERVISE Actor

slide-159
SLIDE 159 class Worker extends Actor { ...
  • verride def preRestart(
reason: Throwable, message: Option[Any]) { ... // clean up before restart }
  • verride def postRestart(reason: Throwable) {
... // init after restart } }

Manage failure

slide-160
SLIDE 160

This was

Akka 2.x

slide-161
SLIDE 161

This was

Akka 2.x

Well...it’s a start...

slide-162
SLIDE 162

...we have much much more

slide-163
SLIDE 163

AMQP Dataflow

...we have much much more

Cluster FSM Transactors Spring Pub/Sub ZeroMQ Microkernel IO TestKit Agents SLF4J Durable Mailboxes EventBus Camel TypedActor Extensions HTTP/REST

slide-164
SLIDE 164

Akka Cluster

Experimental module in 2.1

slide-165
SLIDE 165

Highlights

  • Automatic cluster-wide deployment
  • Decentralized P2P gossip-based cluster membership
  • Leader “election”
  • Adaptive load-balancing (based on runtime metrics)
  • Automatic replication with automatic fail-over upon
node crash
  • Automatic adaptive cluster rebalancing
  • Highly available configuration service
slide-166
SLIDE 166

Enable clustering

akka { 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" ] auto-down = on } }
slide-167
SLIDE 167

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 ¡ ¡ ¡ ¡} ¡ ¡} }
slide-168
SLIDE 168 doc.akka.io/docs/akka/snapshot/cluster/cluster.html

Cluster Specification

doc.akka.io/docs/akka/snapshot/cluster/cluster-usage.html

Cluster User Guide

github.com/akka/akka/tree/master/akka-cluster

Cluster Code

slide-169
SLIDE 169

Typesafe Console

free for developers later in the fall

slide-170
SLIDE 170

Typesafe Console

free for developers later in the fall

slide-171
SLIDE 171
slide-172
SLIDE 172

http://console-demo.typesafe.com

live demo

slide-173
SLIDE 173

get it and learn more

http://akka.io http://typesafe.com http://letitcrash.com

slide-174
SLIDE 174

EOF