写点什么

旧的不去、新的不来:腾讯 iData 分析中心的进化之路

  • 2019-11-05
  • 本文字数:3295 字

    阅读完需:约 11 分钟

旧的不去、新的不来:腾讯iData分析中心的进化之路

腾讯 iData 分析中心是 iData 产品的重要组成部分之一,负责号码包提取、画像分析、工作分析等围绕用户号码包的数据分析功能。在长达几年的运营之后,针对运营中产生的一些问题和用户的新需求,我们意识到了旧系统的不足,开始打造新的分析中心后台。本文开始将以系列文章,围绕新分析中心后台 TGMars 的计算平台的方方面面,来探讨、介绍我们是如何思考、研发新分析中心的。

旧的不去、新的不来

接手旧项目,抗拒估计是肯定的,里面可能会含有大量祖传代码,复杂的意大利面代码,好像合理但是似乎又不合理的架构。


不过肯定不能这么偏见的认为事情一定是这个样子的,因为口碑毕竟不错,外在的效果还挺好,完全不是那种所谓“失败项目”。


腾讯 iData 分析中心的确是一个很好的项目,不管是号码包提取还是跟踪分析还是画像分析,真的很快。但是快就够了么?没有槽点么?


看到的和实际总是不一样。


“我想能有一个新的需求,这个应该很简单,就是扩展一下维度就好了”,面对这种问题,答案往往是需要痛苦的扩展已有的计算逻辑,写大量的代码,从上到下。


“你们就支持提取一些基础指标,游戏里面有些跟踪指标我想定制”,如果一个一个定制可能要排期很久了。


“今天的位图更新失败了,是什么原因呢?”常常有这种情况发生,但是原因可能多种多样,处理方案总结起来可能要和 737 的故障手册图一样写一本书,很难交接到运维。


总之运营过程中遇到的不少问题,无法回避,总结起来却无外乎几点:


  • 计算难以定制,功能难以扩展。

  • 架构复杂,责任不清晰。

  • 部分模块有短板,常常不稳定。

  • 难以运维。


每个点都要展开去讲太难,既然没到软件工程专家的境界,也没资格去长篇大论的阐述每个地方如何做才能完美;当然也不能只是抱怨一通,然后什么都不做改变。模块代码质量或者有 Bug 不必多谈,如果下功夫修复肯定能解决,但是既然决定了我们要做新的系统,解决之前线上我们遇到的各种问题,那么不妨先只谈当前看到的问题,思考下以后该怎么规避。

为什么这么快?为什么难以扩展?

1. 为什么这么快之位图存储

众所周知,腾讯 iData 分析系统很快的秘诀在于位图。那么我们是如何用位图的呢?


游戏用户的最最基础且重要的行为,往往有几个:注册、登陆、充值和消费。注册和登录时用户进入到游戏,正在玩这个游戏的标志;充值和消费是花钱了,游戏创造了收入的标志。跟踪分析就是跟踪这群用户是否还在玩,是否还在花钱。既然是最关心的需求,那么就要做到最高的支持,就按照这几个行为来做。


位图是一个好又简单的数据结构,可以直接以 0 或 1 来标示用户是否产生了某些行为,0 或 1 构成的数组是有顺序的,顺序正好可以表示为时间维度。



一个用户对应一些定长的数组,表示用户当天具体行为,固定为 396 位,头 12 位为月度行为特征,后 368 位为具体到日期的行为特征,后面冗余 8 位没有使用,方便位移和对齐。


每个用户的位图,其首位表示的日期是不同的,有一个最近日期的概念,这是为了方便每次更新位图的时候不用全量移位所有的位图。同时一个用户有多个位图,可以同时知道用户的多个行为,不用再多表关联,可以知道是否登录的同时还知道是否有过消费。因此位图文件的结构按下图所示。



用户记录按一个固定规则进行分片:如果号码类型是数字的则余分片数,如果是字符串的则取 CityHash 再余分片数,账号基本上是均匀分布到每个分片的。

2. 为什么难以扩展之行式存储

位图设计很有效,但是位图文件本身的结构仍有问题:


  • 行存储,位图文件大小是固定的;

  • 位图分片固定,且一旦生成整个生命周期都是固定的,导致位图文件在集群上的分布总是不均匀;

  • 难以扩展,整个结构都是预先设计好的。


