gpt4 book ai didi

scala - Akka Stateful Actor 跨节点复制

转载 作者:行者123 更新时间:2023-12-05 05:16:58 26 4
gpt4 key购买 nike

我有一个 Akka 应用程序,我使用 Play Framework 作为 Web 应用程序运行。当我启动这个应用程序时,我创建了一组 Actor ,这些 Actor 有状态。这些参与者响应外部消息并改变状态(我使用 context.become(...) 机制改变状态)。

我现在想运行这个 Web 应用程序的多个实例,这样我就可以有弹性。但问题是 Web 应用程序公开了前端应用程序连接到的 WebSocket 端点。然后,我每 4 秒通过 WebSocket 端点将 Actor 实例的状态流式传输到前端应用程序。

我有几个问题:

  1. 我怎样才能运行我的 Play Framework Web 应用程序的更多实例,同时记住我有状态参与者!我想确保如果其中一个实例宕机,那个实例中的有状态参与者会恢复到宕机前的状态。 Akka Cluster Sharding 会是可行的方法吗?

  2. 假设我的应用程序中有 10000 个这样的 Stateful actor,我如何利用 Akka Cluster Sharding 使这 10000 个 actor 并非全部都在同一个节点中运行?我的意思是如何让前 5000 个 actor 在 node1 上运行,而后 5000 个在 node2 上运行?现在我对单个实例所做的是,当我启动我的应用程序时,我读取数据库并使用数据为每个数据库行启动一个参与者实例。

  3. 询问模式如何与集群分片配合使用?我发送到分片区域的任何消息都将被路由到相应的 Actor 实例,但是如何从特定的 actor 请求消息呢?它也会以同样的方式工作吗?我向 Actor 请求消息,我将询问请求发送到分片区域,然后该分片区域将此消息转发给相应的 Actor?这是正确的吗?

有什么建议吗?

最佳答案

设置 akka 集群有两种不同的方法:

  1. 按照您的建议让所有 Play Framework 实例形成一个集群
  2. 设置一个单独的 akka 集群(如果需要,可以称之为后端),并使用 Play Framework 实例中的集群客户端连接并与您的集群交互

在上述两种情况下,我都会使用集群分片模块来实现您想要实现的目标。

您不清楚您的 actor 状态当前是如何持久化的。是否所有状态更改都以某种方式写回数据库?如果您一无所有,Akka 持久性可能会对您有所帮助。

您的问题:

  1. 集群分片会负责将您的 actor 分成多个正在运行的实例,并在实例关闭或启动时迁移它们。集群分片根本不会处理你的 Actor 的状态。这是一个完全独立的问题,这就是我在上面提到 akka 持久性的原因。
  2. 使用 cluster sharding 时良好分配 Actor 的关键就是提供一个好的extractShardId和足够的分片。根据您的示例,每个节点很可能不会正好有 5000 个参与者,但它可能足够接近了。我建议从大量的分片开始,比您计划使用的集群实例的数量要多得多,100 是可以开始的。这加上一个好的 extractShardId 将在集群节点之间大致平均分配您的负载。
  3. 问的很好,你说的是对的。分片系统使用 extractShardIdextractEntityId 的组合将您的消息路由到正确的参与者实例。然后该 Actor 可以回复 sender()

注意事项:

  • 以上所有内容也可以通过集群客户端正常工作。
  • 根据您的需要,可能不需要从一开始就启动所有参与者。当您向尚不存在的分片 actor 发送消息时,该 actor 将由集群分片系统自动透明地启动。那时你可以恢复它的状态。这加上自动钝化可以帮助您节省大量资源!

关于scala - Akka Stateful Actor 跨节点复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49774513/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com