【问题标题】:Implement one actor per user (Child-Per-Entity pattern) in a cluster using Akka.NET使用 Akka.NET 在集群中为每个用户实现一个参与者(Child-Per-Entity 模式)
【发布时间】:2017-04-02 02:11:30
【问题描述】:

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

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

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

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

在 StackOverflow 上有一个有点相似的 question 这里指向使用 Akka.Cluster.Sharding,但在 Akka.NET Design Patterns Aaron 有评论说他使用了一致的哈希路由器方法,这就是我首先开始它的原因.

谢谢

【问题讨论】:

  • 作为参考,我将示例添加到GitHub

标签: c# actor akka.net


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢。我确实浏览了 Akka.NET 示例,但没有进入 Sharding 示例,所以我错过了你指出的那个。鉴于 Aaron 的评论,我认为使用一致的哈希路由器(在路由器和实际实体之间使用中间父演员)是可行的,但也许这只是不处于集群模式时的一种选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-12
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多