Scala + Akka:如何开发多机高可用集群

26
我们正在使用Scala+Akka为一款游戏开发服务器系统,该系统将为Android、iPhone和Second Life客户端提供服务。这个服务器的某些部分需要高可用性,能够在多台机器上运行。如果其中一个服务器失效(比如硬件故障),系统需要继续运行。我希望客户端有一份机器列表,类似于Cassandra的工作方式。

到目前为止,我看到的Akka的多节点示例似乎都是围绕可扩展性而设计的,而不是高可用性(至少在硬件方面)。多节点示例似乎总是有单点故障。例如,有负载均衡器,但如果我需要重新启动其中一个拥有负载均衡器的机器,我的系统将会遭受一些停机时间。
是否有任何示例展示了如何在Akka中实现此类型的硬件容错?或者,您是否有任何关于实现这一目标的好方法的想法?
到目前为止,我能想到的最好答案是研究Erlang OTP文档,对它们进行深思熟虑,并尝试使用Akka中可用的组件来构建自己的系统。

但是,如果有资源、示例或关于如何以一种方式在多台机器之间共享状态的想法,即使其中一台机器出现故障也可以继续运行,我将非常感激,因为我担心自己可能正在重复发明轮子。也许有一个多节点STM容器,可以自动跨多个节点同步共享状态?或者,这么做非常简单,文档没有展示如何实现的示例,或者我还没有进行足够的研究和实验。任何想法都会受到赞赏。

对于共享状态,也许我应该实现一种Zookeeper领导者选举类型的算法。在集群中,每个机器都有一个NodeManager actor。第一个节点成为领导者。每个后续节点成为追随者,下一个节点成为那个追随者的追随者。当领导者死亡时,下一个节点接替他的位置。领导者向追随者分享他的状态,以此类推。 - Unoti
更新,目前正在考虑基于JGroups构建解决方案。Akka的集群成员代码使用JGroups。 - Unoti
我确实看了一些JGroups,但后来我走了一条弯路,用Erlang工作了一段时间。事实上,我用Erlang写了相当多的应用程序,并且几乎一直在那里工作。但是,在研究和使用OTP一段时间后,我意识到我可以使用Akka中的设施来完成我需要做的事情。我认为,对于这个应用程序,我真正需要的只是使用远程actor通信的一些共享状态,并且让客户端连接到几个不同的主机名,其中至少有一个会在线。我目前正在使用Scala+Akka重新编写我用Erlang编写的代码。我认为它会起作用。 - Unoti
4个回答

5

高可伸缩性的一个非常重要的方面是HA和负载管理,这是作为AkkaSource商业套餐的一部分提供的。


谢谢,维克托。我在研究过程中也遇到了这个问题:http://groups.google.com/group/akka-user/browse_thread/thread/636e08b7199c9e46?fwc=2 - Unoti
只是想补充一下:目前为止,他们正在开源化这个项目。http://groups.google.com/group/akka-user/browse_thread/thread/132b40035d3ced38 - Blub
它将会在2.0版本中发布,该版本将于今年晚些时候发布。 - Viktor Klang

3
如果您已经在客户端中列出了多个潜在主机,则它们可以有效地成为负载均衡器。您可以提供主机建议服务并向客户推荐应连接到哪台机器(基于当前负载或其他因素),然后客户端可以将其固定连接到该机器,直到连接失败。如果没有主机建议服务,则客户端可以从其内部列表中随机选择一台主机,尝试连接直到连接成功。理想情况下,在首次启动时,客户端将连接到主机建议服务,不仅会被指示连接到适当的主机,还会得到其他潜在主机的列表。每次客户端连接时,此列表都可以定期更新。如果客户端第一次尝试连接时主机建议服务不可用(不太可能,但是...),则您可以预先部署主机列表到客户端安装中,以便它在最开始时立即随机选择主机。确保您的主机列表是实际的主机名,而不是IP地址,这样可以在长期内更加灵活(即使您移动基础设施并更改IP地址,您也将始终拥有host1.example.com、host2.example.com等主机名)。

谢谢您先生。我会按照您的建议去做。现在我只需要想办法让这些主机之间共享状态,使用主动-主动或主动-被动的方法。看起来我需要构建它,并且希望确保我没有构建已经在Akka中准备好使用但是我没有注意到的东西。 - Unoti

3

您可以查看RedDwarf及其分支DimDwarf的构建方式。它们都是水平可扩展的崩溃式游戏应用服务器,而DimDwarf部分使用Scala编写(新的消息功能)。它们的方法和架构应该非常适合您的需求 :)


dimdwrf网站上有一些很棒的文章链接。 - Bessi

2
“如何在多台机器之间共享状态,以使一台机器宕机时仍能保持运行?”请勿在多台机器之间共享状态,而是将状态分区到不同的机器上。我不知道您的领域,所以我不知道这是否适用。但基本上,如果您将某些聚合(在DDD术语中)分配给某些节点,则可以在使用它们时将这些聚合(actor、agent等)保留在内存中。为此,您需要使用类似于Zookeeper的东西来协调哪个节点处理哪个聚合。在发生故障时,您可以在另一个节点上启动聚合。
此外,如果您使用事件源模型构建聚合,那么其他节点几乎可以轻松地通过监听事件并维护自己的副本,在其他节点上实时复制(从属)您的聚合。
通过使用Akka,我们可以免费获得节点之间的远程通信。这意味着任何处理可能需要与另一个节点上的Aggregate/Entity交互的请求的节点都可以使用RemoteActors进行交互。
我在这里概述的是非常普遍的内容,但提供了一种使用Akka和ZooKeeper实现分布式容错的方法。它可能有用,也可能无用。希望对您有所帮助。
祝一切顺利, 安迪

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接