Building Scalable Applications with the Actor Model

Building Scalable Applications with the Actor Model

279b474d14f72e4daa1fc76e6f3c929f?s=128

Greg Shackles

October 13, 2017
Tweet

Transcript

  1. Building Scalable Applications with the Actor Model Greg Shackles Principal

    Engineer, Olo @gshackles github.com/gshackles
  2. Scaling: Up or Out?

  3. Moore’s Law

  4. OK fine, let’s get concurrent!

  5. Multithreaded Programming
 
 Theory

  6. Multithreaded Programming
 
 Practice

  7. Oh right, concurrency is hard...

  8. Amdahl’s law The theoretical speedup is always limited by the

    part of the task that cannot benefit from the improvement.
  9. The Actor Model A better concurrency abstraction

  10. What is an actor? Mailbox Behavior State

  11. What can an actor do? ! Send messages ! Create

    other actors ! Change behavior
  12. Messages ! Invoke actor behavior by sending it a message

    ! Messages are ◦ Immutable ◦ Processed one at a time, in order
  13. Creating other actors

  14. Everything is an actor

  15. Behavior ! Switch how an actor will handle its next

    message ◦ Referred to as becoming something ! User actor in a chat system can become: ◦ Authenticating ◦ Authenticated ◦ Unauthenticated ◦ ...and so on
  16. ! Actors are only referenced by address ◦ Think: phone

    numbers, email addresses ! Code doesn’t know or care where the actor is ! Scaling from one node to thousands becomes configuration Location Transparency
  17. Reactive Systems reactivemanifesto.org Responsive Message Driven Elastic Resilient

  18. None
  19. C#: Create a message public class Greet
 {
 public string

    Who { get; } public Greet(string who)
 {
 Who = who;
 }
 }
  20. C#: Create an actor public class GreetingActor : ReceiveActor
 {


    public GreetingActor()
 {
 Receive<Greet>(greet =>
 Console.WriteLine($"Hello {greet.Who}");
 }
 }
  21. var system = ActorSystem.Create("my-system"); var greeter = system.ActorOf<GreetingActor>("greeter"); greeter.Tell(new Greet("World"));

    C#: Send a message
  22. F#: Create a message type Message = | Greet of

    string
  23. F#: Create an actor let handleMessage (mailbox: Actor<'a>) msg =

    match msg with | Greet who -> printf "Hello %s" who | _ -> ()
  24. let system = ActorSystem.Create("my-system") let greeter = spawn system "greeter"

    (actorOf2 handleMessage) greeter <! Greet "World" F#: Send a message
  25. Supervision ! An actor can respond to subordinate actor failures

    with a directive to: ◦ Resume the subordinate ◦ Restart the subordinate ◦ Stop the subordinate ◦ Escalate to its own supervisor ! Actors are cheap, let them crash
  26. Example Supervision Strategy protected override SupervisorStrategy SupervisorStrategy() => new OneForOneStrategy(

    maxNrOfRetries: 10, withinTimeRange: TimeSpan.FromSeconds(30), decider: Decider.From(ex => { if (ex is ArithmeticException) return Directive.Resume; else if (ex is NotSupportedException) return Directive.Stop; return Directive.Restart; }));
  27. ! Categories of messaging patterns: ◦ At most once ◦

    At least once ◦ Exactly once ! Default is at-most-once delivery ◦ i.e. no guaranteed delivery Message Delivery Reliability
  28. ! Special type of actor that routes messages to its

    routees ! Built-in routing strategies ◦ Round robin ◦ Broadcast ◦ Random ◦ Consistent hashing ◦ Tail chopping ◦ Scatter-gather first-completed ◦ Smallest mailbox Routers
  29. Actor system topology is just configuration

  30. Configuration
 
 Router akka.actor.deployment { /webhook-worker-pool { router = round-robin-pool

    nr-of-instances = 5 } }
  31. Configuration
 
 Remoting actor { provider = "Akka.Remote.RemoteActorRefProvider, Akka.Remote" deployment

    { /remoteecho { remote = "akka.tcp://DeployTarget@localhost:8090" } } } remote { helios.tcp { port = 0 hostname = localhost } }
  32. Configuration
 
 Clustering akka { actor.provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster" remote

    { helios.tcp { port = 8081 hostname = localhost } } cluster { seed-nodes = ["akka.tcp://ClusterSystem@localhost:8081"] roles = ["crawlerV1", "crawlerV2"] role.["crawlerV1"].min-nr-of-members = 3 } }
  33. Demo github.com/gshackles/akka-samples