Другой вариант использования для маршрутизатора с поддержкой кластера akka и шардинга кластера akka?

  1. Маршрутизатор с поддержкой кластера:

    val router = system.actorOf(ClusterRouterPool(
      RoundRobinPool(0),
      ClusterRouterPoolSettings(
        totalInstances = 20,
        maxInstancesPerNode = 1,
        allowLocalRoutees = false,
        useRole = None
      )
    ).props(Props[Worker]), name = "router")
    

    Здесь мы можем отправить сообщение router, сообщение будет отправлено ряду удаленных участников маршрутизации.

  2. Шардинг кластера (постоянство не учитывается)

    class NewShoppers extends Actor {
      ClusterSharding(context.system).start(
        "shardshoppers",
        Props(new Shopper),
        ClusterShardingSettings(context.system),
        Shopper.extractEntityId,
        Shopper.extractShardId
      )
    
      def proxy = {
        ClusterSharding(context.system).shardRegion("shardshoppers")
      }
    
      override def receive: Receive = {
        case msg => proxy forward msg
      }
    }
    

    Здесь мы можем отправить сообщение proxy, сообщение будет отправлено ряду сегментированных субъектов (также известных как объекты).

Итак, мой вопрос: it seems both 2 methods can make the tasks distribute to a lot of actors. What's the design choice of above two? Which situation need which choice?


person atline    schedule 06.03.2017    source источник


Ответы (2)


Маршрутизатор пула будет, когда вы просто хотите отправить некоторую работу на какой-либо узел и выполнить некоторую обработку, два сообщения, отправленные последовательно, скорее всего, не попадут в один и тот же субъект для обработки.

Кластерное сегментирование - это когда у вас есть уникальный идентификатор для каждого какого-либо актора, и у вас их слишком много, чтобы поместиться в один узел, но вы хотите, чтобы каждое сообщение с этим идентификатором всегда попадало в актор для этого идентификатора. Например, моделируя User как объект, вы хотите, чтобы все команды для этого пользователя в конечном итоге выполнялись с пользователем, но вы хотите, чтобы субъект был перемещен, если топология кластера изменяется (удаление или добавление узлов), и вы хотите, чтобы они были разумно сбалансированы по существующим узлы.

person johanandren    schedule 09.03.2017
comment
Тогда как насчет маршрутизатора согласованного хеш-пула? Есть ли разница с сегментированием кластера? - person atline; 09.03.2017
comment
Это отправит работу на один и тот же узел, если топология остается той же, при ее изменении она может начать отправку на другой узел, потому что хэш находится над полным набором узлов. Он никак не проинформирует маршруты, поэтому вы по-прежнему не можете обращаться к актору по идентификатору таким образом. - person johanandren; 09.03.2017
comment
Эта статья: Состояние распространения в приложениях Akka.Cluster plus Йоханандрен отвечает на мой вопрос. - person atline; 10.03.2017
comment
Я добавил ответ, объединяющий ответы Йоханандрена и статью, основанный на моих исследованиях этого предмета. Это в основном то, что я надеялся найти, когда впервые задал тот же вопрос. - person ig-dev; 17.07.2019

Благодарим Johanandren и связанную статью как основу для следующего ответа:

И router, и sharding распространяют работы. Sharding требуется, если, помимо балансировки нагрузки, субъекты-получатели должны надежно управлять состоянием, которое напрямую связано с entity identifier.

Напомним, что entity identifier - это ключ, полученный из отправляемого сообщения, определяющий получателя сообщения в кластере.

Прежде всего, можете ли вы управлять состоянием, связанным с identifier на разных узлах, с помощью маршрутизатора с согласованным хешированием? Маршрутизатор Consistent Hash всегда будет отправлять сообщения с равным identifier одному и тому же целевому субъекту. Ответ: нет, как описано ниже.

Метод на основе хэша перестает работать, когда узлы в кластере переходят в состояние Down или Up, потому что это изменяет связанного субъекта для некоторых идентификаторов. Если узел выходит из строя, сообщения, которые были с ним связаны, теперь отправляются другому субъекту в сети, но этот субъект не информируется о прежнем состоянии субъекта, который он теперь заменяет. Аналогичным образом, если появится новый узел, он позаботится о сообщениях (идентификаторах), которые ранее были связаны с другим субъектом, и ни новый узел, ни старый узел не будут проинформированы об этом.

С другой стороны, при сегментировании созданные акторы осведомлены о entity identifier, которыми они управляют. Sharding будет следить за тем, чтобы сущностью в кластере управлял ровно один субъект. И он воссоздает сегментированных субъектов на другом узле, если их родительский узел выйдет из строя. Таким образом, используя persistence, они сохранят свое (постоянное) состояние между узлами при изменении количества узлов. Вам также не нужно беспокоиться о проблемах параллелизма, если актор воссоздается на другом узле благодаря Sharding. Более того, если встречается сообщение с новым entity identifier, для которого актер еще не существует, создается новый субъект.

Маршрутизатор с постоянным хешированием может по-прежнему использоваться для кэширования, поскольку сообщения с одним и тем же ключом обычно отправляются одному и тому же субъекту. Для управления сущностью с отслеживанием состояния, существующей в кластере только один раз, требуется Sharding.

Используйте маршрутизаторы для балансировки нагрузки, используйте Sharding для распределенного управления объектами с отслеживанием состояния.

person ig-dev    schedule 17.07.2019