行存储的优劣很多文章都有谈到,主要是 OLTP(On-Line Transaction Processing,联机事务处理)用行存储更好,毕竟需要频繁删减的数据库,如果需要快速查询另外附加索引便好,而劣势则是对于 OLAP(On-Line Analytical Processing,联机分析处理)来说,如果只需要几个列的内容,没必要一次扫描那么多数据。


iData 分析系统正好是 OLAP 的:


  • 实时性要求没那么高,毕竟只是查询为主。

  • 数据量大,普通的数据库难以承载,游戏一火爆轻松上亿。

  • 系统主要支持决策,用户可能有自己的想法去提取数据,计算可能还有些复杂,不是预先设计些索引就满足的。

  • 更重要的,数据输出量大,跟踪分析还好,提包需要提取大量记录出来。


因此固定的行式存储,仍有不足之处:难以扩展,不太好适应需求。

3. 为什么这么快之 MapReduce 架构

看一下模块结构图:



计算过程大体需要让用户分群对应的号码包通过包分片服务按相同规则分片,下发到位图和 ETL 文件相同的节点上;而号码包和位图的匹配是一次 Join 计算,精确来说是 SortMergeJoin,即号码包分片和位图分片都有排序,排序后的内容一次 Merge 便能匹配,Merge 是 O(n)的复杂度,而号码包排序显然比预先排序好的位图要快很多,因此计算复杂度不大。


在架构的实现上则是一个典型的 MapReduce 结构,Map 在两个地方生效,包分片将号码包按同样的分片规则分片,而 Map 后的结果在计算节点和存储的位图在本地聚合,没有任何多余的 Shuffle 操作,避免了网络开销;而 Reduce 则在包合并的过程中重新汇总为号码包,或者把统计结果汇总到数据库。


可以看出快的秘诀在于存储计算绑定,相同的分片规则使得两表的 Join 没有任何 Shuffle。

4. 为什么难以扩展之 MapReduce 架构

老实说 MapReduce 有些过时了,他毕竟代表了 Hadoop 的那个荣光时代。想想当年怎么在 Hadoop 上写程序的:


  • 写一个 Mapper,把单个分片的内容汇总成单词和频率的键值对。

  • 写一个 Reducer,把键值对汇总。



然后我们就会发现 Map 很快,Reduce 很慢,因为 Reduce 是在一个机器上做的。


在位图分析系统这里,就是包合并模块,这个模块是经常出错的罪魁祸首,往往有 Bug 或者承载超过负荷就导致任务重试或失败,苦不堪言。


另外所有的任务都适合 MapReduce 么?复杂的 SQL 能支持么?Join 的时候需要涉及到多表的时候可以么?不行,这里只支持一次 MapReduce,一次结果直接写号码包或者到数据库了,没有第二次机会。


因此 MapReduce 的计算架构,扩展性较差,任务的计算粒度不能再分了,无法实现太复杂的需求。

跳出既有的思维模式

出现这样的情况,再分析一下,可能是这样的原因,以往我们以游戏数据分析为中心考虑问题,使得我们的思维受到了局限:第一层次是业务,业务下有数据,按照类型分为登录/注册/充值;提取的指标对应一段计算代码,它负责按照指标蕴含的含义做相应计算动作。


可是转念一想,这不就是一个数据库么?业务是数据库,登录/注册/充值是数据表,为什么到了这里就不分了呢?提取动作就是 SQL 计算,为什么到这里就是固定的代码了呢?


因此我们可以认为难以扩展的根本原因在于过于特化的设计一个系统。我们的目标不在于只是支持特定的业务场景,也不是特定的几种数据,应当抽象出来,按照一个 OLAP 平台的设计思路去做,跳出既有的思维模式;这也是后来面对平台开放后遇到的问题,我们的客户可能不仅是游戏相关的了。

我们需要一个什么样的计算平台?

在新分析中心立项的时候,我们对计算的部分立下了两个大的目标:


  • 存储的结构可扩展。

  • 计算逻辑可定制。


同时也稍微放宽了点要求,前期可以出结果稍微慢点,非常感谢这点——否则可能会不知所措。


先取其精华,总结下好的地方在哪里:


  1. 主键列按固定规则分片,方便匹配到记录。

  2. 存储计算绑定,没有 Shuffle 过程,减小网络开销。

  3. 位图,将时间维度横向转制,快速匹配到用户行为。


再去其糟粕,再看下哪里可以做得更好:


  1. 行式存储,是否可以改成列式结构方便只读取想要的数据?

  2. 维度扩展,是否可以是可定义存储结构?

  3. 支持更复杂的计算模型,是否支持多次的迭代?

  4. 支持 SQL,使得计算可以更随心所欲?


