【问题标题】:Akka and state among actors in cluster集群中参与者之间的 Akka 和状态
【发布时间】:2011-07-26 18:51:34
【问题描述】:

我正在研究我的 bc 论文项目,该项目应该是一个用 scala 和 Akka 编写的 Minecraft 服务器。服务器应该可以轻松地部署在云中或集群上(不确定我是否使用了正确的术语......它应该在多个节点上运行)。然而,我是akka的新手,我一直想知道如何实现这样的事情。我现在要解决的问题是如何在不同节点上的参与者之间共享状态。我的第一个想法是让 Camel actor 从 minecraft 客户端读取 tcp 流,然后将其发送到负载均衡器,负载均衡器将选择一个处理请求的节点,然后通过 tcp 向客户端发送一些响应。假设我有一个 AuthenticationService 实现参与者,它检查用户提供的凭据是否有效。每个节点都会有这样的参与者(或者可能更多),并且所有参与者都应该始终拥有完全相同的用户数据库(或状态)。我的问题是,保持这种状态的最佳方法是什么?我想出了一些我能想到的解决方案,但我还没有做过类似的事情,所以请指出错误:

解决方案 #1:将状态保存在数据库中。这对于这个身份验证示例可能非常有效,其中状态仅由用户名和密码列表表示,但在状态包含不能轻易分解为整数和字符串的对象的情况下,它可能不起作用。

解决方案 #2:每次向某个参与者发出会更改其状态的请求时,该参与者将在处理该请求后,将有关更改的信息广播给所有其他相同类型的参与者,这些参与者将更改其状态根据原始参与者发送的信息进行状态。这似乎非常低效且相当笨拙。

解决方案#3:让某个节点充当某种状态节点,其中会有代表整个服务器状态的参与者。除了此类节点中的参与者之外,任何其他参与者都没有状态,并且每次需要一些数据时都会询问“状态节点”中的参与者。这似乎也效率低下,而且有点防错。

所以你有它。我真正喜欢的唯一解决方案是第一个,但就像我说的那样,它可能只适用于非常有限的问题子集(当状态可以分解为 redis 结构时)。更有经验的大师的任何回应都会非常感激。 问候,托马斯·赫尔曼

【问题讨论】:

    标签: scala cluster-computing akka actor akka-cluster


    【解决方案1】:

    解决方案 #1 可能会很慢。此外,它是一个瓶颈和单点故障(意味着如果带有数据库的节点发生故障,应用程序将停止工作)。解决方案 #3 也有类似的问题。

    解决方案 #2 并不像看起来那么简单。首先,它是单点故障。其次,读取或写入没有原子性或其他顺序保证(例如规律性),除非您执行total order broadcast(比常规广播更昂贵)。事实上,大多数分布式寄存器算法都会在后台进行广播,因此虽然效率低下,但可能是必要的。

    根据您的描述,您的分布式寄存器需要原子性。我所说的原子性是什么意思?原子性意味着在并发读写序列中的任何读取或写入都好像发生在单个时间点上。 非正式地,在解决方案 #2 中,单个参与者持有一个寄存器,这保证如果发生 2 次后续写入 W1 和 W2 到寄存器(意味着 2 次广播),则没有其他参与者读取这些值从寄存器中读取它们的顺序与第一个 W1 然后 W2 不同(实际上比这更复杂)。如果您查看几个后续广播示例,其中消息在不同时间点到达目的地,您会发现根本无法保证这样的排序属性。

    如果排序保证或原子性不是问题,某种基于 gossip 的算法可能会起到将更改缓慢传播到所有节点的作用。这在您的示例中可能不会很有帮助。

    如果您想要完全容错和原子,我建议您阅读 Rachid Guerraoui 和 Luís Rodrigues 撰写的关于可靠分布式编程的book,或与分布式寄存器抽象相关的部分。这些算法建立在消息传递通信层之上,并维护一个支持读写操作的分布式寄存器。您可以使用这样的算法来存储分布式状态信息。但是,它们不适用于数千个节点或大型集群,因为它们无法扩展,通常在节点数量上具有复杂性多项式。

    另一方面,您可能不需要将分布式寄存器的状态复制到所有节点 - 将其复制到节点的子集(而不是仅一个节点)并访问这些节点以读取或写入它提供了一定程度的容错能力(只有当整个节点子集发生故障时,寄存器信息才会丢失)。你可以调整书中的算法来达到这个目的。

    【讨论】:

    • 嘿,非常感谢您的回答。这似乎比我想象的要难:]。实际上,我将不得不考虑一段时间来弄清楚我是否真的需要操作的原子性。我去看看书,谢谢你的提示。或者,也许我可以将其他节点用作主节点的从节点,主节点将保存所有信息,其他节点只会接收消息并对从主节点接收的数据进行一些计算。不过还是感觉不对。
    • 不客气。请记住,拥有主节点的问题始终是它是单点故障。如果您担心容错,那可能是个问题。也许您还可以查看一些分布式哈希表实现,看看它们是否可以帮助您(例如 Apache Cassandra)。
    • 是的,容错并不是什么大问题。反正不在这个阶段。此外,无论如何,我都需要定义中的某种特权节点。 Minecraft 客户端将连接到的那个。
    猜你喜欢
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多