我想在我的server.exe中使用sql数据库。
假设有1000位用户在线。玩家在玩游戏时会更改其数据。服务器需要保存这些更新。
但是如何?
我认为有两种方法:
1)服务器将在运行时保存在ram中,并且有时或每小时服务器将从ram将数据(更新)写入sql数据库。但是,如果断电或服务器关闭,更新将无法保存。当然,我不想丢失更新。
2)服务器将在运行时将更新保存在数据库中。但是速度会怎样?我想到了一种方法。我将在下面显示图片。通过这种方法,我能否为1000名在线玩家获得足够的速度?
我想在我的server.exe中使用sql数据库。
假设有1000位用户在线。玩家在玩游戏时会更改其数据。服务器需要保存这些更新。
但是如何?
我认为有两种方法:
1)服务器将在运行时保存在ram中,并且有时或每小时服务器将从ram将数据(更新)写入sql数据库。但是,如果断电或服务器关闭,更新将无法保存。当然,我不想丢失更新。
2)服务器将在运行时将更新保存在数据库中。但是速度会怎样?我想到了一种方法。我将在下面显示图片。通过这种方法,我能否为1000名在线玩家获得足够的速度?
Answers:
我研究过或知道的大多数MMO(或使用类似体系结构的项目)都使用第一种方法:游戏服务器主要与运行服务器进程的计算机上的RAM配合使用,并且仅定期将相关游戏数据序列化到SQL数据库用于存档(如果已使用)。
您注意到的有关电源故障的问题是有效的,但它比过程中崩溃的问题要小(正常运行时间的可靠性通常是您要向数据中心支付的费用之一)。但是还是。您可以通过调整保存间隔(这样一来,故障最多仅花费几分钟的时间),在多台计算机之间分配保存队列,积极确定需要保存的数据量以及实施可重新启动的保存等方法来缓解这些问题。队列。
一般而言,使用SQL Server本身作为主内存会很慢(而且很麻烦)。我在您的提案中没有看到足够的细节,无法确定它是否仅适用于大约1000名玩家-可能会很好。但是我不相信您可以使其具有可扩展性。
此外,它不能解决问题。除非您执行相同类型的可重新启动保存队列的工作,否则保存过程中的电源故障仍然会丢失或破坏数据(即使这样做,也只会严重降低灾难性数据丢失的可能性,但并不能防止这种情况发生) 。
我建议您采用第一种方法。
1000个播放器可能有问题,也可能没有。这取决于您需要多久更新一次数据库。但是,有一个简单的解决方案:将数据库放在自己的服务器上。
我看了一眼数据库系统如何运作,人们称其为MMO-Lite的一种游戏-我不会透露。但我可以说它始终拥有1000多名玩家,这是抽象的:
在这种情况下,使用基于文档的数据库是提高性能的一个好主意。尽管这样做对执行联接和聚合操作不利,但对访问数据也有好处……但是他们不会对其中的数据进行访问。
另一方面,当他们需要为每个人执行一个对象与另一个对象的更改之类的操作时,需要运行一个逐个字符并逐个更新它们的后台脚本,这需要花费大量时间。
字符的数据既存在于客户机上,又存在于服务器上,并且系统旨在使它们保持同步,并在两侧进行相同的操作。
现在,当玩家使用系统进行交易时(例如,通过NPC或类似方式将某物品交换为另一物品),这具有以下阶段:
注意事项:
玩家之间的交易以类似的方式处理,有额外的规则可以防止玩家欺骗其他玩家,并且在需要撤销交易时具有额外的可追溯性。我听说有一段时间保存的所有事务的特殊日志(以解决有人抱怨时的问题),我不知道该部分的工作原理。
有时出问题了,这有两种可能的结果:
无论哪种情况,客户端都知道该错误,并将与播放器所做的所有操作一起记录下来。客户端日志一直在发生。然后,在注销时,如果出现错误,客户端会将日志发送到服务器。
该游戏不使用大多数MMORPG拥有的传统的每日或每周停机维护时间。计划的维护通常用于重置计数器,计时器,运行数据库过程。他们也有机会交换服务器版本以进行更新。
x:10,y:10,z:10
To x:11,y:11,z:11
,应该立即将其保存在数据库中吗?如果玩家不断奔跑,那意味着我们每1秒或更短的时间保存一次他的当前位置,如果有成千上万的玩家,那么每秒就有数百万条查询到数据库。这是怎么运作的?
两种方法都可用于MMORPG。将所有内容保留在内存中并定期检查将其指向磁盘似乎是最受欢迎的选择,至少对于较旧的游戏而言。它的优点是易于实施和扩展,但使其可靠完全取决于开发人员。SQL数据库提供了ACID属性,这些属性使可靠性更容易,但总体而言,实现起来更复杂,并且在扩展方面可能会遇到问题。
EVE Online是MMO的示例,其中所有内容都存储在SQL数据库中。我认为它达到了大约60,000个并发用户的峰值,并且多年来必须为数据库服务器提供一些昂贵的硬件,以跟上负载。但是,与大多数MMORPG相比,EVE每位用户存储的数据要多得多,并且交易频率和多样性也要高得多。数据库的ACID属性使整个庞大而复杂的数据库始终保持一致状态。
例如,考虑某人向另一个玩家提供物品的情况。EVE的数据库保证即使在崩溃或电源故障的情况下,该物品也只能存放在一个玩家的库存中。也就是说,从一个玩家的库存中删除该物品并将其添加到另一玩家的数据库交易是原子的。交易要么完全完成,要么根本不发生。您不能以该物品既不在玩家的物品库中又不在两者中的状态而结束。
MMORPG必须将播放器数据保存在内存中并定期检查点,才能自己实现这种原子性。一种方法是在每个播放器的数据上同时设置检查点,以确保新检查点在被视为最新检查点之前已完全提交到磁盘。游戏还必须确保在检查点时玩家数据不会更改。在拥有大量活跃玩家的情况下,挑战就变成了所有这一切,而又不会造成玩家会注意到的足够长的延迟。
不要低估一致性的重要性。在开发游戏时,它会崩溃很多。您不需要追踪为什么物品会消失和/或重复,而不是当问题是无关的错误导致游戏在糟糕的时间崩溃时就可以了。而且,当您的游戏上线时,崩溃的方式将比您预期的要多。您的服务器在测试中运行良好,突然就会在满负荷情况下暴露出许多错误,并且播放器会执行您未曾期望的错误。
请注意,大多数MMORPG都不使用SQL数据库来获取与帐户相关的信息,即使它们不是实际的游戏数据也是如此。比使游戏状态保持一致更重要的是保持计费状态保持一致。游戏数据库损坏的最坏情况是您必须从每日备份中还原数据库。帐户数据库损坏的最坏情况是,由于所有退款,您将破产。
对于您的项目,您可以选择任何一种方式。目前,拥有1000个并发用户可能不会突破SQL Server在商用PC上可以处理的限制,但是这在很大程度上取决于交易的性质。如果您熟悉SQL和关系数据库设计,那么它可以为您工作。您需要尽可能地减少事务,对于诸如玩家当前生命值之类的事情,您可能只想定期将它们保存到数据库中,因为此类统计数据不一定是一致的。(在PvP游戏中,他们可能会……)根本不将怪物HP之类的东西存储在数据库中,在大多数游戏中,只有与玩家相关的数据才是持久的。
另一方面,如果您不是SQL向导,则可能会发现将所有数据保存在内存中要简单得多,以使其可靠地工作。SQL数据库使一致性和可靠性更容易,但不是自动的。设计不良的数据库可能会导致性能下降并导致不一致。除非您这样做,否则交易不会是原子的。如果您不虔诚地使用参数化语句,那么您将容易遭受SQL注入攻击。
各种游戏以不同的方式存储事物。通常,游戏公司会创建某种方式来实现此目的,并且大多数游戏都使用相同的方式。当然,不同的工作室经常使用不同的方式。SQL当然是用于游戏的,例如CCP(EVE)拥有(或至少拥有)SQL服务器网络,我不确定他们现在是如何做到的。其他人,只需使用大量文件。
也许从创建一个不可知的“数据代理机制”开始,以处理各种游戏数据交易?由于您无论如何都只是在测试,因此请创建一种机制,使您无需从游戏本身的角度就太在乎存储。意思是,集中精力于如何从宿主应用程序中处理此问题。
我个人认为,如果您可以切换实际的商店而不必重写游戏和经纪人本身,那将是一笔巨大的财富。只需切换到具有相同接口的另一个模块,代理即可与之对话。
就其本身而言,存储数据本身可能不会成为问题。在主机和所有客户端之间有效地将数据传输到该存储/从该存储传输数据可能会比较棘手。我是否应交付整个播放器数据集,或者如果将其细分为多个部分,则选择按什么粒度进行分区等?在哪种情况下哪种资源消耗更多?
XML是一种用于发送数据的格式。这样,您就可以更轻松地动态地对其进行分块。一个字符对多个字符,或者一个项目对一组项目,等等。然后,您可以将XML作为“ XML”存储(在SQL中),和/或让SQL以更具事务性的方式将XML从XML分发到您希望如何实际存储数据。
另一种方法是二进制,在运输方面效率更高,但在其他情况下会产生更多成本。
如果有1,000个客户端,则可以从每个客户端开始轻松地存储10 MB,并且仅使用10 GB的有效RAM +添加一些系统管理RAM来管理该数据,例如再增加一到两个GB。您可以将其保留在主机上的RAM中,并且已经可以使用数据结构了。并根据谁在线来动态加载/保存,取决于活动等各种频率。
您甚至可以将每个客户的信息存储在单独的文件中,依此类推。