akka: simpler scalability, fault-tolerance, concurrency & remoting through actors

162
Jonas Bonér Akka: Simpler Scalability, Fault-tolerance, Concurrency & Remoting through Actors http://akkasource.org Scalable Solutions AB Copyright 2009 - Scalable Solutions AB Wednesday, December 30, 2009

Upload: jonas-boner

Post on 06-May-2015

17.751 views

Category:

Technology


2 download

DESCRIPTION

Akka is the platform for the next generation event-driven, scalable and fault-tolerant architectures on the JVMWe believe that writing correct concurrent, fault-tolerant and scalable applications is too hard. Most of the time it's because we are using the wrong tools and the wrong level of abstraction.Akka is here to change that.Using the Actor Model together with Software Transactional Memory we raise the abstraction level and provides a better platform to build correct concurrent and scalable applications.For fault-tolerance we adopt the "Let it crash" / "Embrace failure" model which have been used with great success in the telecom industry to build applications that self-heals, systems that never stop.Actors also provides the abstraction for transparent distribution and the basis for truly scalable and fault-tolerant applications.Akka is Open Source and available under the Apache 2 License.

TRANSCRIPT

Page 1: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Jonas Bonér

Akka:Simpler Scalability, Fault-tolerance,

Concurrency & Remoting through Actors

http://akkasource.org

Scalable Solutions AB

Copyright 2009 - Scalable Solutions AB

Wednesday, December 30, 2009

Page 2: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

2

State

Wednesday, December 30, 2009

Page 3: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

3

The devil is in the state

Wednesday, December 30, 2009

Page 4: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

4

Wrong, let me rephrase

Wednesday, December 30, 2009

Page 5: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

5

The devil is in

the mutable state

Wednesday, December 30, 2009

Page 6: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

6

Definitions&

Philosophy

Wednesday, December 30, 2009

Page 7: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

What is a Value?A Value is something that

does not change

Discussion based onhttp://clojure.org/state

by Rich Hickey

Wednesday, December 30, 2009

Page 8: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

What is an Identity?A stable logical entity

associated with a series of different Values

over time

Wednesday, December 30, 2009

Page 9: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

What is State?The Value

an entity with a specific Identity

has at a particular point in time

Wednesday, December 30, 2009

Page 10: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

How do we know if something has State?

If a function is invoked with the same arguments at

two different points in time and returns different values...

...then it has state

Wednesday, December 30, 2009

Page 11: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

The ProblemThe unification Of

Identity & Value

They are not the same

Wednesday, December 30, 2009

Page 12: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

We need to separate Identity & Value

...add a level of indirection

Software Transactional Memory Managed References

Message-Passing ConcurrencyActors/Active Objects

Dataflow ConcurrencyDataflow (Single-Assignment) Variables

Wednesday, December 30, 2009

Page 13: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

The problems with Shared State Concurrency

Wednesday, December 30, 2009

Page 14: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Shared-State Concurrency>Concurrent access to shared, mutable state. >Protect mutable state with locks >The JavaC#C/C++RubyPythonetc.

Wednesday, December 30, 2009

Page 15: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Shared-State Concurrency is incredibly hard

>Inherently very hard to use reliably>Even the experts get it wrong

Wednesday, December 30, 2009

Page 16: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Example of Shared-State Concurrency

Transfer funds between bank accounts

Wednesday, December 30, 2009

Page 17: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

AccountpublicclassAccount{privateintbalance;publicvoidwithdraw(intamount){balance‐=amount;}publicvoiddeposit(intamount){balance+=amount;}}

Not thread-safeWednesday, December 30, 2009

Page 18: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Let’s make it thread-safepublicclassAccount{privateintbalance;publicsynchronizedvoidwithdraw(intamount){balance‐=amount;}publicsynchronizedvoiddeposit(intamount){balance+=amount;}}

Thread-safe right?Wednesday, December 30, 2009

Page 19: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

It’s still brokenTransfers are not atomic

Wednesday, December 30, 2009

Page 20: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Let’s write an atomic transfer method

publicclassAccount{...

publicsynchronizedvoidtransferTo(Accountto,doubleamount){this.withdraw(amount);to.deposit(amount);}...}

