MMORPG Server - 数据存储

来源:互联网 发布:pdf阅读器推荐 知乎 编辑:程序博客网 时间:2024/05/01 03:13

在游戏中有很多的数据,有些数据可能会经常变换,有些数据就会一直不变。针对这些数据,可以简单的进行一个分类:永远不会改变的数据;经常进行读取和改变的数据;下面就对游戏中的数据进行一个分类。

a) 永远不会进行改变的数据。 如策划填写的资源数据。这些数据在游戏中可能会涉及到数据的重载,但是不会在游戏中由程序控制进行更改。并且这些数据会大量的在程序中被使用。所以这些数据会长期驻留在内存中并不对其进行更改。

b) 全局数据。比如帮会数据等这些数据是由整个服务器内的全体玩家共享的信息,且修改的频率不是很大的数据。针对这些数据我们可以把它们完全放置到内存中去。然后采用实时/定期同步的方式来存储到数据库中去。这种数据的处理还是比较简单的。

c) 玩家的数据。网络游戏是由受人控制的玩家组成的。每个玩家身上都会有不同的数据,并且数据量巨大。但大量的数据不见得就得必须都在内存中体现。玩家又会分为在线玩家和离线玩家。在线玩家的数据毋庸置疑必须要加载到内存中去的,而离线玩家的数据就不见得必须要加载到内存中去了。但是游戏的业务逻辑中经常会去查看一些玩家的数据,这些数据为一些基本数据,如玩家等级、名称、基本属性等信息。这些信息用于给别人查看使用。这样的话可以设计一个缓存来存储所有的在线数据并加入部分离线数据。在内存中的数据可以由主线程直接进行加载,而数据库中的离线数据则必须采用离线的方式来进行加载。

游戏中肯定针对玩家的数据有缓存,针对这些缓存也有多种解决方案:比如采用H2内存数据库来实现、采用一个大型的Map来实现(在java中Map中的数据在达到1W数量级后会有大量的下滑,这个需要注意)

1. 缓存解决方案

a)TM中采用大型Map的方式来解决缓存问题。这个缓存在WS中,Map中存储所有的在线玩家数据和部分离线玩家数据。玩家的数据存储也是通过这个模块解决的。所有的玩家的数据都是通过这个模块来获得数据的。这样就能保证这个模块中的数据为最正确的数据。当有玩家数据信息改变时,就直接修改了这个缓存Map中的数据。当然Map(缓存)中的数据的大小是有限制的,需要使用特定的策略来保证缓存中数据的命中率。(采用三个队列,最近经常使用,)。。。。。未完待续

2 离线数据解决方案

a)解决原则:对数据库异步访问对离线数据的支持。

离线数据都在数据库中,对其的访问只需读写数据库即可,为了不影响主线程运行,需要采用异步的方式进行操作。

但是采用了异步的方式操作,就有可能产生冲突的情况。

冲突原因:在很短时间内进行的两次操作,访问了同一对象。前一次的未能立刻入库,后一次的读取的不是正确的最新数据,后一次的更新把前一次的进行了覆盖。

解决原理:由于冲突是在短时间内并发操作引起的,根本的解决办法就是将并发串行化,保证操作具有完整的时序性。

如何解决:

1) 首先要保证发起操作本身的时序。这就要求对同一条数据的操作来自同一个线程。如果操作本身的先后顺序都无法确定,那又何以确定的正确性呢。而且非常容易引起死锁。 

2)其实,针对同一条数据的操作需安装顺序依次执行。只有前面一条数据执行完毕之后,才能执行后面的数据。因此一条数据操作时需要加锁,执行完毕后解锁。当收到解锁通知后才及性能触发后面的操作。

3)尽量保证每条操作的数据需求单一化。一旦操作需求多条数据,就很可能发生死锁。

解决详情:

1)客户端在收到信息后,把消息发送给服务器。在主线程或场景线程中针对这些消息已经进行过一次排序,时序已经有了保证。

2)抽象出一个IoOperation,每条IoOperation都是一条独立的行为,只操作此玩家的数据。


原创粉丝点击