Upload
others
View
26
Download
0
Embed Size (px)
Citation preview
Akka:Simpler Concurrency, Scalability &
Fault-tolerance through Actors
Jonas Bonér
Viktor Klang
Tuesday, April 20, 2010
•Writing correct concurrent applications is too hard
•Scaling out applications is too hard
•Writing highly fault-tolerant applications is too hard
We believe that...
Tuesday, April 20, 2010
It doesn’t have to be like this
We need to raise the abstraction level
Tuesday, April 20, 2010
Locks & Threadsare...
Tuesday, April 20, 2010
...sometimes
plain evil
Tuesday, April 20, 2010
...but always the
wrong default
Tuesday, April 20, 2010
Introducing
STM
Persistent
Distributed
RESTful Secure
Agents
Dataflow Open Source
Actors
Tuesday, April 20, 2010
Actorsone tool in the toolbox
Tuesday, April 20, 2010
• Implements Message-Passing Concurrency• Share NOTHING• Isolated lightweight processes•Communicates through messages•Asynchronous and non-blocking• Each actor has a mailbox (message queue)
Actor Model of Concurrency
Tuesday, April 20, 2010
Actor Model of Concurrency
• Easier to reason about• Raised abstraction level• Easier to avoid–Race conditions–Deadlocks–Starvation–Live locks
Tuesday, April 20, 2010
Akka Actors
Tuesday, April 20, 2010
Two different models
• Thread-based• Event-based– Very lightweight (600 bytes per actor)– Can easily create millions on a single workstation (6.5 million on 4 G RAM)– Does not consume a thread
Tuesday, April 20, 2010
Microbenchmark
•Chameneos benchmark• http://shootout.alioth.debian.org/
• +4 times faster• Run it yourself (3 different benchmarks):
• http://github.com/jboner/akka-bench
Akka 0.8.1 3815
Scala Actors 2.8.0.Beta1 (react) 16086
Tuesday, April 20, 2010
caseobjectTick
classCounterextendsActor{privatevarcounter=0
defreceive={caseTick=>counter+=1println(counter)}}
Actors
Tuesday, April 20, 2010
valworker=actor{caseWork(fn)=>fn()}
Actorsanonymous
Tuesday, April 20, 2010
//fire‐forgetcounter!Tick
Send: !
Tuesday, April 20, 2010
//usesFuturewithdefaulttimeoutvalresult:Option[..]=actor!!Message
Send: !!
Tuesday, April 20, 2010
//returnsafuturevalfuture=actor!!!Messagefuture.awaitvalresult=future.get
...Futures.awaitOne(List(fut1,fut2,...))Futures.awaitAll(List(fut1,fut2,...))
Send: !!!
Tuesday, April 20, 2010
classSomeActorextendsActor{defreceive={caseUser(name)=>//usereplyreply(“Hi”+name)}}
Reply
Tuesday, April 20, 2010
Akka Dispatchers
Tuesday, April 20, 2010
classDispatchers{defnewThreadBasedDispatcher(actor:Actor)
defnewExecutorBasedEventDrivenDispatcherdefnewExecutorBasedEventDrivenWorkStealingDispatcher
...//etc}
Dispatchers
Tuesday, April 20, 2010
classMyActorextendsActor{dispatcher=Dispatchers.newThreadBasedDispatcher(this)...}
actor.dispatcher=dispatcher//beforestarted
Set dispatcher
Tuesday, April 20, 2010
Let it crash fault-tolerance
Tuesday, April 20, 2010
Stolen from
ErlangTuesday, April 20, 2010
9 nines
Tuesday, April 20, 2010
OneForOne fault handling strategy
Tuesday, April 20, 2010
OneForOne fault handling strategy
Tuesday, April 20, 2010
OneForOne fault handling strategy
Tuesday, April 20, 2010
OneForOne fault handling strategy
Tuesday, April 20, 2010
OneForOne fault handling strategy
Tuesday, April 20, 2010
OneForOne fault handling strategy
Tuesday, April 20, 2010
OneForOne fault handling strategy
Tuesday, April 20, 2010
AllForOnefault handling strategy
Tuesday, April 20, 2010
AllForOnefault handling strategy
Tuesday, April 20, 2010
AllForOnefault handling strategy
Tuesday, April 20, 2010
AllForOnefault handling strategy
Tuesday, April 20, 2010
Supervisor hierarchies
Tuesday, April 20, 2010
Supervisor hierarchies
Tuesday, April 20, 2010
Supervisor hierarchies
Tuesday, April 20, 2010
Supervisor hierarchies
Tuesday, April 20, 2010
AllForOneStrategy(maxNrOfRetries,withinTimeRange)
OneForOneStrategy(maxNrOfRetries,withinTimeRange)
Fault handlers
Tuesday, April 20, 2010
link(actor)unlink(actor)
startLink(actor)spawnLink[MyActor]
Linking
Tuesday, April 20, 2010
trapExit=List(classOf[ServiceException],classOf[PersistenceException])
trapExit
Tuesday, April 20, 2010
classSupervisorextendsActor{trapExit=List(classOf[Throwable])faultHandler=Some(OneForOneStrategy(5,5000))
defreceive={caseRegister(actor)=>link(actor)}}
Supervision
Tuesday, April 20, 2010
classFaultTolerantServiceextendsActor{...overridedefpreRestart(reason:Throwable)={...//cleanupbeforerestart}overridedefpostRestart(reason:Throwable)={...//initafterrestart}}
Manage failure
Tuesday, April 20, 2010
Remote Actors
Tuesday, April 20, 2010
//usehost&portinconfigRemoteNode.start
RemoteNode.start("localhost",9999)
Remote Server
Scalable implementation based on NIO (Netty) & Protobuf
Tuesday, April 20, 2010
•Client-initated and managed•Server-initiated and managed
Two types of
remote actors
Tuesday, April 20, 2010
//methodsinActorclass
spawnRemote[MyActor](host,port)
spawnLinkRemote[MyActor](host,port)
startLinkRemote(actor,host,port)
Client-managedsupervision works across nodes
Tuesday, April 20, 2010
valactorProxy=spawnLinkRemote[MyActor](“darkstar”,9999)
actorProxy!message
Client-managedmoves actor to server
client manages through proxy
Tuesday, April 20, 2010
RemoteNode.register(“service:id”,newMyService)
Server-managedregister and manage actor on server
client gets “dumb” proxy handle
server part
Tuesday, April 20, 2010
valhandle=RemoteClient.actorFor(“service:id”,“darkstar”,9999)
handle!message
Server-managed
client part
Tuesday, April 20, 2010
Cluster.relayMessage(classOf[TypeOfActor],message)
for(endpoint<‐Cluster)spawnRemote[TypeOfActor](endpoint.host,endpoint.port)
Cluster Membership
Tuesday, April 20, 2010
STManother tool in the toolbox
Tuesday, April 20, 2010
43
What is STM?
Tuesday, April 20, 2010
STM: overview• See the memory (heap and stack) as a transactional dataset
• Similar to a database• begin• commit• abort/rollback
• Transactions are retried automatically upon collision
• Rolls back the memory on abort
Tuesday, April 20, 2010
• Separates Identity from Value- Values are immutable- Identity (Ref) holds Values
•Change is a function•Compare-and-swap (CAS)•Abstraction of time•Must be used within a transaction
Managed References
Tuesday, April 20, 2010
valref=Ref(Map[String,User]())
valusers=ref.get
valnewUsers=users+(“bill”‐>User(“bill”))
ref.swap(newUsers)
Managed References
Tuesday, April 20, 2010
valusers=TransactionalMap[String,User]()
valusers=TransactionalVector[User]()
Transactionaldatastructures
Tuesday, April 20, 2010
importTransaction.Local._
atomic{...atomic{//nestedtransactionscompose...//dosomethingwithinatransaction}}
STM: API
Tuesday, April 20, 2010
Actors + STM = Transactors
Tuesday, April 20, 2010
classUserRegistryextendsTransactor{privatelazyvalstorage=TransactionalMap[String,User]()
defreceive={caseNewUser(user)=>storage+(user.name‐>user)...}}
Transactors
Tuesday, April 20, 2010
Transactors
Tuesday, April 20, 2010
TransactorsStart transaction
Tuesday, April 20, 2010
TransactorsStart transaction
Send message
Tuesday, April 20, 2010
TransactorsStart transaction
Send message
Tuesday, April 20, 2010
TransactorsStart transaction
Send message
Update statewithin transaction
Tuesday, April 20, 2010
TransactorsStart transaction
Send message
Update statewithin transaction
Tuesday, April 20, 2010
TransactorsStart transaction
Send message
Update statewithin transaction
Tuesday, April 20, 2010
TransactorsStart transaction
Send message
Update statewithin transaction
Tuesday, April 20, 2010
TransactorsStart transaction
Send message
Update statewithin transaction
Tuesday, April 20, 2010
TransactorsStart transaction
Send message
Update statewithin transaction
Tuesday, April 20, 2010
TransactorsStart transaction
Send message
Update statewithin transaction
Transaction fails
Tuesday, April 20, 2010
TransactorsStart transaction
Send message
Update statewithin transaction
Transaction fails
Tuesday, April 20, 2010
Transactors
Tuesday, April 20, 2010
Transactors
Tuesday, April 20, 2010
Transactors
Tuesday, April 20, 2010
Transactors
Tuesday, April 20, 2010
Transactors
Tuesday, April 20, 2010
Transactors
Tuesday, April 20, 2010
TransactorsTransactionautomatically
retried
Tuesday, April 20, 2010
Agentsyet another tool in the toolbox
Tuesday, April 20, 2010
valagent=Agent(5)
//sendfunctionasynchronouslyagentsend(_+1)
valresult=agent()//deref...//useresult
agent.close
Agents
Cooperates with STMTuesday, April 20, 2010
Deploy as dependency JAR in WEB-INF/lib etc. Run as stand-alone microkernel Soon OSGi-enabled, then drop
in any OSGi container (Spring DM server, Karaf etc.)
How to run it?
Tuesday, April 20, 2010
Akka Persistence
Tuesday, April 20, 2010
Persistence//transactionalCassandra‐backedMapvalmap=CassandraStorage.newMap
//transactionalRedis‐backedVectorvalvector=RedisStorage.newVector
//transactionalMongo‐backedRefvalref=MongoStorage.newRef
Tuesday, April 20, 2010
REST
Comet
Security
...and much much more
Web
GuiceAMQP
Camel
Spring
Tuesday, April 20, 2010
Learn morehttp://akkasource.org
Tuesday, April 20, 2010
The commercialentity behind Akka
http://akkasource.com
Tuesday, April 20, 2010
EOFTuesday, April 20, 2010
?Tuesday, April 20, 2010