具有多个消息ID的Akka分片群集

具有多个消息ID的Akka分片群集,akka,akka-cluster,Akka,Akka Cluster,我使用Akka的群集切分,如下所示: val deviceOperations = ClusterSharding(system).start( typeName = DeviceOperations.shardName, entryProps = Some(DeviceOperations.props(notification, profile, dataDecoders)), idExtractor = DeviceOperations.idExtractor, shardR

我使用Akka的群集切分,如下所示:

val deviceOperations = ClusterSharding(system).start(
  typeName = DeviceOperations.shardName,
  entryProps = Some(DeviceOperations.props(notification, profile, dataDecoders)),
  idExtractor = DeviceOperations.idExtractor,
  shardResolver = DeviceOperations.shardResolver)
idExtractor和shardResolver被设置为从消息中提取ID,并将消息路由到集群中具有匹配ID的参与者

val idExtractor: ShardRegion.IdExtractor = {
  case ParentDeviceRegister(deviceId, registerProps) ⇒ (deviceId.toString, DeviceRegister(registerProps))
  ...
}
val shardResolver: ShardRegion.ShardResolver = {
  case ParentDeviceRegister(deviceId, _) ⇒ s"${deviceId.hashCode() % 10}"
  ...
}
这应该将具有相同ID的所有传入消息路由到集群中的同一参与者。不幸的是,来自该设备的一半消息使用一个唯一ID,其余消息使用不同的唯一ID。两个唯一ID都属于同一设备,我希望将两组消息路由到同一参与者。将这些消息路由到集群中相同的对应参与者的最佳方式是什么

我曾经考虑过某种类型的键值存储,用于从两个单独的唯一ID中查找公共的唯一ID,但我不希望引入单一故障点。还必须对每条消息进行查找,这似乎不太理想

如果能够为集群中的每个参与者分配多个身份,以便协调器能够处理它,那将是一件非常棒的事情

更新 我想我有个计划

我将选择一个ID作为主ID。我将使用辅助参与者系统将包含辅助ID的消息转发给主参与者系统。辅助参与者将存储设备的主ID,并使用主ID将消息转发给主参与者系统

次要参与者最初不知道主ID,但在收到第一条消息时,可以直接从设备请求主ID。然后,辅助参与者将存储主ID,并使用存储的主ID将将来的消息路由到主设备参与者系统


包含主ID的其他消息将直接发送到主参与者系统,而无需通过辅助参与者系统进行路由。

两个ID的族之间是否存在语法差异?因为您可能会执行类似于“if(isType1(设备))->doSomething else doSomethingElse”的操作。你不能让一个演员拥有多个id的afaik,但是你的提取器可以足够聪明来管理它。id在语法上是不同的。一个可能是IMEI,另一个可能是序列号(不同的长度和字符)。它们都在标识单个设备,但我需要将这两种类型的消息路由到集群中的同一个分片参与者。您如何知道imei X和序列Y属于同一个设备?在设备连接到服务器后,有一个命令可以检索这两个标识符。我可能会让服务器在我第一次初始化device actor时这样做。我还可以将imei和序列号映射到服务器上的UUID。除非我不想为每条消息查找UUID。如果你想避免查找,你的更新想法是个好主意。请注意,您并不是完全避免它,只是通过发送给另一个参与者使它成为非阻塞的。