实习不到一个月,老大让我做一个游戏数据分析系统

/ 经历分享 / 2 条评论 / 646浏览

今年8月我开始在公司实习(11月因回校考试离职),业务是我从未涉足的游戏业务。去的第一个月,先是学习团队所使用的框架,然后慢慢的做一些简单的游戏业务,也算是练练手,例如:抽奖、PVE、关卡设置等。第二个月便进入新的一个知识盲区——游戏数据分析,老大想做一个团队内部使用的数据分析系统,并且实现定制化的需求。集团以及第三方已经有成熟的系统和SDK,但是就团队内部开发的游戏而言,这些系统和SDK无法实现定制化需求,所以觉得咱们自己搞一个。后端组其他同事也都有各自维护的游戏项目,工作也比较忙,于是这个系统就交到我的手上了。

之前的做法

在之前团队除了参考发行那边的游戏数据,然后都是使用的ELK(ElasticSearch + Logstash + Kibana)来获取数据,当然还有FileBeats,因为ES的聚合运算功能有限,很多数据不能直接得出来,比如留存、ARPU值等,所以只有将这些经过一次聚合运算后的数据导出成Excel,然后在Excel里面计算以及展现图表,老大和产品拿到的就是这些Excel文件。这个过程很麻烦,因为获取不同查询指标的结果就要进行多次Excel导出和计算,比如我要获取某款游戏所有区服美国、巴西、所有国家的数据那么就要拉取三次然后整合到一个Excel,如果突然老大又让你查这款游戏110区这些国家的数据你又得再拉三次,所以半人工计算的这个过程很麻烦,那么游戏数据分析系统的存在就很有必要了。

需求

我负责系统的设计和开发工作,对于功能需求当然是老大来提了,毕竟我还是个实习生,对游戏数据分析了解甚少,很多理论概念和计算指标都得现学现卖。经过上级几次定稿改稿之后,初版需求拿到了我的手上,需求大致如下:

当这些需求下来之后,首先我要去学一下这些数据指标的概念和计算,有些名词听都没听过,偶尔还得麻烦组长或老大给我解释。当清楚这些指标的计算方法之后才知道需要对哪些数据进行计算、哪些数据进行存储。

我对这个系统的思考

其实上面那些需求对于我来说并不难,纵眼一看无非就是让我设计一个团队使用的内部系统,其中的业务数据也都是之前手动计算过,我只是需要把手工计算的过程用程序去实现罢了。对我真正有所挑战的是每天产生如此多的数据(预估平均每款游戏每天至少产生40G数据),要如何去读取、计算、保存然后展示给用户,同时Kibana中所涉及到的ES数据读取、简单计算、聚合计算、复杂查询等功能都得自己去实现(此时我还不会用ES),所以对我的挑战就是框架的学习、架构、性能优化。

为了辅助阅读,先放出当时做设计报告的时候做的一张图吧

学习框架只能在做的过程中边学边做,然后多在网上查询一些教程和经验(很坑的是国内ES文档描述的极其简单,每个功能介绍描述的不到它设计的1/10,我只好看源码以及结合国外文档来学)。先说一下整个系统的架构吧,首先明确系统使用范围是给团队内部使用,不会对外开放,当然也就不存在多大的并发,这一点让我省去了很多事,因为计算压力分散到了各个ES上,本系统承载的计算服务较小,因此没有设计成分布式。当然需求方都是爸爸,谁知道以后会有什么样的变化呢,所以在设计的时候需要分层明确,减少层与层之间的耦合依赖,就算以后需要水平拓展改动也很小不至于重构。

因为团队之前是使用ELK+FileBeats这一套去读取数据的,因此我也就不用考虑数据从哪儿来了,直接从各自的游戏对应的ES中读取即可,其载入到ES的流程如下。

因为每天产生的数据量非常大,自然就面临着何时去读、怎么读这样的问题。首先对于何时去读,要衡量一下ES中的聚合计算和本系统的数据指标计算的计算量,对于这两套系统哪一个在计算时所负载的压力更大、哪一个一天内计算的频率更高、哪一个工作空档期固定。相比之下ES那边的压力更大,本系统所计算的数据都是经过原始数据处理后的数据(处理方法后面讲),数据量更小,而且ES的负载是受游戏玩家的活跃情况所影响的,大部分游戏玩家在凌晨3-6点的活跃度最低,因此ES的工作空档期也就固定在3-6点,所以我需要在ES服务器负载最低的时候去做计算,也就是凌晨3-6点,以保证服务器的正常运行。

如何读?可多个游戏多个ES集群同时读,将数据读到队列中,系统对队列中的数据一一处理,这里用到了消费者生产者模式。每个游戏读数据不能一次性读,毕竟JVM内存是有限制的,不可能一次性读完,ES层面得分页读取(分页读数据也是一个坑,ES分页读有两种方式:分页和游标,数据量大时选择游标读取性能更佳)。但是这里存在一个隐患,如果同时读取的游戏非常多,每个游戏读取的数据大小和可能就会超过JVM分配到的内存大小造成OOM,需要加入一个类似于TCP协议中的滑动窗口进行限流,也就是根据虚拟机内存的可承受能力来选择性的控制几个游戏同时读数据,不过当时为了简单就做成的游戏一一遍历读取(^▽^)。

需求中有一项是能查看到游戏历史的所有数据,也就是从游戏开服开始,游戏的数据都要保存,而上面也提到过,团队内开发的游戏每天产生的数据会非常多,因为使用的是云服务器,磁盘的租用费也不低,原始数据是不会一直保存的,为了降低成本,团队的做法是定期删除几个月或一年之前的原始数据,也就是说ES中保存的只有近几个月的原始数据,那么系统如果要读取之前的数据,只有将这些数据经过处理后保存到DB中。原始数据各个k-v占用字节数较大,同时并不是每一条日志的每一项数据都是有效的,其中存在一部分冗余,所以存入DB的数据仅仅是一些关键数据项(比如用户ID、充值记录等)以及经过聚合计算后的结果,大大节省了磁盘空间和计算时间,按照10G的原始数据算,这样经过处理下来的数据不到1M。

不难但是很烦的内容

对于我个人而言,一个系统中不难但是很烦的内容就是业务逻辑和页面设计,虽然这一块在程序设计上有大的学习空间,但我还是觉得它很烦,特别是让我这个后端开发去开发前端(PS:因为团队是手游业务,所以没有招web前端开发),作为实习生也不能丢了自个面子啊,页面又不能太丑至少得看得下去,简直要人命。而对于其他后台的组件模块、权限、缓存等便更符合后端开发胃口,因为业务需求较为简单,也不涉及到一个大产品那样复杂的逻辑和场景,在这一块,对我的收获没有前面做数据计算的收获大!

总结

在实习期,这个系统对我的成长是最有帮助的,里面学习到了很多数据分析的知识,同时也涉猎到了大量数据的计算,ELK等相关的工具也有所学习。不过对于整个系统来说,还有非常多可优化的地方(包含团队之前的一些设计),总结如下:

微信公众号浏览体验更佳,在这里还有更多优秀文章为你奉上,快来关注吧!

北风IT之路

  1. 厉害,大佬

  2. 厉害,虽然也不怎么看的懂,😂😂😂