讨论一下MMORPG中数据库的访问策略

73 views
Skip to first unread message

agile java

unread,
Jul 7, 2009, 2:01:02 AM7/7/09
to dev4s...@googlegroups.com
最近在做一个MMORPG的游戏,对于数据库的访问策略一直拿不准如何处理,在这里想听听大家的意见。

先简单说一下我的想法:

从数据库加载玩家数据,在玩家登录时完成,之后就不再访问数据库了。

在游戏中,所有对玩家数据的修改都只在内存中进行,同时将修改的数据通过定义的消息发送到一台backup server(一个区中共享一台)中,在backup server中有简单的业务处理来记录数据的修改信息。

玩家下线时,将内存中的数据一次更新到数据库,同时通知backup server删除该玩家的数据。

如果服务器崩溃,则将backup server中的所有玩家数据更新到数据库中。

这样可以大大的减少数据库的负担,而且在游戏中基本不会涉及到数据库的操作,所有的业务逻辑全部针对内存中的数据操作,就是实现起来会麻烦一些。

在这儿想请大家讨论一下这种做法可行否,以及自己在这方面的经验,谢谢。









--
d0ngd0ng

Lei Gu

unread,
Jul 7, 2009, 2:30:32 AM7/7/09
to dev4s...@googlegroups.com
比较可行,只要机房不断电,问题不大

2009/7/7 agile java <agile...@gmail.com>

Allen Jiang

unread,
Jul 7, 2009, 2:38:26 AM7/7/09
to dev4s...@googlegroups.com
1.万一backup server崩了呢?
2.数据库的数据的全部加载过来数据量的问题?
3.多台服务器的数据同步问题?

Lei Gu

unread,
Jul 7, 2009, 3:03:21 AM7/7/09
to dev4s...@googlegroups.com
1. backup server崩了,重新启动,然后再重新收集数据
2. 只加载在线玩家数据,不是全部
3. 数据在多台服务器中应该只存在一个可写copy,不存在同步问题,而且这只是个backup server

2009/7/7 Allen Jiang <jianggui...@gmail.com>

Allen Jiang

unread,
Jul 7, 2009, 4:05:34 AM7/7/09
to dev4s...@googlegroups.com
1. backup server崩了,重新启动,然后再重新收集数据
那么在一段时间内的数据还是会丢失,
2.那么你的backup server起的作用只是DB proxy,A服务器要取得玩家数据的话,还是要跨服务器去访问取得,你测过这个过程和从DB中取得快多少没?比如说mysql,并不是每次取数据都是从数据库里读取,也有缓存机制在利用。
 
你的实现方案看上去是登陆时一次加载,登出时一次写入操作这样一个过程,只是把DB偷换成了backup server,是不是这样的?

Kouga

unread,
Jul 7, 2009, 4:09:32 AM7/7/09
to dev4s...@googlegroups.com
该想法可行,而且也应该是一般性实现吧?因为数据库无论怎么说,都是一个低速存储容器。(为应用加速编写的在内存中存活的数据库不算~)

因为游戏数据变量较大(一次交易即可看做由几个步骤形成的原子操作),而将每个步骤都记录在案或者同步到数据库没有必要,而且很多时候还存在撤销的可能性——这样只需要在内存中稍稍动作一下就能释放该资源了,然后再在后续步骤进行的时候,让backup server来通过接口遍历“正在进行的历史”即可。甚至于,正在进行的历史,可以由swap来镜像。

2009/7/7 Lei Gu <jack...@gmail.com>



--
签名是什么东西??

Lei Gu

unread,
Jul 7, 2009, 4:34:48 AM7/7/09
to dev4s...@googlegroups.com
你没有理解好,只是backup server,不是db proxy


2009/7/7 Allen Jiang <jianggui...@gmail.com>

agile java

unread,
Jul 7, 2009, 4:35:49 AM7/7/09
to dev4s...@googlegroups.com
这个方法主要考虑到得就是在游戏的过程中玩家的数据变化很快,如果要把每次的变化都更新到数据库里,数据库的负载将成为系统的瓶颈,也会影响玩家的体验。



2009/7/7 Kouga <ncw...@gmail.com>



--
d0ngd0ng

Lei Gu

unread,
Jul 7, 2009, 4:40:25 AM7/7/09
to dev4s...@googlegroups.com
我们的MMORPG就是用的这个方案,单台数据库服务器支持接近上万人同时在线,数据库不是瓶颈,很不错。只有一次整个机房突然停电,造成了一次回档。

2009/7/7 agile java <agile...@gmail.com>

kennywong

unread,
Jul 7, 2009, 6:35:33 AM7/7/09
to 高性能网络编程邮件列表

On 7月7日, 下午4时40分, Lei Gu <jackf...@gmail.com> wrote:
> 我们的MMORPG就是用的这个方案,单台数据库服务器支持接近上万人同时在线,数据库不是瓶颈,很不错。只有一次整个机房突然停电,造成了一次回档。
>

> 2009/7/7 agile java <agile.j...@gmail.com>
>
>
>
> > 这个方法主要考虑到得就是在游戏的过程中玩家的数据变化很快,如果要把每次的变化都更新到数据库里,数据库的负载将成为系统的瓶颈,也会影响玩家的体验。
>
> > 2009/7/7 Kouga <ncwh...@gmail.com>


>
> > 该想法可行,而且也应该是一般性实现吧?因为数据库无论怎么说,都是一个低速存储容器。(为应用加速编写的在内存中存活的数据库不算~)
>

