Akka一致散列路由

xdnvmnnf  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(146)

我已经开发了一个应用程序使用Typed Akka 2.6.19。
我想根据IP地址将事件从某个源路由到同一个被路由者/工作者。因此,我计划使用一致散列路由。
我没有看到太多关于这种路线类型的文献类型的 akka 。请给予一些指针和示例代码。

jdgnovmf

jdgnovmf1#

您只需要使用要使用的哈希函数初始化路由器。
例如(在Scala中,虽然Java API是类似的):

trait Command {
  // all commands are required to have an associated IP Address (here represented in string form)
  def ipAddr: String
}

// inside, e.g. the guardian actor, and using the actor context to spawn the router as a child
val serviceKey = ServiceKey[Command]("router")
val router = context.spawn(
  Routers.group(serviceKey)
    .withConsistentHashingRouting(
      virtualNodesFactor = 10,
      mapping = { msg: Command => msg.ipAddr }
    )

// spawn the workers, who will register themselves with the router
val workerBehavior =
  Behaviors.setup[Command] { ctx =>
    ctx.system.receptionist ! Receptionist.Register(serviceKey, context.self)

    Behaviors.receiveMessage { msg =>
      ??? // TODO
    }
  }

(1 to 10).foreach { i =>
  context.spawn(workerBehavior, s"worker-$i")
}

实际上,对于每个注册的工作者,路由器将生成10virtualNodesFactor)随机数,并将它们与该工作进程关联。然后,路由器将对每个传入消息执行mapping函数,以获取该消息的字符串密钥,并对该字符串密钥进行散列。如果存在关联随机数小于或等于该散列的工作进程,工作者选择也小于或等于该散列的最大关联随机数;如果散列值恰好小于与任何工作者相关联的每个随机数,则选择具有最大相关联随机数的工作者。
请注意,这意味着给定的工作线程可以处理超过1 ipAddr的消息。
请注意,此算法并不能强有力地保证具有相同ipAddr的命令将始终转到相同的工作线程,即使它们被路由到的工作线程仍处于活动状态:如果另一个工作者注册并生成了大于前一个工作者的相关令牌的令牌,并且所生成的令牌小于ipAddr的散列,则该新工作者将有效地从旧工作者窃取该ipAddr的消息。
缺少这种保证意味着,如果您依赖于给定ipAddr的所有消息都发送到同一个工作线程来保证正确性,那么您将需要类似于集群分片的东西,这是更高的开销,但是允许保证没有工作者将看到多个ipAddr的消息,并且(特别是对于持久性)将保证相同的“逻辑参与者”/实体处理相同ipAddr的消息。

相关问题