最近我司需要做一个统一的游戏日志系统,要求有一定的通用性,能应对公司所有的游戏业务。接下来分享一下这次日志系统的项目经验。
目前流行的日志系统为ELK,由Beats、Logstash、Elasticsearch、Kibana等组件共同实现,但万变不离其宗,一个基本的日志系统架构类似如下:
游戏分析,与其它服务系统不同的是,游戏内的系统可能是天马行空的,数据类型是多样的,甚至频繁变化的。我们要在变化中总结到不变的内容,例如系统经济产出,玩家物品消耗,商店购买等进行分析。所以这次的游戏日志系统要满足以下需求:
虽然ELK在安装配置方面不算困难,插件众多,例如Filebeat,读log文件,过滤格式,转发,但谁来生产这些log文件,没有提及。实际上,业务具有多样性,只要有日志文件的地方,它就可以用。例如多数会使用Nginx进行日志收集。我们也需要考虑到日志生产者的问题,责权分离,需要单独一台机子进行日志采集。
游戏是一种技术与艺术结合的产品,数据庞杂,形态各异,光日志埋点也花不少功夫复杂,但不能因此放弃则携治疗。好的游戏日志,还可以帮我们还原玩家玩家画像。游戏更新周期短,数据变化大,需要提供更实时参照报表,为非技术人员更好友的查询界面,才能更好的服务于游戏数据分析。ELK 在这方面,基本解决了采集和储存的问题,但实现分析方面还不能满足我们的需求。
经过一翻思索,我们可以用现有工具,粘合多个套件,所以,我们有了以下思闹宽路:
这个框架主要使用到了Fluentd,ElasticSearch,以及NodeJS,我就称它为 FEN 架构吧,如下图。
上图看出,这样的日志架构和第一个图基本没什么不同,只是多了后面的分析与分批入库处理,并且大量使用了NodeJS。
注:在这里不会介绍各组件的详细的安装配置方法,网上有太多了,怎样使用好每一个组件才是关键。
先介绍我们用到的工具:
Fluentd是一个完全开源免费的log信息收集软件,支持超过125个系统的log信息收集。Fluentd在收集源日志方面非常方便而且高性能,通过HTTP GET就可以,这类似于Nginx的日志记录行为。它的优点是,日志文件可以高度定制化,例如我们液盯亮这里每5秒生成一个文件,这样每分钟有12个文件,每个文件体积非常小。为什么要这样做?下面会介绍。Fluentd还有非常多的插件,例如直接存入MongoDB,亚马逊云等,要是熟悉Ruby,也可以自己写插件。
有人使用MongoDB进行日志收集,是非常不明智的,只有几千万条还可以,如果半个月生产10亿条日志呢?日志文件需要保存一个月甚至更长,那么集群和硬盘维护就非常重要。使用便利性也很重要,例如分词检索,在客服回溯玩家日志,分析游戏 BUG 的时候非常有用。下文的 ES 也是该组件的简称。
NodeJS不适合做 CPU 密集型任务,但在网络应用方面还不错,并且是我们正好熟悉的。日志系统并不对实时性要求并不高,延时半小时以内都是允许的,事实上,正常情况延时也就10来秒。下面的读与转发日志的Pusher,收集日志的logger,分析日志并数据落袋为安的的analyser,都是由NodeJS实现的。
下面继续介绍用 NodeJS实现的每一个部分:
上面说到,为什么Fluentd使用分割成多个小文件的方式,因为NodeJS在大文件处理方面并不友好,并且要考虑到通过网络发送到另一台机,转发速度比读慢太多了,所以必须实现续传与断点记录功能。想想,如果读几百 M 的文件,出现中断后,需要永久记录上次位置,下次再从此处读起,这就增加了程序复杂度。NodeJS虽然有readline模块,但测过发现并不如文件流那样可控,访模块用于交互界面尚可。相反,如果日志分割成多个小文件,则读的速度非常高效,并且每5秒一个文件,哪怕有上万条记录,文件也大不到哪里去,内存也不会占用太多,在断点续传与出错重试方面都能自如应对。如果游戏日志增多,可以增加节点来缓解文件过大的压力。
为什么不直接让日志生产者直接发到Koa上?因为效率与带宽。NodeJS的适合做网站,但比专业的HTTP服务器要弱太多,4核心主机面对3000QPS就吃力,更多的关于NodeJS的性能问题,可以参考网络文章。在高并发量下,带宽是个很大的问题,尤其是需要做统一服务,面对的情况是日志机器与游戏并不在同一内网中。在10万日活下,带宽超过了50M,非常吓人,带宽可是很贵的,过高的带宽费用在这里性价比太低了。
这里我们使用Koa作为日志采集器。使用Koa,无论在性能还是开发效率上,都比expressJS高效。我们还用到了Redis作为缓存,而不是直接在这里做分析任务,是为了尽量提高与Pusher的对接效率,毕竟日志的生产速度是很快的,但网络传送是相对低效的。
注:pm2 3.2.2的集群可能出现集群内端口冲突的吊诡问题,建议用3.0.3
分析器读取Redis的内容,这里就是单进程的队列 *** 作。到这一步,日志怎么分析,就可以很自由了。
因为我们本身有后台管理系统,所以我们很方便的把用户画像与其它分析点接了入去,在查询玩家行为时,我们搜索ES,在查询分析报表时,我们查询MongoDB中的数据。当然我们也使用了Kibana来满足可能的需求。
目前该日志系统运行1个半月,由纯MongoDB到结合 ES,走了不少弯路,还好现在终于稳定下来。目前在性能方面,logger 与 analyser都在同一台机,平均 CPU 为23%左右,高峰47%左右,说明还有更大的机器压榨空间。
内存方面,在高峰期5G 以内,总体非常平稳没多大波动,其中redis内存使用为800MB以内,但机器是16G,还有很大余量保障。
NodeJS 的脚本中,logger的CPU占用更小,3条进程,每条才3%,每条内存占用不到100MB。analyser 的 CPU 与内存占用多一点,这一点可以通过脚本内的参数调整,例如内存计数的内容清理得更快,使用pm2的话设置max_memory_restart : '4G' 都可以提高稳定性。
以上是我在游戏日志系统中的经验总结。
参考文献:
1、起源Node.js起源于2009年3月。最初Ryan Dahl是为了构建一个高性能的文本服务器,而node.js是他在寻找一种更高提升web服务器性能发现的,事件驱动、非阻塞I/O这种方式能更好的提高性能。随着Nodejs的不断发展,Nodejs渐渐演变成一种构建网络应用的基础框架,并发展为一个不共享任何资源的单线程、单进程系统,但包含了很适合网络的库,这样Nodejs就为构建大型分布式应用提供了基础设施。他配宴们的目标都是为了构建快速、可伸缩的网络应用平台。它自身非常简单、采用虚闹通信协议来组织许多的Node,非常容易通过拓展来达成构建大型网络应用的目的。
2、node.js简介
Node.js是一个可以快速构建网络服务及应用的平台。该平台的构建是基于Chrome'sJavaScriptruntime,也就是说,实际上它是对GoogleV8引擎(应用于GoogleChrome浏览器)进行了封装。Nodejs不是一个js应用而是一个js运行平台。其是由C++编写而成。但是Nodejs是一个后端的运行环境。因此你可以编写系统级或者服务器端的js让Nodejs帮你执行。差卖罩
3、优势
1)node.js采用事件驱动、异步编程,为网络服务而设计。
2)node.js采用非阻塞模式的IO处理,可以使node.js在相对低系统资源耗,拥有出色的负载能力,非常适合用作依赖其它IO资源的中间层服务。
3)node.js轻量高效,可以认为是数据密集型分布式部署环境下的实时应用系统的完美解决方案。
4)使用node.js配合CoffeeScript 写异步 *** 作链非常便利,相比之下Tornado无论是写命名函数的回调,还是 yield 一个 Task 都没那么自然。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)