使用 Akka.NET 在集群中为每个用户实施一个参与者(每个实体子模式)

Implement one actor per user (Child-Per-Entity pattern) in a cluster using Akka.NET

我正在做一个小样本来了解一些 Akka.NET。我正在尝试实现一个 Child-Per-Entity 模式(如 Akka.NET Design Patterns 中所示),其中每个用户有一个参与者(跨集群)。

为此,我尝试使用带有 ConsistentHashingPool 的 ClusterRouterPool,它将消息分发给一些保留 IDictionary(int,IActorRef) 的父 actor,子 actor 由其 id 索引(用作一致性哈希)。

然而,这种方法似乎并没有像我最初预期的那样起作用,因为:

  1. 让不同的客户端创建路由器会导致它们创建多个父 actor,这反过来又会创建重复的子 actor。
  2. 即使我只有一个路由器,如果一个新节点加入集群会发生什么?路由器是否会重新平衡自身,导致再次路由到新的父 actor,从而创建重复的子 actor?

Whosebug 上有一个有点类似的,它指向使用 Akka.Cluster.Sharding,但在 Akka.NET Design Patterns 上,Aaron 发表评论说他使用了一致的哈希路由器方法,因此我首先开始使用它。

谢谢

我认为,关键概念是理解 Akka.Cluster.Sharding 和一致性哈希路由器之间的区别:

  • Akka.Cluster.Sharding 中,消息参与者路由基于 (ShardId, EntityId) 标识符。这是一对一的关系,这意味着具有不同标识符的消息将始终路由到其专用的参与者。此外,集群分片将确保即使集群中的节点数量发生变化,消息也会正确发送给他们的参与者。
  • 一致性哈希路由器 方法中,需要理解的重要一点是密钥的概念 space - 它是所有可能的消息标识符的 space已收到。这个 space 然后除以路由器后面的参与者数量——这意味着每个参与者不是与单个标识符相关联,而是与一个范围相关联。这是一对多的关系,因此具有不同 id 的两条消息可能会被路由到同一个参与者。此外,随着集群中节点数量的变化,该路由器后面的参与者数量也会发生变化——因此,参与者的键范围不是固定的,它可能会随着时间的推移而变化。这意味着当集群大小发生变化时,具有相同标识符的消息可能会被路由到不同的参与者。

因此我认为,集群分片正是您要找的。在 Akka.NET 核心存储库的示例部分中,您可能会发现 a sample 直接解决了您的问题。