Akka:跨参与者实例共享状态
Posted
技术标签:
【中文标题】Akka:跨参与者实例共享状态【英文标题】:Akka: Sharing state across actor instances 【发布时间】:2015-07-10 17:01:41 【问题描述】:我的MyProcessingActor
actor 将使用实体 ID 上的 ConsistentHashingRouter
进行路由,这样在任何时候(跨多个线程)都可能有该 actor 的多个实例在处理中
actor 使用地图来执行一些计算逻辑。因此,2 个不同的 actor 实例可以同时读取和写入此地图。
在这些 Actor 实例之间共享地图似乎公然违反了 Actor 模型,即使它是 Java ConcurrentHashMap
。
处理此类问题的最佳选择是什么?我没有在 Akka 文档中看到它,除非我错过了。
我可以看到 2 个选项:
MyMapManagerActor
的单个实例,它将管理对此地图的读/写。如果这是单线程的,那么实际上MyProcessingActor
也将是单线程的
使用 Akka STM - 我在最新版本的项目中没有看到这一点
还有哪些其他推荐的方法?
【问题讨论】:
我对 Akka 没有太多经验,但一直在研究它。您所描述的似乎确实与 Akka 打算适应的范式背道而驰。也许您可以在消息中传递路由映射并使其不可变。如果您要传递它,该地图也应该是不可变的。 你看过 Akka Agents 吗?他们可能会帮助解决此类问题doc.akka.io/docs/akka/snapshot/java/agents.html 【参考方案1】:正如您在问题中所说,在参与者之间共享可变状态是一件非常糟糕的事情。我已经使用了您提到的两种方法(使用类似 MapManagerActor
和使用 Akka STM)并且两者都可以工作,尽管 MapManagerActor
方法对我来说感觉更好。就 MapManagerActor
而言,唯一被序列化的部分是对 Map 的实际读写,而不是计算本身,因此根据您的用例,您可能会发现并行化是足够的。
另一种选择是将地图本身替换为 Actor。你可以有一个父actor来管理子actor,并且每个地图条目都有一个该actor的子actor。如果您的密钥集是静态的,您可以在启动时预先创建所有子 Actor,例如,使用密钥(或其哈希码)作为 Actor 名称。然后您可以使用actorSelection
直接访问子Actor,如/user/parentActor/<key>
。如果需要动态创建演员,最好向父演员询问特定的孩子,并让它回复ActorRef
给那个特定的孩子(如果需要,创建它)。比如:
override def receive =
case GetActor(key) =>
context.children(key) match
case Some(ref) => sender ! GetActorReply(ref)
case None => sender ! context.actorOf(ChildActor.props, key)
然后MyProcessingActor
可以使用该ActorRef
进行所有处理。
【讨论】:
【参考方案2】:不幸的是,这在 Akka 中似乎是一件相当困难的事情。创建一个actor来管理对地图的访问被证明是相当麻烦的,而且最新版本似乎不支持STM。
因此,这里的解决方案是仔细选择ConsistentHashingRouter
的键,这样在读取和写入映射时就不会出现任何竞争条件。有问题的地图是ConcurrentHashMap
【讨论】:
【参考方案3】:当一个 Actor 实际运行时,它会作为 Runnable
在某个 Executor 上运行。顺序运行一组协作的 Actor 的技巧是为每组这样的 Actor 提供一个专用的串行执行器 - 请参阅 my answer to the corresponding question。
【讨论】:
【参考方案4】:如果地图是 Actor 实例上的一个字段,那么就会有两个地图,不会出现跨线程问题。如果地图是共享的但只读的,那么你仍然可以。如果地图是共享的并且两个参与者都向它写入,那么您肯定需要使用 ConcurrentHashMap 进行锁定。
【讨论】:
您在这里并没有真正回答问题,只是重复了问题已经说明的内容。 “还有哪些其他推荐的方法?” 没错。我要指出的是,如果不共享地图,则不会发生冲突。因此,不需要替代方法。如果要共享地图,那么 ConcurrentMap 将是正确的选择。 这些是共享的:因此,2 个不同的 actor 实例可以同时读取和写入此地图。以上是关于Akka:跨参与者实例共享状态的主要内容,如果未能解决你的问题,请参考以下文章