这就是新分析中心后台中计算部分的基本设计思路了:在好的基本设计思路下,我们还能做什么解决已有的问题。

为什么不直接用现成的?

“那为什么不直接用现成的啊?”,的确现有的很多大数据计算平台好像都满足需求,满足 OLAP 的能力,还能有更多。比如 TiDB、比如 Spark、比如 ClickHouse 或 Palo。


本文转载自公众号云加社区(ID:QcloudCommunity)。


原文链接:


https://mp.weixin.qq.com/s/nRYKqgdIS4E-Aexp6uJyvA


2019-11-05 23:23953

评论

发布
暂无评论
发现更多内容

腾讯技术大牛带你玩转Spring全家桶,赠三本Spring实战篇电子文档

Java 程序员 后端

自己搭建电商平台初期,原来“超卖,java书籍百度网盘

Java 程序员 后端

聊聊MySQL主从复制的几种复制方式,上岸蚂蚁金服

Java 程序员 后端

脑筋急转弯:如何用两个栈实现一个队列?用两个队列实现一个栈(1)

Java 程序员 后端

脑筋急转弯:如何用两个栈实现一个队列?用两个队列实现一个栈

Java 程序员 后端

腾讯T4架构师:刷3遍以下面试题,你也能从小公司成功跳到大厂

Java 程序员 后端

蘑菇街Java大牛纯手打肛出的一份多线程文档,请别丢进收藏夹吃灰

Java 程序员 后端

蚂蚁金服+拼多多+抖音,java从入门到精通第四版视频

Java 程序员 后端

蓦然回首,十余年的程序员生涯最后就只剩下了这些!希望我犯过的错误你不要再犯

Java 程序员 后端

膜拜!华为内部都在强推的783页大数据处理系统:Hadoop源代码pdf

Java 程序员 后端

蚂蚁金服面试经验分享,阿里的offer真的不难,初面蚂蚁金服

Java 程序员 后端

血赚!阿里P9整理出内部500多页最全双十一顶级秒杀方案笔记

Java 程序员 后端

脉脉上瞬间爆火的Java高级面试题被全网封杀,这套资源到底有什么魅力?

程序员 后端

腾讯T4:结合我多年工作经验给程序员的几点忠告,别再埋头苦干了

Java 程序员 后端

架构实战营- 模块二作业

危险游戏

架构实战营

膜拜!京东T9大牛沉淀三年终于整理出了这份架构核心修炼之道

Java 程序员 后端

聊聊多线程(一)线程的基础,linux集群架构师

Java 程序员 后端

聊聊多线程(四)线程安全之AtomicInteger类,最全面试考点与面试技巧

Java 程序员 后端

肝完这份Linux网络编程笔记,感觉2年开发白干了,nginx反向代理原理转发过程

Java 程序员 后端

聚焦WAVE SUMMIT 2021,大咖齐聚共研深度学习(1),java在大数据技术中的运用

Java 程序员 后端

腾讯五面、快手三面已拿offer(Java岗位,linux基础教程第二版pdf

Java 程序员 后端

若依集成 WebSocket,linux学习步骤

Java 程序员 后端

蘑菇街大牛熬夜整理的Java多线程知识点总结(思维导图+源码笔记

Java 程序员 后端

蚂蚁金服二面被血虐,spring-并发-JVM把我直接问懵,我经历了什么-

Java 程序员 后端

腾讯、美团等六家大厂收到offer,浅谈大数据面试经历,2021Java面经

Java 程序员 后端

腾讯启动有史以来最大校招:苦逼程序猿,拿头发换了高质量生活

Java 程序员 后端

获12w+星标的神仙文档再度上榜,简直是一套活生生自学Java的福星

Java 程序员 后端

蚂蚁金服Java开发岗面试挂了以后,流泪总结了这份大厂常问面试题!

Java 程序员 后端

聊聊RabbitMQ RabbitMQ相关面试题,kafka入门教程步骤

Java 程序员 后端

聚焦WAVE SUMMIT 2021,大咖齐聚共研深度学习,关于线程池的五种实现方式

Java 程序员 后端

腾讯T8纯手写66个微服务架构设计模式,全部学会真的“变强

Java 程序员 后端

旧的不去、新的不来:腾讯iData分析中心的进化之路_文化 & 方法_杜钢_InfoQ精选文章