游戏服务器关于玩家数据的解决方案

游戏系统的数据可以分为两大类。一类是由策划童鞋配置的玩法规则,称为策划数据或产品数据;第一类是保存玩家或公共信息的数据,称为用户数据。一般说来,策划数据只能由程序读取而不能修改,而用户数据则增删查改都会涉及。

对待玩家数据的严谨态度,无论怎么重视都不为过。玩家数据,正如游戏系统的血液。只有保证玩家的数据安全,才能留得住玩家的玻璃心。如果玩家今天历尽艰难险阻,耗尽所有rp刷到一件极品装备,明天上线发现装备不见了,估计想烧游戏公司的心都有了。

游戏服务端一般采用的数据库是关系型数据库,用mysql就足够了。我呆过的几家游戏公司都是采用mysql数据库。

本文将从数据持久层框架的选择、数据表结构的设计以及数据入库模型三个方面,讨论相关解决方案。

  • 关于数据的持久层方案

以前做web的时候,持久层一般都采用诸如mybatics或hibernate等ORM框架。游戏后端需要保存玩家及公共数据,持久层框架也可以采用mybatics等。

但一般每个公司都会有自己沉淀的一套持久层框架。例如有公司利用JDBC的ResultSetMetaData元数据获取列信息,然后与实体bean的field进行映射,将数据表的每一列跟对应的bean属性对应起来。当数据需要入库的时候,就调用bean对应的所有getter方法拼装成insert或update语句;读取数据则调用bean对应的所有setter方法,将数据表记录注入到实体里。这种方法是我见到的最有意思的持久化方案。

  • 关于玩家数据表的设计方案
不管是页游还是手游,当你进入游戏界面后,总能看到满屏的icon在闪。所有游戏业务的玩家数据一般都需要持久化。那么问题来了,这么多的数据需要保存,怎么来组织数据表结构呢?

比较直观的是,每一种游戏业务就采用一张表,所有的表通过角色id作为外键。这种方式优点就是结构清晰,在生产环境容易分析玩家的状态,修复数据也可以直接执行sql。缺点则是,每次新增功能业务的时候,需要人为加表,比较麻烦。

另外一种方式恰好与之互补。我不管以后加多少业务,我都统一把数据作为角色对象的属性,持久化的时候只需要采用json或者xml序列化为字符串(有公司甚至直接序列化为二进制字节),数据读取的时候则采用同样的方式进行反序列化。这种方式优点非常明显,加功能无需修改数据表;缺点也很突出,由于数据表示相当复杂(一般还需要进行压缩以及加密),直接查看数据库数据根本无法理解,修复玩家数据需要在游戏服内存中处理。

  • 关于玩家入库时机的设计方案

玩家的业务行为非常频繁,也非常广泛。如果玩家的每一次获得物品,每发一封邮件,都往数据库生成一条执行语句的话,那么数据库瓶颈马上就会出现的。特别是很多更新语句,新增的语句一般都是可以直接替换旧的语句,如果每一条都执行的话就显得相当冗余了。比较正规的做法是,玩家的业务行为只影响内存里的玩家缓存。用一条专门的消费者线程异步地执行sql语句,这样数据库就能平稳工作了。需要特别注意的是,执行停服操作的时候,一定要等待所有用户sql都执行完毕。如果丢了数据,我们这些程序屌丝就会被扣绩效伺候了。  (=。 =)

你可能感兴趣的:(架构设计,java,手游服务端)