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

Scaling Web Apps with Akka

May 08, 2015

Download

Technology

Maciej Matyjas
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Scaling Web Apps with Akka

 Scaling Web Apps with Akka 

Maciej Matyjas London Scala User Group Skills Matter2010 July 14

Page 2: Scaling Web Apps with Akka

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

Page 3: Scaling Web Apps with Akka

Scaling Web Apps with Akka

High AvailabilityQuick Page LoadsFast Reads/Writes

Characteristics TechniquesHardware Load BalancingCachingPartitioning Queues/MessagingReplication CDN

Page 4: Scaling Web Apps with Akka

Scaling Web Apps with Akka

Page 5: Scaling Web Apps with Akka

Scaling Web Apps with Akka

Range of mountains in Sweden

Open Source Project

Written in Scala with Scala/Java APIs

Page 6: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

Actors Model of Computing

Defined in 1963 by Carl Hewitt

Used by Erlang to support reliability (99.9999999% uptime)

Page 8: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

No shared state +

No locks =

Safe concurrency

Page 10: Scaling Web Apps with Akka

ErlangScala Thread basedScala Event basedLift ActorsAkka

Actors Model Implementations

Page 11: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

Leverage Multi-Core and Distributed Cloud Infrastructure

Millions of lightweight actors on commodity hardware

Safe Concurrency

Remote Actors

Page 17: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

NoSQL & Distributed Data Stores

Pluggable Storage Back EndsCassandraRedisMongoDBOthers...

Brings the D in ACIDWorks with STM and Transactors

Page 23: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

Flexible Dispatch Strategies

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

Page 25: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

Here Comes the Code Demo Time!

Page 27: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

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: Scaling Web Apps with Akka

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]