结合个人参与的游戏项目开发,谈一下游戏开发玩家数据保存的处理
玩家的数据基本上分为两份,一份是玩家下线或者永久保存的数据,通常保存至数据库(mysql或者mongodb)中,一份是保存在内存中。
一般玩家数据的处理流程:(玩家不会操作非在线玩家信息)
1、玩家上线
(1)新玩家上线,查询玩家是否在数据库中,没有就创建新的角色,写入到数据库中,并将玩家信息保存到内存中
(2)老玩家上线游戏网关开发,查询玩家,并验证玩家真实性,通过,就将玩家信息保存在内存中
优化:
(1)一般服务器架构是将登录服与游戏服区分开,所有最好的方式通过内存数据保存玩家数据(以redis为例)
(1)新玩家--->查询数据库-->创建新角色--->插入redis---->插入数据库
(2)老玩家---->查询数据库--->插入redis---->更新数据库部分信息
(2)防止玩家重登
(1)redis 设置记录、加锁(2)缓存玩家上线状态信息(网关服会记录玩家在线,在线的不会请求登录服操作)
2、玩家在线
玩家登录到游戏服后,会将玩家数据从redis导入到内存中,这时候玩家数据有三个地方(游戏服内存中,redis、内存)
(1)玩家心跳时间控制,每隔一段时间将内存数据放入到redis(同时写入一个保存标识)
3、玩家下线
玩家下线将内存数据导入到redis(同时写入一个保存标识)
4、数据保存
数据服心跳里 查询redis是否有保存标识游戏网关开发游戏动态,如果有,则取出玩家数据进行保存
注:一般会独立出来一个数据服处理玩家数据保存、及其他增删改查的数据操作,使用缓存队列+多线程连接池
游戏玩家数据保存方式(玩家操作非在线玩家信息)
(玩家上线在去加载数据到内存中)由于玩法的特殊性3D场景,会出现一个玩家修改另一个玩家数据情况,比如说,比如说我在地图上找到一个敌人,我去掠夺玩家资源,必然会修改另一个玩家数据,这个玩家可能在线可能不在线。如果这个玩家在线,我直接根据在线玩家找到他,并修改他的内存数据即可,如果这个玩家不在线,我需要从数据库加载他的数据,并修改放回到数据库里,如果在我放回他的数据同时,他恰好上线,他的内存数据还是我修改之前的,就会造成这个玩家数据不一致。那么如何解决这个问题呢?
(开服时就加载全部玩家数据到内存中)一种办法,就是玩家始终一份数据,始终保存在内存中,也就是说服务器启动时就应该把一个区服的所有玩家信息加载到内存中,这样就保证了玩家只有一份数据保存在内存中,玩家上线不用在从数据库中加载数据到内存中。如果玩家信息很多,怎么办,毕竟内存还是有限的,可以做一些优化处理,就是玩家数据分为:在线数据、非在线数据。服务器启动只加载在线数据,等玩家上线时加载非在线数据。
注意:
开服就加载全部数据到内存中,如果遇到合服的情况就很麻烦,不能将所有玩家数据都放到内存中了。这时候就需要考虑数据的冷热情况。
数据库保存两张表,一张全部玩家数据表A,一张最近登录活动频繁表B(两张表结构一致),开服时加载表B到内存。
表A 表B数据要保持一致
内存中需要维护两个链表,链表A(保存最近登录玩家信息)、链表B(最近被查找玩家)
如何解决查找更改离线玩家数据不一致呢?
假如 玩家A 查找离线玩家B,
先查链表A,如果找到说明玩家B在线, 查看更新玩家B没有问题
在查链表B,如果找到说明玩家B数据已经在内存中,查看更新玩家B没有问题
再去查数据库,第一次查找离线玩家B,将玩家B加载到内存中,更新链表B
离线玩家B上线,
查找链表A,如果找到,说明加导内存中
查找链表B,如果找到,说明加导内存中
再去查数据库,更新链表A,删除链表B即可,加载信息到内存中
数据持久化更新表A、表B
玩家数据持久化
一般交给数据库连接池处理
文章来源:https://blog.csdn.net/chinabhlt/article/details/102563320