Search code examples
akkaakka-cluster

how to properly set AKKA number of routee via configuration file


I am currently learning AKKA and have problem with controlling number of routee. I am trying to implement a cluster with cluster aware router as receptionist with simple actor as routee, all running on my local for development .Say I have a configuration like below

deployment {
  /RouterA {
    router = round-robin-pool
    metrics-selector = mix
    nr-of-instances = 20
    routees.paths = ["/user/ActorA"]
    cluster {
      enabled = on
      max-nr-of-instances-per-node = 20
      allow-local-routees = on
    }
  }
}

then I can see 20 routers in debug log

and I registered RouterA as cluster receptionist like below

ActorRef someactor=system.actorOf(Props.create(Something.class),"ActorA");
ActorRef routerA=system.actorOf(FromConfig.getInstance().props(),"RouterA");
ClusterClientReceptionist.get(system).registerService(routerA);

Q1 : am I registering a particular router instance as receptionist ? or 20 of them ? is it possible/suggested to register a/20 router(s) as receptionist ?

Q2: why I see 20 routers are all using same ActorA (via this.hashCode() ) instance? what is the correct way to configure router (via file) so it will send message to one of 20 routees regardless local or remote ? or am I wrong with the way of creating 20 routees ? (need 20 routees to balance the load)

Q3 : if I use following configuration , it seems there is only 1 router in debug log,why ? is it because optimal-size-exploring-resizer? so it discarding nr-of-instances = 20 ? if so , how do I make router ramp up ?

deployment {
  /RouterA {
    router = cluster-metrics-adaptive-group
    metrics-selector = mix
    nr-of-instances = 20
    routees.paths = ["/user/ActorA"]
    cluster {
      enabled = on
      max-nr-of-instances-per-node = 20
      allow-local-routees = on
    }
    optimal-size-exploring-resizer {
          enabled = on
          action-interval = 5s
          lower-bound = 10
          upper-bound = 50
          downsize-after-underutilized-for = 72h
    }
  }
}

Thanks


Solution

  • First need to give you some concepts, seems you misunderstand it.

    nr-of-instances = 20 same as max-total-nr-of-instances = 20, see following explanation:

    Maximum number of routees that will be deployed, in total on all nodes. See also description of max-nr-of-instances-per-node. For backwards compatibility reasons, nr-of-instances has the same purpose as max-total-nr-of-instances for cluster aware routers and nr-of-instances (if defined by user) takes precedence over max-total-nr-of-instances.

    This means in your cluster, you router will just new 20 routees at most. But how many routees it will new depends on other 2 parameter:

    1) max-nr-of-instances-per-node = 20, explain follows:

    Maximum number of routees that will be deployed on each cluster member node. Note that max-total-nr-of-instances defines total number of routees, but number of routees per node will not be exceeded, i.e. if you define max-total-nr-of-instances = 50 and max-nr-of-instances-per-node = 2 it will deploy 2 routees per new member in the cluster, up to 25 members.

    2) the number of cluster member you have.

    Here, your situation is:

    nr-of-cluster-node = 1

    max-nr-of-instances-per-node = 20

    So total routees are nr-of-cluster-node * max-nr-of-instances-per-node = 20, even if you set nr-of-instances = 100, the routees will still 20, because no enough node to host your routees.

    So correct code as follows:

    ActorRef routerA = system.actorOf(FromConfig.getInstance().props(Props.create(ActorA.class)), "routerA");
    ClusterClientReceptionist.get(system).registerService(routerA);
    

    Above code will create a router actor for you, and use ActorA instance as your routees. Then, for your scenario, will generate 20 actors, when you send message to receptionist, the message will be sent to the router, and the router will choose one routee to handle the message(depends on router type).

    Next explain your questions:

    For Q1:

    With the code, not as you expected, it will not set 20 routers, it will just setup one router for you, detail see above explanations. So just one router was registered to receptionist.

    For Q2:

    I don't think you can see 20 routers, meanwhile, I think you can not see 20 routees as well. With your code ActorRef someactor=system.actorOf(Props.create(Something.class), "ActorA");, what you can see just one actor is created, and this was not created by router actor. With just one actor instance, you are surely just see the same actor hashcode. Your application.conf is correct, just your understanding is wrong, and your code is wrong.

    For Q3:

    Again, not one router, you see one routee. This is because with the code ActorRef someactor=system.actorOf(Props.create(Something.class), "ActorA");, you have create a routee by yourself.

    And with router = cluster-metrics-adaptive-group, this means router will not create routee for you, it will use existed routee, you just set it as routees.paths = ["/user/ActorA"], and here you just set one routee actor.