This will work right?Wednesday, December 30, 2009

Page 21: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Let’s transfer fundsAccountalice=...Accountbob=...//inonethreadalice.transferTo(bob,10.0D);//inanotherthreadbob.transferTo(alice,3.0D);

Wednesday, December 30, 2009

Page 22: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Might lead to

DEADLOCKDarn, this is really hard!!!

Wednesday, December 30, 2009

Page 23: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

We need to enforce lock ordering>How? >Java won’t help us >Need to use code convention (names etc.) >Requires knowledge about the internal state and implementation of Account

>…runs counter to the principles of encapsulation in OOP

>Opens up a Can of Worms

Wednesday, December 30, 2009

Page 24: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

The problem with locksLocks do not composeTaking too few locksTaking too many locksTaking the wrong locksTaking locks in the wrong orderError recovery is hard

Wednesday, December 30, 2009

Page 25: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

It’s justtoo hard

Wednesday, December 30, 2009

Page 26: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Java bet on the wrong horse?

Perhaps, but we’re not

completely screwed There are alternatives

Wednesday, December 30, 2009

Page 27: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

We need better and more high-level

abstractions

Wednesday, December 30, 2009

Page 28: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

28

Alternative Paradigms>Software Transactional Memory (STM) >Message-Passing Concurrency (Actors) >Dataflow Concurrency

Wednesday, December 30, 2009

Page 29: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Actors

Wednesday, December 30, 2009

Page 30: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

•Originates in a 1973 paper by Carl Hewitt

• Implemented in Erlang, Occam, Oz•Encapsulates state and behavior•Closer to the definition of OO than classes

Actors

Wednesday, December 30, 2009

Page 31: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

“OOP to me means only messaging, local retention and protection and

hiding of state-process, and extreme late-binding of all things.”

“Actually I made up the term “object-oriented”, and I can tell you

I did not have C++ in mind.”

Replace C++ with Java or C#

Alan Kay (father of SmallTalk and OOP)

Wednesday, December 30, 2009

Page 32: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Actors• Implements Message-Passing Concurrency• Share NOTHING• Isolated lightweight processes• Communicates through messages• Asynchronous and non-blocking

Wednesday, December 30, 2009

Page 33: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Actor Model of Concurrency

• No shared state … hence, nothing to synchronize.• Each actor has a mailbox (message queue)

Wednesday, December 30, 2009

Page 34: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

• Non-blocking send• Blocking receive• Messages are immutable• Highly performant and scalable

• SEDA-style (Staged Event-Driven Architecture)

Actor Model of Concurrency

Wednesday, December 30, 2009

Page 35: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Actor Model of Concurrency

• Easier to reason about• Raised abstraction level• Easier to avoid

–Race conditions–Deadlocks–Starvation–Live locks

Wednesday, December 30, 2009

Page 36: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Actors• Asynchronous

–Fire-and-forget–Futures (Send Receive Reply Eventually)

• Synchronous• Message loop with pattern (message) matching

• Erlang-style

Wednesday, December 30, 2009

Page 37: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Two different models• Thread-based• Event-based

–Very lightweight–Can easily create millions on a single workstation (6.5 million on 4 G RAM)

Wednesday, December 30, 2009

Page 38: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

> Akka (Java/Scala)> Kilim (Java)> Jetlang (Java)> Actor’s Guild (Java)> ActorFoundry (Java)> Actorom (Java)> FunctionalJava (Java)> GParallelizer (Groovy)> Fan Actors (Fan)

Actor libs for the JVM

Wednesday, December 30, 2009

Page 39: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka TransactorsSupervisor hierarchies

STMPersistent

Fault tolerance & Scalablility

Distributed

RESTful Comet

Secure

Wednesday, December 30, 2009

Page 40: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

caseobjectTick

classCounterextendsActor{privatevarcounter=0

defreceive={caseTick=>counter+=1println(counter)}}

Actors

Wednesday, December 30, 2009

Page 41: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valworker=actor{caseWork(fn)=>fn()}

Actorsanonymous

Wednesday, December 30, 2009

