P001使用VERSANT分布式面向对象云数据库的大型多人在线游戏性能Versant白皮书作者:DerekLaufenbergVersantChina上海市昆明路572号B区415-419室邮箱:info@versant.com.cn电话:(021)51721968传真:(021)51721967网址:摘要详细的游戏模型和机器模拟被用来生成对数据库服务器的真实负载。收集到的计时数据证明了测试硬件的能力,并且指明了数据库服务器所能够支持的玩家数量的上限。引入“玩家—分钟”这个概念是为了将性能的数据规格化,推断出昀大在线玩家负载。使用价格低廉的硬件和250个玩家的测试负载,收集到的计时数据显示,服务器的性能要比实时要求快上成百上千倍。只要服务器的性能比实时要求快就可以支持新增的玩家,这也证明了支持七万多名玩家所必须的系统带宽。概述这个例子使用的是一个非常详尽的持久性对象模型。该模型不严格地建立在当今非常盛行的拥有大量玩家—角色数据的大型多人在线游戏上(例如WoW,EverQuest)。这个模型的设计目标是要对游戏服务器在数据库服务器上运行的一系列操作进行测试。测试客户端执行影响游戏角色持久性状态的模拟游戏动作。被改变的对象和新建的对象会尽快地被传送到数据库,整套操作都会重复进行。测试客户端可以尽快地运行以试图达到数据库的性能极限。对一组动作收集的计时数据可以用来衡量一组模拟玩家在线时数据库的性能。对一个“普通的玩家”来说,在给定的游戏时间单位内会对数据库生成的一定量的负载。为了使计时数据规格化,所以使用了“玩家—分钟”游戏活动的概念。玩家—分钟被定义为玩家在一分钟的时间完成的所有的动作以及这些动作的频率。单个动作的频率各不相同,但是作为一个综合的估算值,所有的动作将能够代表大量玩家在服务器上施加的数据库负载。因为有些动作可能一个小时之内只会出现几次,而另一些动作一分钟内就会出现很多次,所以一些动作会有小数值。使用了这个模型以后,就有可能实现其它的负载配置。游戏设计者可以调优或是测试不同的游戏概念,观察数据库负载的结果。这份白皮书讨论了角色登录配置以及活跃玩家活动配置。活跃玩家配置假定一个大量创建和删除物品的非常活跃的玩家。游戏模型下面的UML(统一建模语言)图描述了用C++来完成的游戏持久化类模型。玩家及其支持的类都被用来模拟游戏服务器中一个典型的的操作。当对象通过不同的玩家动作改变之后,这些对象会被写回到服务器里。因为大多数大型多人在线游戏都与玩家的装备和行会P003有关,所以这些概念可以在模型和用例里得以详细化。例如,载入一个玩家的性能很大程度上依赖于该玩家拥有的物品数量。当载入一个玩家时,他所拥有的全部物品也都将被载入。玩家所拥有的对象会被载入到测试客户端,并在服务器上被锁住,以防止其它的进程改变它。这个载入和加锁进程可以防止各种游戏问题的出现,比如复制故障。图1游戏模型统一建模语言为了进行测试,每一个玩家都会有100个物品,但是根据物品创建/删除用例,物品列表可以增加或缩减。在这个模型中,玩家创建的物品比删除的物品更多,所以过了一段时间,玩家在他们的物品栏中就会有200至300个物品。根据这个模型,每个玩家的角色P004大约使用16KB的空间。这可能要比现在大多数大型多人在线游戏使用的要详细得多,但是这可以使游戏对象之间进行更多的互动。例如,在这个模型中,可以设计成当发生交易时物品能够追踪到它以前的主人。这可以被用于社交网络游戏机制,或用于某种形式的欺诈侦测。测试条件这个测试在一个简单的两台机器组成的配置上进行。一台WindowsXP笔记本用来运行测试客户端软件。另外一台能力稍强的台式计算机则用来运行数据库服务器。一个专门的1GBit的以太网被用来连接客户端和服务器系统。客户端机器服务器机器IntelT7200Core2Dual2.0GHzIntelQ6600Core2Quad2.4GHz2GBRAM4GBRAMWindowsXP32bit–SP3Linux564bit数据库测试群体测试数据库有5万个帐户,每个帐户有5个玩家。每个玩家有100个物品。数据库也已创建了5000个行会以及随机玩家构成的成员名单。数据库的空间大小为8GB,跨两个文件卷。磁盘驱动器则是成本低廉的7200RPMSATA磁盘驱动器,是台式机系统使用的典型的磁盘驱动器。DatabasePopulation50000instancesof'Account'250000instancesof'Player'250000instancesof'PlayerTaxi'250000instancesof'PlayerZones'250000instancesof'PlayerBulkData'250000instancesof'PlayerHighFreq'250000instancesof'Mailbox'250000instancesof'Bank'P005250000instancesof'Pet'250000instancesof'VISetQuest'25049127instancesof'Item'5000instancesof'Guild'30000instancesof'GuildRank'5000instancesof'Quest'10004instancesof'ItemDescriptor'登录测试案例通常登录和角色选择进程是由不同的服务器,甚至可能是由不同的数据库服务器来处理的。因为Versant能够跨不同的数据库引用对象,所以,很自然可以将帐户数据放进它自己的数据库,然后使用LOID(逻辑对象标识)引用已选中的角色进行载入。这个测试的目的就是要通过将动作限制在登录进程所包含的动作中--查询、角色选择和更新帐户信息,来重现登录时的情况。登录功能对一个随机产生的用户名进行查询。该用户名和测试数据库的5万个帐户里的某个用户名相匹配。用户的帐户对象随后被载入测试客户端,对象被修改后,排队等候被写入服务器。一个角色的LOID(逻辑对象标识)也会被放入玩家的载入队列中,所以玩家的角色就能够被载入。这在在线系统中是非常典型的操作。在这个例子中,没有玩家被实际载入,所以登录进程的带宽是可以估算的。启动一系列的测试客户端将负载加到客户端机器和数据库服务器上。每个测试客户端在每个样本周期都会执行1000次登录。每个客户端都会计算所有的登录和所用的时间。可以用Windows任务管理器和Linux的“iostat”命令来记录CPU的利用率,通过测试客户端来计算吞吐量(登录次数/秒)。登录测试结果登录客户端的数量不断增加,直到客户端计算机的CPU的利用率达到80%。对于这个硬件配置,可以在客户端的机器上运行总共8个登录客户端。P006LoginProcessing0100020003000400050000246810ClientsLogin/sec图2:每秒钟登录数量登录进程包括将每个帐户对象及登录事件产生的更新信息写回到数据库。没有创建任何新的对象,但是本次测试中依然包括查询、读取和更新这些负载被加到数据库上。因为写回到服务器上的数据量很少,所以本次测试主要是受到服务器上CPU的限制。LoginProcessingServerCPU01020304050600123456789ClientsServerCPU%图3数据库服务器上CPU的利用率P007即使使用这样十分有限的硬件,也可以实现每秒钟4000多次登录。看看服务器上CPU的使用情况,我们就可以看出到一个相当线形的响应曲线,并且只使用了50%服务器的CPU。任何达到每秒钟4000次登录的游戏都将会是非常成功的游戏,而一个单独的Versant数据库服务器可以支持这些登录次数或更多登录次数。游戏运行测试游戏服务器运行测试包括一组玩家的动作,这些动作被连接在一起以模拟当玩家游戏时,游戏服务器给数据库的负载压力。测试程序根据给定的玩家人数来决定每一个动作以及玩家的一组动作的执行频率。在一个测试周期内,这些动作被调用很多次。一分钟的测试周期被作为一个基准,但实际程序并不限定为一分钟。实际上昀终的测试在比一分钟短得多的时间内来完成相当于一分钟的数据库工作量。这样做有利于在一个较短的时间内完成测试,并将其规格化以预测数据库服务器能支持的全部负载。动作的数量是根据玩家在一分钟游戏时间内执行动作的次数来估算的。因为大多数游戏系统设计为每分钟将数据库和玩家状态同步一次,所以一分钟是一个合理的测试基准周期。在测试时,动作列表被不断执行并计时以计算系统的性能指标。下面的表格描述了250个玩家在一分钟游戏时间内所执行的动作及其次数。测试的目的是通过创建很大的数据库负载来增加数据库服务器的压力,因为正是因为这样,所以应用程序是不受限制的并且测量时间比一分钟的目标要短得多。动作次数/周期描述登录1随机的帐户查询,玩家检索玩家载入1玩家的图片和物品被载入金钱更新500玩家对象被更新:金钱,经验,位置行会名册读取2行会,等级,成员载入加入行会1玩家离开一个行会,加入另一个创建物品250一个新物品对象被创建并放入物品栏写入列表1将变化的对象写入数据库服务器删除物品200玩家物品被删除更新物品500物品被改变和更新P008物品堆栈大小500物品的数量被改变(类似于更新)完成探索250玩家的新探索对象被创建朋友25玩家的朋友列表被改变忽略25玩家的忽略列表被改变玩家退出1玩家离开模拟退出列表1退出对象被发送到数据库,并从内存释放检查点1任何其它的新对象/脏对象被写入数据库在测试程序中,通过修改表格可以调整这些动作的混合比例,以适合游戏服务器的预期配置。这个负载的对象是250玩家-分钟的游戏时间。就是250个玩家在测试“区”中执行一分钟时间的不同动作。可以把它看成一个很大的测试区。玩家被随机选取,以避免由于磁盘一起读写协同定位引起的性能偏差。这个实验所使用的测试动作集在物品操纵上有很大的负载压力,包括大量的创建、删除以及对单纯现有物品的更新。可以认为,这些数量大致代表了实际上超过250玩家分钟的游戏活动。这个配置在每个周期有效地更改1000个物品,创建250个新物品。同时还在每个周期删除200个物品。在动作表上列出的还有一些数据库专门的操作:写入列表,退出列表,和检查点。这些动作被用来强制测试客户端把更改的或新建的对象推送到服务器。这些调用引起网络和数据库的输入输出,占用了客户端的大部分时间。定期检查点为服务器提供了一个在测试模拟中所有游戏对象的一致状态。当发生检查点时,任何没有被其它操作显式写入的新对象或脏对象将被发送到数据库。这种模式不断地将数据流传送到数据库服务器上。退出列表动作对于客户端的内存管理很重要。当一个玩家离开模拟,这个退出玩家的对象被从缓存刷新到数据库并将内存归还到堆。登录和玩家载入动作增加一个新玩家以替代退出的玩家,使测试达到平衡。游戏测试结果该测试案例可以运行1700多个周期。收集到的计时信息可以用来制作出如下的表。记住,因为目标负载量是每个周期250玩家分钟,所以这个负载代表的是250个玩家29个小时的游戏时间。幸运的是,实际上只需要5分多钟的时间来进行测试。P009250-playerminuteperiods0500100015002000250030003500400016:12:4316:13:2616:14:1016:14:5316:15:3616:16:1916:17:0216:17:4616:18:29wallclockPeriodmSPeriod图4250玩家-分钟负载计时样本在运行的过程中,平均用了176毫秒就完成了一个测试周期,或者说一分钟可以完成340个测试周期。目标负载量是一分钟,那么这样做会比实时动作快上340倍,这也代表了数据库服务器一般的负载量。观察一下服务器的统计数字,iostat显示30%到60%的磁盘利用率被用来“等待”(等待磁盘命令的平均时间),“等待”时间为3-50毫秒。而在整个测试的运行过程中CPU的使用率是40%到