原文:https://www.cnblogs.com/wgslucky/p/9161771.html
在游戏服务器中,一般相同用户的操作都会在一个指定的线程中操作,而一个线程中又会有多个用户的使用。如果对用户数据的操作进入直接入库操作,那么就会产生io操作,主要有网络io和磁盘io。所以一般我们都是采用内存缓存的方式。内存缓存数据库的方式有很多种,网上也有很多,这里只是介绍一下我的思路和实现。
首先确定一下服务的定位,
一,业务服务,负责处理业务逻辑的服务,叫logicServer吧,这个服务会对数据进行频繁的修改,所以为了提高效率,这个服务会缓存角色的所有数据。
二,是数据缓存更新服务,暂且叫dao层服务吧,它负责对角色数据的长期缓存,和更新数据到数据库中。logicServer对数据的修改频繁,如果每次修改都请求数据库的话,就有点太频繁了,有些数据被多次修改,只需要更新一次就可以了。所以这里缓存的数据采用定时更新到dao层的方式。比如60s更新一次。用户下线之后,如果五分钟还没有再次上线,就判断用户不玩了,就把这个用户的内存数据清理掉。但是dao层对数据的缓存时间要长一些,比如一天或一周如果没有更新数据就清理掉。相当于redis做一下长时间的缓存,这样用户一天内或一周内登陆多次就会直接从缓存中获取数据,而不用查数据库了。dao层的数据也是定理更新到数据库,比如每五分钟更新一次。不过只更新产生变化的数据。
角色信息数据库使用mongodb
它是一个文档类型的数据库,在游戏中,一个角色的数据由多个对象组成,比如角色信息对象,背包对象,技能对象,关卡对象等等。我们把一个用户的所有信息都放到一个大对象中,比如UserData中,UserData中包括了所有的数据对象。把它一次性存储到mongodb中,用户进入logicServer的时候,也一次性全部取出来了,可以减少查询的次数。而且在保存数据到数据库的时候,只需要调用mongo的save方法,如果更新的对象存在_id,就直接覆盖掉老 数据,如果不存在_id,就插入一条新数据。很方便。如果角色的数据太多,可以把大表的数据单独再存到一个collection中。
在用户选择角色,进入游戏时,User服务调用dao初始化数据,拿到初始化的数据,再调用logicServer的接口,把数据初始化到logic服务器中,这里需要注意的是,如果业务服务中已经有缓存了,就不做任何操作,防止由于定时更新数据导致的数据不一致笥,这样就不会因为用户第一次进入业务服务去dao层拉数据而卡线程了。
logicServer缓存的是数据对象,而dao中缓存的是对象的json数据。因为dao层的数据不做可视化调用,只是和业务服务之间传输,而且这样做,在业务中增加数据时,不需要修改dao层的结构。业务服更新数据到dao采用消息队列的方式,异步更新。
每天坚持学习1小时Go语言,大家加油,我是彬哥,下期见!如果文章中不同观点、意见请文章下留言或者关注下方订阅号反馈!
社区交流群:221273219
Golang语言社区论坛 :
www.Golang.Ltd
LollipopGo游戏服务器地址:
https://github.com/Golangltd/LollipopGo
社区视频课程课件GIT地址:
https://github.com/Golangltd/codeclass
有疑问加站长微信联系(非本文作者)