Page 42: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valworker=actor{...//init}receive{caseWork(fn)=>fn()}

Actorsanonymous

Wednesday, December 30, 2009

Page 43: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

//fire‐forgetcounter!Tick

Send: !

Wednesday, December 30, 2009

Page 44: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classSomeActorextendsActor{defreceive={caseUser(name)=>//useimplicitsendersender.get!(“Hi”+name)}}

Reply

Wednesday, December 30, 2009

Page 45: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classSomeActorextendsActor{defreceive={caseUser(name)=>//usereplyreply(“Hi”+name)}}

Reply

Wednesday, December 30, 2009

Page 46: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

//usesFuturewithdefaulttimeoutvalresultOption=actor!!Messagevalresult=resultOptiongetOrElsedefaultResult

//usesFuturewithexplicittimeout(actor!!(Message,1000)).getOrElse(thrownewException(“Timedout”))

Send: !!

Wednesday, December 30, 2009

Page 47: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classSomeActorextendsActor{defreceive={caseUser(name)=>//usereplyreply(“Hi”+name)}}

Reply

Wednesday, December 30, 2009

Page 48: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classSomeActorextendsActor{defreceive={caseUser(name)=>//storeawaythesenderfuture//toresolvelateror//somewhereelse...=senderFuture}}

Reply

Wednesday, December 30, 2009

Page 49: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

actor.startactor.stop

spawn(classOf[MyActor])

//callbackoverridedefshutdown={...//cleanupbeforeshutdown}

Start / Stop

Wednesday, December 30, 2009

Page 50: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

publicclassCounter{privateintcounter=0;publicvoidcount(){counter++;System.out.println(counter);}}

Active Objects: Java

Wednesday, December 30, 2009

Page 51: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Countercounter=(Counter)ActiveObject.newInstance(Counter.class,1000);

Create: POJO

Wednesday, December 30, 2009

Page 52: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Countercounter=(Counter)ActiveObject.newInstance(Counter.class,CounterImpl.class,1000);

Create: Interface & Implementation

Wednesday, December 30, 2009

Page 53: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classCounter{privatevarcounter=0defcount={counter+=1println(counter)}}

Active Objects

Wednesday, December 30, 2009

Page 54: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valcounter=ActiveObject.newInstance(classOf[Counter],1000)

Create: POSO

Wednesday, December 30, 2009

Page 55: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

counter.count

Send

Wednesday, December 30, 2009

Page 56: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

@onewayclassCounter{privatevarcounter=0@onewaydefcount={counter+=1println(counter)}}

Wednesday, December 30, 2009

Page 57: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

//definethecaseclasscaseclassRegister(user:User)

//createandsendanewcaseclassmessageactor!Register(user)

//tuplesactor!(username,password)

//listsactor!List(“bill”,“bob”,“alice”)

Immutable messages

Wednesday, December 30, 2009

Page 58: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

<akka>version="0.6"<actor>timeout=5000serialize‐messages=off</actor></akka>

Actors: config

Wednesday, December 30, 2009

Page 59: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Dispatchers

Wednesday, December 30, 2009

Page 60: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classDispatchers{defnewThreadBasedDispatcher(actor:Actor)

defnewExecutorBasedEventDrivenDispatcher(name:String)...}

Dispatchers

Wednesday, December 30, 2009

Page 61: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classMyActorextendsActor{dispatcher=Dispatchers.newThreadBasedDispatcher(this)...}

actor.dispatcher=dispatcher//beforestarted

Set dispatcher

Wednesday, December 30, 2009

Page 62: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valdispatcher=Dispatchers.newExecutorBasedEventDrivenDispatcher.withNewThreadPoolWithBoundedBlockingQueue(100).setCorePoolSize(16).setMaxPoolSize(128).setKeepAliveTimeInMillis(60000).setRejectionPolicy(newCallerRunsPolicy).buildThreadPool

EventBasedDispatcherFluent DSL

Wednesday, December 30, 2009

Page 63: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

When to use which dispatcher?

Wednesday, December 30, 2009

Page 64: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Thread-based actors• One thread per Actor• Good: • Threads (actors) don’t block each other• Good for long-running tasks

• Bad:• Poor scalability• Bad for short running tasks

• Use for a limited number of Actors• Use for low frequency of messages

Wednesday, December 30, 2009

Page 65: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Event-based actors

• Backed by thread pool • Lightweight: • Can create millions of Actors • 6.5 million on 4 G RAM

•Best scalability and performance•2 million messages in 8 seconds

Wednesday, December 30, 2009

Page 66: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Single threaded event-based actors

•Best performance• Millions of Actors•Bad: •one actor can block all other actors

•Does not take advantage of multicore

Wednesday, December 30, 2009

Page 67: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

MessageQueues

• Unbounded LinkedBlockingQueue• Bounded LinkedBlockingQueue• Bounded ArrayBlockingQueue

Bounded SynchronousQueue

Plus different options per queue

Wednesday, December 30, 2009

Page 68: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Supervision

Wednesday, December 30, 2009

Page 69: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Stolen from

ErlangWednesday, December 30, 2009

Page 70: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

9 nines

Wednesday, December 30, 2009

Page 71: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Supervisor hierarchiesOneForOne

Wednesday, December 30, 2009

Page 72: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Supervisor hierarchiesAllForOne

Wednesday, December 30, 2009

Page 73: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

AllForOneStrategy(maxNrOfRetries,withinTimeRange)

OneForOneStrategy(maxNrOfRetries,withinTimeRange)

Fault handlers

Wednesday, December 30, 2009

Page 74: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

link(actor)unlink(actor)

startLink(actor)spawnLink(classOf[MyActor])

Linking

Wednesday, December 30, 2009

Page 75: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

trapExit=List(classOf[ServiceException],classOf[PersistenceException])

trapExit

Wednesday, December 30, 2009

Page 76: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classSupervisorextendsActor{trapExit=List(classOf[Throwable])faultHandler=Some(OneForOneStrategy(5,5000))

defreceive={caseRegister(actor)=>link(actor)}}

Supervision

Wednesday, December 30, 2009

Page 77: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classFaultTolerantextendsActor{...overridedefpreRestart(reason:AnyRef)={...//cleanupbeforerestart}overridedefpostRestart(reason:AnyRef)={...//initafterrestart}}

Manage failure

Wednesday, December 30, 2009

Page 78: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

RestartStrategy(AllForOne,//restartpolicy10,//max#ofrestartretries5000)//withintimeinmillis

LifeCycle(//Permanent:alwaysberestarted//Temporary:restartedifexitedthroughERRPermanent)

Declarative config

Wednesday, December 30, 2009

Page 79: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

objectfactoryextendsSupervisorFactory(SupervisorConfig(RestartStrategy(AllForOne,3,10000),Supervise(actor1,LifeCycle(Permanent))::Supervise(actor2,LifeCycle(Temporary))::Nil))

factory.newSupervisor.start

Declarative config

Wednesday, December 30, 2009

Page 80: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valactors=ActorRegistry.actorsFor(FQN)

valactors=ActorRegistry.actorsFor(classOf[..])

ActorRegistry

Wednesday, December 30, 2009

Page 81: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

overridedefinit={...//inittheactor}

Initialize actor

init is called on startup

Wednesday, December 30, 2009

Page 82: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Remote Actors

Wednesday, December 30, 2009

Page 83: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

//usehost&portinconfigRemoteNode.startRemoteNode.start(classLoader)

RemoteNode.start("localhost",9999)RemoteNode.start("localhost",9999,classLoader)

Remote Server

Wednesday, December 30, 2009

Page 84: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

//usehost&portinconfigvalserver=newRemoteServer

server.start("localhost",9999)

Remote Server

Wednesday, December 30, 2009

Page 85: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

spawnRemote(classOf[MyActor],host,port)

startLinkRemote(actor,host,port)

spawnLinkRemote(classOf[MyActor],host,port)

Remote actors

Wednesday, December 30, 2009

Page 86: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

<akka><remote>service=onhostname="localhost"port=9999connection‐timeout=1000</remote></akka>

Remote config

Wednesday, December 30, 2009

Page 87: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka STM

Wednesday, December 30, 2009

Page 88: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

88

Software Transactional Memory (STM)

Wednesday, December 30, 2009

Page 89: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

89

What is STM?

Wednesday, December 30, 2009

Page 90: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

STM: overview>See the memory (heap and stack) as a transactional dataset

>Similar to a databasebegin commit abort/rollback

>Transactions are retried automatically upon collision

>Rolls back the memory on abort

Wednesday, December 30, 2009

Page 91: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

> Transactions can nest> Transactions compose (yipee!!)atomic{..atomic{..}}

STM: overview

Wednesday, December 30, 2009

Page 92: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

92

>All operations in scope of a transaction:Need to be idempotentCan’t have side-effects

STM: restrictions

Wednesday, December 30, 2009

Page 93: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

93

Akka STMis based on the ideas of

Clojure STM

Wednesday, December 30, 2009

Page 94: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

94

2 things: 1. Managed References2. Persistent Datastructures

Wednesday, December 30, 2009

Page 95: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

• Typical OO: direct access to mutable objects

Managed ReferencesTypical OO - Direct

references to Mutable Objects

• Unifies identity and value

• Anything can change at any time

• Consistency is a user problem

• Encapsulation doesn’t solve concurrency problems

?

?

42

?

6:e

:d

:c

:b

:a

foo

• Managed Reference: separates Identity & ValueClojure - Indirect references

to Immutable Objects

6

17

"ethel"

"fred"

42

:e

:d

:c

:b

:afoo

@foo

• Separates identity and value

• Obtaining value requires explicit dereference

• Values can never change

• Never an inconsistent value

• Encapsulation is orthogonal

Copyright Rich Hickey 2009

Wednesday, December 30, 2009

Page 96: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

• Separates Identity from Value- Values are immutable- Identity (Ref) holds Values

• Change is a function• Compare-and-swap (CAS)• Abstraction of time• Can only be altered within a transaction

Managed References

Wednesday, December 30, 2009

Page 97: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valref=TransactionalState.newRef(HashTrie[String,User]())

valusers=ref.getvalnewUsers=users+//createsnewHashTrie(“bill”‐>newUser(“bill”,“secret”)

ref.swap(newUsers)

Managed References

Wednesday, December 30, 2009

Page 98: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valusersRef=TransactionalState.newRef(HashTrie[String,User]())

for(users<‐usersRef){users+(name‐>user)}

valuser=for(users<‐usersRef)yield{users(name)}

Managed References

Wednesday, December 30, 2009

Page 99: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

for{users<‐usersRefuser<‐usersroles<‐rolesRefrole<‐rolesifuser.hasRole(role)}{...//dostuff}

Managed References

Wednesday, December 30, 2009

Page 100: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

//wrapsaRefwithaHashTrievalusers=TransactionalState.newMap[String,User]

//wrapsaRefwithaVectorvalusers=TransactionalState.newVector[User]

Managed Referencesconvenience classes

Wednesday, December 30, 2009

Page 101: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Persistent datastructures

• Immutable• Change is a function• Old version still available after change• Very fast with performance guarantees (near constant time)

• Thread safe• Iteration safe

Wednesday, December 30, 2009

Page 102: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Bit-partitioned hash trieBit-partitioned hash tries

Copyright Rich Hickey 2009

Wednesday, December 30, 2009

Page 103: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Structural sharing with path copying

Path Copyingint count 15

INode root

HashMapint count 16

INode root

HashMap

Copyright Rich Hickey 2009

Approach

• Programming with values is critical

• By eschewing morphing in place, we just need to manage the succession of values (states) of an identity

• A timeline coordination problem

• Several semantics possible

• Managed references

• Variable-like cells with coordination semantics

Wednesday, December 30, 2009

Page 104: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

importse.scalablesolutions.akka.collection._

valhashTrie=newHashTrie[K,V]

//API(+extendsMap)defget(key:K):Vdef+[A>:V](pair:(K,A)):HashTrie[K,A]def‐(key:K):HashTrie[K,A]defempty[A]:HashTrie[K,A]

Persistent datastructuresHashTrie

Approach

• Programming with values is critical

• By eschewing morphing in place, we just need to manage the succession of values (states) of an identity

• A timeline coordination problem

• Several semantics possible

• Managed references

• Variable-like cells with coordination semantics

Wednesday, December 30, 2009

Page 105: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

importse.scalablesolutions.akka.collection._

valvector=newVector[T]

//API(+extendsRandomAccessSeq)defapply(i:Int):Tdef+[A>:T](obj:A):Vector[A]defpop:HashTrie[K,A]//removetaildefupdate[A>:T](i:Int,obj:A):Vector[A]

Persistent datastructuresVector

Approach

• Programming with values is critical

• By eschewing morphing in place, we just need to manage the succession of values (states) of an identity

• A timeline coordination problem

• Several semantics possible

• Managed references

• Variable-like cells with coordination semantics

Wednesday, December 30, 2009

Page 106: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

• Transactional Memory- Atomic, Consistent, Isolated (ACI)- MVCC- Rolls back in memory and retries automatically on clash

• Works together with Managed References• Map, Vector and Ref abstraction

Akka STM

Wednesday, December 30, 2009

Page 107: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classUserRegistryextendsTransactor{privatelazyvalstorage=TransactionalState.newMap[String,User]

defreceive={caseNewUser(user)=>storage+(user.name‐>user)...}}

STM: declarative API

Wednesday, December 30, 2009

Page 108: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classUserRegistryextendsActor{makeTransactionRequiredprivatelazyvalstorage=TransactionalState.newMap[String,User]

defreceive={caseNewUser(user)=>storage+(user.name‐>user)...}}

STM: declarative API

Wednesday, December 30, 2009

Page 109: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

@transactionrequiredclassUserRegistry{}

STM: declarative Java API

Wednesday, December 30, 2009

Page 110: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

importse.scalablesolutions.akka.stm.Transaction._

atomic{..//dosomethingwithinatransaction}

atomic(maxNrOfRetries){..//dosomethingwithinatransaction}

atomicReadOnly{..//dosomethingwithinatransaction}

STM: high-order fun API

Wednesday, December 30, 2009

Page 111: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

importse.scalablesolutions.akka.stm.Transaction._

atomically{..//trytodosomething}orElse{..//iftxclash;trydodosomethingelse}

STM: high-order fun API

Wednesday, December 30, 2009

Page 112: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valuserStorage=TransactionalState.newMap[String,User]

for(tx<‐Transaction()){userStorage.put(user.name,user)}

STM: monadic API

Wednesday, December 30, 2009

Page 113: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valuserStorage=TransactionalState.newMap[String,User]

valusers=for{tx<‐Transaction()name<‐userNamesifuserStorage.contains(name)}yielduserStorage.get(name)//transactional

STM: monadic API

Wednesday, December 30, 2009

Page 114: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

<akka><stm>service=ondistributed=off</stm></akka>

STM: config

Wednesday, December 30, 2009

Page 115: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

TransactionManagement.disableTransactions

STM: disable

Wednesday, December 30, 2009

Page 116: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Serialization

Wednesday, December 30, 2009

Page 117: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

SerializersScalaJSONJavaJSONProtobufSBinary

JavaWednesday, December 30, 2009

Page 118: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valfoo=newFoovaljson=Serializer.ScalaJSON.out(foo)valfooCopy=Serializer.ScalaJSON.in(json).asInstanceOf[Foo]

SerializersScala 2 JSON & JSON 2 Scala

Wednesday, December 30, 2009

Page 119: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

importsbinary.DefaultProtocol._valusers=("user1","passwd1")::("user2","passwd2")::("user3","passwd3")::Nilvalbytes=Serializer.SBinary.out(users)

valusersCopy:List[Tuple2[String,String]]]=Serializer.SBinary.in(bytes)

SerializersScala 2 Binary & Binary 2 Scala

Wednesday, December 30, 2009

Page 120: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valpojo=ProtobufPOJO.getDefaultInstance.toBuilder.setId(1).setName("protobuf").setStatus(true).buildvalbytes=pojo.toByteArray

valpojoCopy=Serializer.Protobuf.in(bytes,classOf[ProtobufPOJO])

SerializersProtobuf

Wednesday, December 30, 2009

Page 121: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

caseclassMyMessage(id:String,value:Tuple2[String,Int])extendsSerializable.ScalaJSON

valmessage=MyMessage("id",("hello",34))valjson=message.toJSON

Serializable

Wednesday, December 30, 2009

Page 122: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Persistence

Wednesday, December 30, 2009

Page 123: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

• Pluggable storage backend- Cassandra - MongoDB- Redis

• Map, Vector and Ref abstraction• MVCC• Works together with STM

Persistence

Wednesday, December 30, 2009

Page 124: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Persistence API

//transactionalCassandra‐backedMapvalmap=CassandraStorage.newMap

//transactionalRedis‐backedVectorvalvector=RedisStorage.newVector

//transactionalMongo‐backedRefvalref=MongoStorage.newRef

Wednesday, December 30, 2009

Page 125: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

<akka><storage><cassandra>hostname="127.0.0.1"port=9160storage‐format="protobuf"consistency‐level=quorum</cassandra>

<mongodb>hostname="127.0.0.1"port=27017dbname="mydb"</mongodb></storage></akka>

Persistence: config

Wednesday, December 30, 2009

Page 126: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka’s Cassandra API

valsessions=newCassandraSessionPool(keyspace,StackPool(SocketProvider(host,port)),Protocol.Binary,consistencyLevel)

Create a session pool

Wednesday, December 30, 2009

Page 127: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Cassandra API//getacolumnvalcolumn=sessions.withSession{session=>session|(key,newColumnPath(columnFamily,superColumn,serializer.out(name))}

valvalue=if(column.isDefined)Some(serializer.in(column.get.value,None))elseNone

Automatic connection management

Wednesday, December 30, 2009

Page 128: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Cassandra API//addacolumnsessions.withSession{session=>session++|(key,newColumnPath(cf,null,serializer.out(name)),serializer.out(value),System.currentTimeMillis,consistencyLevel)}

Wednesday, December 30, 2009

Page 129: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka REST

Wednesday, December 30, 2009

Page 130: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

@Path("/count")classCounterextendsActor{privatevarcounter=0

@GET@Produces(Array("text/html"))defcount=(this!!Tick).getOrElse(<h1>Errorincounter</h1>)

defreceive={caseTick=>counter+=1reply(<h1>Tick:{counter}</h1>)}}}

RESTful actors

Wednesday, December 30, 2009

Page 131: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

<akka><rest>service=onhostname=“localhost”port=9998</rest></akka>

REST: config

Wednesday, December 30, 2009

Page 132: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classBoot{objectfactoryextendsSupervisorFactory(SupervisorConfig(RestartStrategy(OneForOne,3,100),Supervise(newCounter,LifeCycle(Permanent))::Supervise(newChat,LifeCycle(Permanent))::Nil)))valsupervisor=factory.newInstancesupervisor.start}

Boot classes

Wednesday, December 30, 2009

Page 133: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

<akka>boot=["sample.rest.Boot","sample.comet.Boot"]...</akka>

Boot config

Wednesday, December 30, 2009

Page 134: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Comet

Wednesday, December 30, 2009

Page 136: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

@Path("/chat")classChatextendsActor{caseclassChat(who:String,what:String,message:String)

@Suspend//receivingendpoint@GET@Produces(Array("text/html"))defsuspend=<!‐‐suspend‐‐>

//sendingendpoint@Broadcast(Array(classOf[XSSHtmlFilter],classOf[JsonFilter]))@Consumes(Array("application/x‐www‐form‐urlencoded"))@Produces(Array("text/html"))@POSTdefpublishMessage(form:MultivaluedMap[String,String])=(this!!Chat(form.getFirst("name"),form.getFirst("action"),form.getFirst("message"))).getOrElse("Systemerror")

defreceive={caseChat(..)=>..}}

Comet actors

Wednesday, December 30, 2009

Page 137: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Security

Wednesday, December 30, 2009

Page 138: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classSampleAuthenticationServiceextendsDigestAuthenticationActor{

//Useanin‐memorynonce‐mapasdefaultoverridedefmkNonceMap=newHashMap[String,Long]

//Changethistowhateveryouwantoverridedefrealm=“sample”

//Username,passwordandrolesforausernameoverridedefuserInfo(uname:String):Option[UserInfo]={...//getuserwithpasswordandrolesSome(UserInfo(uname,password,roles))}}

Security: service

Wednesday, December 30, 2009

Page 139: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classSecuredActorextendsActor{@RolesAllowed(Array(“admin”))defresetSystem=(this!!Reset).getOrElse(<error>Couldnotresetsystem</error>)

defreceive={caseReset=>...}}

Security: usage

Wednesday, December 30, 2009

Page 140: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

<akka><rest>service=onhostname=“localhost”port=9998filters=[“AkkaSecurityFilterFactory”]authenticator=“SimpleAuthenticationService”</rest></akka>

Security: config

Wednesday, December 30, 2009

Page 141: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Lift

Wednesday, December 30, 2009

Page 142: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

classBoot{//Lift’sbootstrapclassdefboot{LiftRules.httpAuthProtectedResource.prepend{case(ParsePath("akka‐lift"::Nil,_,_,_))=>Full(AuthRole("admin"))}LiftRules.authentication=HttpBasicAuthentication("lift"){case("guest","guest",req)=>userRoles(AuthRole("admin"))}objectfactoryextendsSupervisorFactory(SupervisorConfig(RestartStrategy(OneForOne,3,100),List(Supervise(newAkkaService,LifeCycle(Permanent))))factory.newInstance.start}}

Lift integration

Wednesday, December 30, 2009

Page 143: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

<web‐app><servlet><servlet‐name>AkkaServlet</servlet‐name><servlet‐class>se.ss.akka.rest.AkkaServlet</servlet‐class></servlet><servlet‐mapping><servlet‐name>AkkaServlet</servlet‐name><url‐pattern>/*</url‐pattern></servlet‐mapping></web‐app>

Lift integration

Wednesday, December 30, 2009

Page 144: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka HotSwap

Wednesday, December 30, 2009

Page 145: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

HotSwapactor!HotSwap(Some({//newbodycasePing=>...casePong=>...}))

Wednesday, December 30, 2009

Page 146: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka AMQP

Wednesday, December 30, 2009

Page 147: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valproducer=AMQP.newProducer(config,hostname,port,exchangeName,serializer,None,None,//listeners100)

producer!Message(“Hithere”,routingId)

AMQP: producer

Wednesday, December 30, 2009

Page 148: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

valconsumer=AMQP.newConsumer(config,hostname,port,exchangeName,ExchangeType.Direct,serializer,None,100,passive,durable,Map[String,AnyRef())

consumer!MessageConsumerListener(queueName,routingId,actor{caseMessage(payload,_,_,_,_)=>...//processmessage})

AMQP: consumer

Wednesday, December 30, 2009

Page 149: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Kernel

Wednesday, December 30, 2009

Page 150: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

java‐jarakka‐0.6.jar\‐Dakka.config=<path>/akka.conf

Start Kernel

exportAKKA_HOME=<pathtoakkadist>java‐jar$AKKA_HOME/dist/akka‐0.6.jar

Or

Wednesday, December 30, 2009

Page 151: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka Deployment

Wednesday, December 30, 2009

Page 152: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka as a library

Using the Actor moduleWednesday, December 30, 2009

Page 153: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka as a library

Add STM moduleWednesday, December 30, 2009

Page 154: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka as a library

Add Persistence module as a CacheWednesday, December 30, 2009

Page 155: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka as a library

Add Persistence module as primary SoRWednesday, December 30, 2009

Page 156: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka as a library

Add REST and Comet modulesWednesday, December 30, 2009

Page 157: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Akka as stand-alone Kernel

Wednesday, December 30, 2009

Page 158: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

<log>console=onfilename="./logs/akka.log"roll="daily"level="debug"syslog_host=".."syslog_server_name=".."</log>

Logging

Wednesday, December 30, 2009

Page 159: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Monitoring & Management Provisioningand more...

Part of commercial license

Wednesday, December 30, 2009

Page 160: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Learn morehttp://akkasource.org

Wednesday, December 30, 2009

Page 161: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Professional help

http://[email protected]

Consulting Training Mentoring

Wednesday, December 30, 2009

Page 162: Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

EOFWednesday, December 30, 2009