> >> 因为游戏数据变量较大(一次交易即可看做由几个步骤形成的原子操作),而将每个步骤都记录在案或者同步到数据库没有必要,而且很多时候还存在撤销的可能性--- -这样只需要在内存中稍稍动作一下就能释放该资源了,然后再在后续步骤进行的时候,让backup


> >> server来通过接口遍历"正在进行的历史"即可。甚至于,正在进行的历史,可以由swap来镜像。
>

> >> 2009/7/7 Lei Gu <jackf...@gmail.com>
>
> >>> 1. backup server崩了,重新启动,然后再重新收集数据2. 只加载在线玩家数据,不是全部


> >>> 3. 数据在多台服务器中应该只存在一个可写copy,不存在同步问题,而且这只是个backup server
>

> >>> 2009/7/7 Allen Jiang <jiangguilong2...@gmail.com>


>
> >>> 1.万一backup server崩了呢?
> >>>> 2.数据库的数据的全部加载过来数据量的问题?
> >>>> 3.多台服务器的数据同步问题?
>
> >>>> ----- Original Message -----

> >>>> *From:* agile java <agile.j...@gmail.com>
> >>>> *To:* dev4s...@googlegroups.com
> >>>> *Sent:* Tuesday, July 07, 2009 2:01 PM
> >>>> *Subject:* 讨论一下MMORPG中数据库的访问策略


>
> >>>> 最近在做一个MMORPG的游戏,对于数据库的访问策略一直拿不准如何处理,在这里想听听大家的意见。
> >>>> 先简单说一下我的想法:
>
> >>>> 从数据库加载玩家数据,在玩家登录时完成,之后就不再访问数据库了。
>
> >>>> 在游戏中,所有对玩家数据的修改都只在内存中进行,同时将修改的数据通过定义的消息发送到一台backup
> >>>> server(一个区中共享一台)中,在backup server中有简单的业务处理来记录数据的修改信息。
>
> >>>> 玩家下线时,将内存中的数据一次更新到数据库,同时通知backup server删除该玩家的数据。
>
> >>>> 如果服务器崩溃,则将backup server中的所有玩家数据更新到数据库中。
>
> >>>> 这样可以大大的减少数据库的负担,而且在游戏中基本不会涉及到数据库的操作,所有的业务逻辑全部针对内存中的数据操作,就是实现起来会麻烦一些。
>
> >>>> 在这儿想请大家讨论一下这种做法可行否,以及自己在这方面的经验,谢谢。
>
> >>>> --
> >>>> d0ngd0ng
>
> >> --
> >> 签名是什么东西??
>
> > --
> > d0ngd0ng

那公共数据呢,假设我要做个交易所,玩家可以在上面买卖物品.

关中刀客

unread,
Jul 7, 2009, 6:59:15 AM7/7/09
to 高性能网络编程邮件列表
逻辑服务器都只是将玩家的信息写入到共享内存中,即使宕机了,重启的时候读取这个内存映射文件,再次的写回数据库即可

> 那公共数据呢,假设我要做个交易所,玩家可以在上面买卖物品.- 隐藏被引用文字 -
>
> - 显示引用的文字 -

Kouga

unread,
Jul 7, 2009, 1:49:29 PM7/7/09
to dev4s...@googlegroups.com
Linux系统和Unix系统有做这种事情的很好的基础~另外,考虑热机替换的话,仍旧可行。
(服务器再怎么也该有个UPS啊……只要能够满足一周期数据巡幸即可……话说备份停电最后“凝固”的数据其实很快的吧?

2009/7/7 关中刀客 <guanzho...@gmail.com>



--
签名是什么东西??

Kouga

unread,
Jul 7, 2009, 1:50:32 PM7/7/09
to dev4s...@googlegroups.com
公共数据该在哪里存储就在那里存储——换句话说,它们也一样在内存里,只是定时不定时的备份当前状况去数据库而已。

2009/7/7 kennywong <huangw...@21cn.com>



那公共数据呢,假设我要做个交易所,玩家可以在上面买卖物品.




--
签名是什么东西??

agile java

unread,
Jul 7, 2009, 9:49:02 PM7/7/09
to dev4s...@googlegroups.com
受教了,谢谢大家 :)

2009/7/8 Kouga <ncw...@gmail.com>



--
d0ngd0ng

kilnt

unread,
Jul 9, 2009, 3:30:14 AM7/9/09
to dev4s...@googlegroups.com

bdb值得考虑 kv 的结构对存玩家属性足够用了,mysql 还是太重。 
gs 产生的数据大都没啥关联。就是个log而已。

不过这根账号角色对应策略关系比较大。

liam

unread,
Jul 13, 2009, 10:56:13 AM7/13/09
to 高性能网络编程邮件列表
通常会同时使用定时策略和即时策略,定时从玩家上线后每隔一段时间存储一次一般半小时,即时策略当玩家下线或服务器宕机会立即存储
那么怎么服务器宕机还能够立即存储呢,这里会使用共享内存,它是与共享内存服务器共享数据,一般与游戏服务器和世界服务器(包含需要存档数据的)在同一
台,也可以与数据库服务器同一台,依靠数据包通知更新
共享内存服务器负责存储策略,和数据库打交道,共享内存服务器逻辑简单不容易宕掉

Kouga

unread,
Jul 16, 2009, 10:24:11 AM7/16/09
to dev4s...@googlegroups.com
喵~共享内存服务器只需要提供 读 和 写 的简单接口,并且可以双机热备份,所以不容易翘掉,呵呵。

然后,游戏主逻辑就在这里面调度整个世界~而后台备份服务器则慢吞吞的一点点将数据挪去数据库保存。

2009/7/13 liam <liam...@hotmail.com>



--
签名是什么东西??
Reply all
Reply to author
Forward
0 new messages