实时游戏的最佳服务器架构是什么?


10

我正在开发一款实时游戏,该游戏应能实时容纳数千名玩家(FPS,最大延迟为1秒)。最好的基础架构是什么?

我的想法是使用2个服务器群集-一个用于服务器端(所有计算端),一个用于数据库端,其中负载均衡器对每个群集都是“负责任的”。一台主服务器将接收来自用户的请求,并发回相关服务器的IP地址,以便用户可以使用该服务器。

数据库集群将使用数据库复制来确保数据库之间的一致性。

还应该有一个地理负载均衡器-因此它将为每个用户分配区域负载均衡器以获得最佳响应。

我正在使用.NET + MSSQL进行游戏。

谢谢!


2
当您说“基础设施”时,您是指软件,硬件,服务,还是只希望我们对现有计划进行评估?
四分

1
@Nate-我们正计划扩大规模,而不是重复-因此它应具有完全的可扩展性。
罗马

2
-1,因为teddziuba.com/2008/04/im-going-to-scale-my-foot-up-y.html-您未满足任何容量要求,您说游戏没有分片,但已划分区域性能优化的性质(包括可伸缩性)需要特定的信息,并且没有绝对的最佳架构。

1
我将您的问题改写为更具体的问题。以事实,非主观的方式来看,“最佳”是什么?您是说最容易扩展,最容易管理,最容易上手,最快还是什么?
共产党鸭子

1
“最简单”也是主观的。在什么时间范围内,给谁最简单的资源?Stack Exchange在遇到以下特定问题时效果最佳:“我已经使用LINQ和MSSQL构建了该服务器,但是它在每秒70个事务之后就崩溃了,这是我的前两个事务,占我运行时间的73%,我应该如何提高吞吐量? ”

Answers:


6

没有最好的架构,就没有最好的架构,例如。角色之间的互动类型,将要保留的数据量等等。

如果您可以应付1秒的延迟,则可以在一台服务器上托管1000个播放器而不会出现问题-但这实际上与FPS的想法相冲突,因为它们通常需要低得多的延迟。少于100ms。但是,可以处理高延迟的系统可以承受通过消息传递进行的所有操作,这使得一致性变得微不足道。提供您的逻辑非常简单,也就是说,当您将复杂的逻辑转变为基于消息的系统而不是锁定对象系统时,复杂的逻辑甚至会变得更糟-但是这完全取决于应用程序的需求。

同样,如果您不保留大量数据,则根本不需要数据库机,但是如果不知道这一点,就很难说了。如果您要保留少量数据,并且可能仅在比赛结束之类的时候这样做,那么您就不需要一个单独的数据库,当然也不需要它们的集群。另一方面,如果您不是很坚持,而是读了很多书,那么复制数据库可以为您提供帮助-但它也表明关系数据库可能并不是最适合您问题的数据库。通常,内存缓存是一种更好的解决方案。同样,如果字符之间没有事务样式的交互,则一致性变得不太重要。(并且,如果此类交易很少,则可以将它们作为特殊情况。)

实际上,请警惕仅在大型系统中就已采用RDBMS。尽管我本人确实赞成在在线游戏中使用它们,但最好查看您的需求并从中找出您的持久性策略,而不是选择您喜欢的数据库,然后尝试通过缓存和复制来对其进行调整,以使其适合您的需求。应用程式。您可能会发现,您所需要的只是离线报告功能,在这种情况下,最好让后台进程从您的游戏持久性机制登录到其他地方的远程RDBMS。


4

免责声明:我的游戏编程经验基于客户端单人游戏,但是我具有Web应用程序背景(尤其是Microsoft堆栈),因此我从这个答案中受益匪浅,我认为适用,但是如果没有对真实游戏服务器进行实际测试,就很难说出它将如何应用,但这是可行的。知道这一点:我尚未部署游戏服务器,仅部署了Webapp。

我建议采用两层(服务器)方法。数据库层和“应用程序”层;第三(展示)层是您的游戏客户端。

关系数据库擅长查询数据,并且擅长写数据。关键是将数据库写入序列化为集群可以处理的可管理大小的块。SQL Server的更高级版本(数据中心/企业版)支持群集和复制。我将从构建一个小型集群开始,并对它运行一些查询以了解其工作原理。

在应用程序层中,如果您正在执行“分区”或类似的操作,则可能无需设置任何集群就可以摆脱困境,而只需为每个区域设置一台服务器即可。如果区域变大,则可以为每个区域设置一个群集。

您将需要构建一个序列化过程,以从应用程序层->数据库层发送数据。关键是要进行多个级别的序列化。东西这样:

  • 级别1:每X秒保存到数据库,包括关键数据:
    • 球员健康
    • 玩家物品/皮卡
  • 级别2:每2X秒保存到DB,包括中等数据:
    • 玩家位置
    • NPC位置
  • 级别3:尽可能少地进行其他所有操作

这将使您的写入保持一致和可预测,具体取决于您的游戏的性质,您可能不经常进行数据库写入。关键是要意识到,如果您的应用程序服务器崩溃了,您必须从数据库中的状态恢复在线,因此每90分钟序列化玩家清单可能会使玩家感到沮丧。

为了读取数据,您需要将尽可能多的负载加载到应用程序层的内存中,然后确保所有代码都使用此内存池,在后台可以将内存池与数据库同步。正如Joe指出的那样,有时您需要“实时”交易。通过序列化大多数写入操作,您应该在数据库上仍具有足够的IO以在必要时进行实时事务,并假定数据库服务器/集群上具有足够的硬件。


-1,因为您刚刚淘汰了ACID,并且只是将数据库用作大数据存储。没关系,Windows的磁盘调度程序非常笨拙,仍然可以提高性能,您可以使用其中的数据进行一些整洁的脱机指标,但是您仍然需要ACID(即数据库)支持游戏本身中的交易,实时地。

虽然稀疏,但这是我在上一段中要讲的。我建议您使用某种混合方式,在可能的地方使用IN-Memory,在必要时使用数据库。
Nate

问题在于您已经弄清了内存中的内容,它是另一个完整的数据库,并且您没有给出如何实现的指示,这实际上是一个棘手的问题。

没错,尽管问题是关于全局架构,而不是实现细节。
Nate

没错,但是您没有考虑整个中间层。它是低延迟的RDB吗?一个ODB?键/值存储?没有数据库,放弃ACID吗?STM还是锁?公平地讲,很难回答这个问题,因为问题中没有太多信息,但是所有对架构图的回答都是中间带有“?”的大气泡。并在其中连接其他两个服务,而不是实际填写什么“?” 是。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.