meetup slides
TRANSCRIPT
Suraj Atreya
Data Engineer
Glassbeam
Introduction to
What we do
Machine log analytics company
Scala shop
Akka is used extensively
We are a bunch of passionate hackers who solve concurrency, race conditions, memory overcommit issues
We process 1 TB worth of logs everyday
Akka, Cassandra, Solr, H2
Akka
Pronounced as 'Ahkka', part of Typesafe stack
Framework for:Distributed
Asynchronous
Concurrent
Non-blocking
Event driven
Message passing
Actor Model
Based on Carl Hewitt 1973 paper
Actor Model
3 axioms When an Actor receives a message it can:Create new Actors
Send messages to other Actors
Decide how it should handle the next message it receives
Akka Actors
High level abstraction
No need to worry about thread locking and synchronization
Fault tolerant
Location transparent
Support for Java and Scala APIs
Create Actor
case class HelloWorld(who: String)
class HelloWorldActor extends Actor with ActorLogging { def receive = { case HelloWorld(person) log.info("Hello " + person) }}
object TestHelloWorld {
def main(args: Array[String]): Unit = { val system = ActorSystem("MySystem") val helloWorldActorRef = system.actorOf(Props[HelloWorldActor], name = "hello") helloWorldActorRef ! HelloWorld("Mr.X") }}
Create Actor
case class HelloWorld(who: String)
class HelloWorldActor extends Actor with ActorLogging { def receive = { case HelloWorld(person) log.info("Hello " + person) }}
object TestHelloWorld {
def main(args: Array[String]): Unit = { val system = ActorSystem("MySystem") val helloWorldActorRef = system.actorOf(Props[HelloWorldActor], name = "hello") helloWorldActorRef ! HelloWorld("Mr.X") }}
Create an Actor System
Create Actor
case class HelloWorld(who: String)
class HelloWorldActor extends Actor with ActorLogging { def receive = { case HelloWorld(person) log.info("Hello " + person) }}
object TestHelloWorld {
def main(args: Array[String]): Unit = { val system = ActorSystem("MySystem") val helloWorldActorRef = system.actorOf(Props[HelloWorldActor], name = "hello") helloWorldActorRef ! HelloWorld("Mr.X") }}
Create an Actor SystemCreate an Actor
Create Actor
case class HelloWorld(who: String)
class HelloWorldActor extends Actor with ActorLogging { def receive = { case HelloWorld(person) log.info("Hello " + person) }}
object TestHelloWorld {
def main(args: Array[String]): Unit = { val system = ActorSystem("MySystem") val helloWorldActorRef = system.actorOf(Props[HelloWorldActor], name = "hello") helloWorldActorRef ! HelloWorld("Mr.X") }}
Create an Actor SystemCreate an ActorSend message
Actor hierarchy
Guardian System Actor
Actor hierarchy
Guardian System Actor
HelloWorldActor
system.actorOf(Props[HelloWorldActor], name = "hello")
Actor hierarchy
Guardian System Actor
HelloWorldActor
system.actorOf(Props[HelloWorldActor], name = "hello")
File system like name resolution
Guardian System Actor
HelloWorldActor
system.actorOf(Props[HelloWorldActor], name = "hello")
B
/HelloWorldActor
A
/HelloWorldActor/A
/HelloWorldActor/B
Under the hood
...
Actor 1Actor 2
Actor mailbox
m1
m2
.......
Time elapsed
Message delivery
At most once semantics
Ordering of messages sender-receiver pair
Actors != Threads
General confusion that actors are threads. They are not!
Actors are perceived as processes
Actors are assigned to threads by 'Dispatcher'
Many different kinds of dispatchers:Default dispatcher
Pinned dispatcher
Balancing dispatcher (not covered in this talk)
CallingThreadDispatcher (not covered in this talk)
Routers
Router is an actor that first receives messages and routes them to other actors
Can be configured to be any one of the routers:Round Robin
Random Router
Smallest Mailbox
Broadcast Router
Scatter Gather First Completed
Consistent Hashing
Create a router
val router1 = system.actorOf(Props[ExampleActor1] .withRouter(RoundRobinRouter(nrOfInstances = 5)))
Sending messages to router
router1 ! MyMsg
RoundRobin router
Router
Routee 1
Routee 2
Routee 3
Routee 4
Routee 5
router1 ! MyMsg
RoundRobin router
Router
Routee 1
Routee 2
Routee 3
Routee 4
Routee 5
router1 ! MyMsg
SmallestMailBox router
Router
Routee 1
Routee 2
Routee 3
Routee 4
Routee 5
router1 ! MyMsg
Pinned dispatcher demo
Pinned dispatcher
Log file
............................................................................................................................................................................................................................................................
.....................................................................
Chuncked file
.....................................................................
.....................................................................
.....................................................................
Pinned dispatcher
Chunk 1
Chunk 2
Chunk 3
Chunk 4
Best practices
Do not block inside an Actor Eg: a big while loop, network socket etc
Prefer immutable messages between actors instead of mutable objects
Do not create too many ActorSystems. Instead create as many actors as you want.
Do not send behaviour as messages. Might accidently share state.
EOF