29
Scaling Web Apps with Akka Maciej Matyjas London Scala User Group Skills Matter 2010 July 14

Akka lsug skills matter

Embed Size (px)

DESCRIPTION

During the talk, we will build a simple web app using Lift and then introduce Akka ( http://akkasource.org) to help scale it. Specifically, we will demonstrate Remote Actors, "Let it crash" fail over, and Dispatcher. Other Scala oriented tools we will use include sbt and ENSIME mode for emacs.

Citation preview

Page 1: Akka lsug skills matter

 Scaling Web Apps with Akka 

Maciej Matyjas London Scala User Group Skills Matter2010 July 14

Page 2: Akka lsug skills matter

“ Simple Scalability,     Fault-Tolerance, Concurrency &     Remoting through Actors”akkasource.org

Page 3: Akka lsug skills matter

Scaling Web Apps with Akka

High AvailabilityQuick Page LoadsFast Reads/Writes

Characteristics TechniquesHardware Load BalancingCachingPartitioning Queues/MessagingReplication CDN

Page 4: Akka lsug skills matter

Scaling Web Apps with Akka

Page 5: Akka lsug skills matter

Scaling Web Apps with Akka

Range of mountains in Sweden

Open Source Project

Written in Scala with Scala/Java APIs

Page 6: Akka lsug skills matter

Scaling Web Apps with Akka

Actors Model

Multi-Core and Cloud Infrastructure

Graceful Failure a la Erlang OTP

Transactions a la Clojure

NoSQL and Distributed Data Stores

Flexible Dispatch Strategies

Page 7: Akka lsug skills matter

Actors Model of Computing

Defined in 1963 by Carl Hewitt

Used by Erlang to support reliability (99.9999999% uptime)

Page 8: Akka lsug skills matter

Actors Model of Computing

"encapsulates state and behavior into a lightweight process/thread" - Jonas BonérAsynchronous message passing between ActorsMessages are immutableSynchronized mailboxMailbox is read with pattern matchingNo shared stateNo locksSafe concurrency

Page 9: Akka lsug skills matter

No shared state +

No locks =

Safe concurrency

Page 10: Akka lsug skills matter

ErlangScala Thread basedScala Event basedLift ActorsAkka

Actors Model Implementations

Page 11: Akka lsug skills matter

Erlang Actors Example-module(mypackage). myErlangActor() ->receive{msgType, Msg} -> io:format(" p n", [Msg]), myErlangActor()Other -> io:format("wholy canoli, this is unmatched! n"), myErlangActor()end.

c(mypackage).Pid = spawn(fun mypackage:myErlangActor/0).Pid ! {msgType, "Erlang is for the discerning programmer"}.

Page 12: Akka lsug skills matter

Scala Thread Based Actorsimport scala.actor.Actorimport scala.actor.Actor._

case class Message(msg: String)

class AnActor extends Actor { def act() = receive { case Message(m) => println(m) case _ => println("unknown message") }}

class Director { val myActor = new AnActor myActor.start myActor ! Message("threedz can haz block?")}

Page 13: Akka lsug skills matter

Scala Event Based Actorsimport scala.actor.Actorimport scala.actor.Actor._

case class Message(msg: String)

class AnActor extends Actor { def act() = loop { react { case Message(m) => println(m) case _ => println("unknown message")} } }

class Director { val myActor = new AnActor myActor.start myActor ! Message("eventz iz lightweight?")}

Page 14: Akka lsug skills matter

Lift Actors

case class Message(msg: String)

class AnActor extends LiftActor { def messageHandler = { case Message(m) => println(m) case _ => println("unknown message")} }

class Director { val myActor = new AnActor myActor ! Message("Lift Actors is lightest & rulz!")}

Page 15: Akka lsug skills matter

Akka Actorsimport se.scalablesolutions.akka.actor.Actorcase class Message(msg: String)

class AnActor extends Actor { def receive = { case Message(m) => println(m) case _ => println("unknown message") }}

class Director { val myActor = Actor.actorOf[AnActor] myActor.start myActor ! Message("akkastic!")}

Page 16: Akka lsug skills matter

Leverage Multi-Core and Distributed Cloud Infrastructure

Millions of lightweight actors on commodity hardware

Safe Concurrency

Remote Actors

Page 17: Akka lsug skills matter

Leverage Multi-Core and Distributed Cloud Infrastructure: Remote Actorsimport se.scalablesolutions.akka.remote.RemoteNode spawnRemote[MyActor](host, port) spawnLinkRemote[MyActor](host, port)startLinkRemote(myActor, host, port)

Page 18: Akka lsug skills matter

Handle Failure Gracefully

"Let it Crash"Actor exceptions w/out supervision do not behave well Remote Actors w/out supervision are unmanaged Linking ActorsSupervisor

Manages linked ActorsNotified when linked Actor crashesOneForOneAllForOne

Works with Remote Actors

Page 19: Akka lsug skills matter

Handle Failure Gracefully: Supervisor val supervisor = Supervisor( SupervisorConfig( RestartStrategy(OneForOne, 3, 1000, List(classOf[Exception])), Supervise( actorOf[MyActor], LifeCycle(Permanent)) :: Nil))

supervisor.link(actorOf[MyActor])

class MyActor extends Actor { self.lifeCycle = Some(LifeCycle(Permanent)) override def preRestart(reason: Throwable) { // clean things up }}

Page 20: Akka lsug skills matter

Manage Transactions

Software Transactional Memory (STM)Thanks Clojure!Addresses fundamental weakness of Actors ModelHello Shared State!Transactional but still no locksIn memoryMap, Vector, & Ref throw exceptions if modified outside of transactionACI but no D

Transactors Transactional ActorsActors + STMIf Actor's writes clash, rollback memory and retried

Page 21: Akka lsug skills matter

Manage Transactions: Transactorsimport se.scalablesolutions.akka.actor.Transactorimport se.scalablesolutions.akka.stm._ class MyActor extends Transactor { def receive = { case Increment(counter) => counter.swap(counter.get + 1) } }

class Director { lazy val counter = Ref(0) //counter.swap(7) // blows up, cannot mutate outside transaction myActor ! Increment(counter)}

Page 22: Akka lsug skills matter

NoSQL & Distributed Data Stores

Pluggable Storage Back EndsCassandraRedisMongoDBOthers...

Brings the D in ACIDWorks with STM and Transactors

Page 23: Akka lsug skills matter

NoSQL & Distributed Data Stores: Casssandraimport se.scalablesolutions.akka._import stm.Transaction.Local._import persistence.cassandra._ val map = CassandraStorage.newMap(myId)// map += "myKey" -> Value(someSuch) // exceptionatomic { map += "myKey" -> Value(someSuch)}

Page 24: Akka lsug skills matter

Flexible Dispatch Strategies

Default is Single-threaded, Event-based dispatcher Work-stealing, Event-based Reactor-base, Event-drivenThread-basedEvent-based

Page 25: Akka lsug skills matter

Flexible Dispatch Strategies

class MyActor extends Actor { self.dispatcher = Dispatchers.newExecutorBasedEventDrivenDispatche(name) dispatcher .withNewThreadPoolWithBoundedBlockingQueue(100) .setCorePoolSize(16) .setMaxPoolSize(128) .setKeepAliveTimeInMillis(60000) .setRejectionPolicy(new CallerRunsPolicy) .buildThreadPool}

Page 26: Akka lsug skills matter

Here Comes the Code Demo Time!

Page 27: Akka lsug skills matter

Versions

Scala 2.8.0.RC6Lift 2.0-scala2.8.0-SNAPSHOTAkka 2.8.0.RC3 0.9.1sbt 0.7.4ensime master on github.com

Page 28: Akka lsug skills matter

AlternativesBefore Drinking the Kool-Aid or Flogging Your Fav Tool

scalaz FunctionalJavaGParallelizerKilimActorFoundryActors GuildJetlangActoromFan Actors

Other Actor Impls More Options JVM

Fork/JoinESBNettyHawtDispatch

ErlangRabbitMQHadoopOpenMPMPI

Page 29: Akka lsug skills matter

Questions About Akka?

http://akkasource.orghttp://groups.google.com/group/akka-userCourse at Skills Matter Oct 13-14 LSUG talk on Oct 13Ask me:

@matyjas [email protected]