【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

旧的不去、新的不来:腾讯 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:23660

评论

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

如何科学制定和管理项目计划?

万事ONES

项目管理 ONES 项目经理

☕️【Java 技术之旅】带你一起攻克String类创建的难点分析

洛神灬殇

Java string pool string 6月日更

我人生的里程碑之【作为独立开发者,第一次承接外包项目的心得经历,也许说出你的心声哦!】

洛神灬殇

程序人生 6月日更

阿里云官方出品:全面总结阿里云云原生架构方法论与实践经验

尹文敏

云计算 阿里云 云原生

创业邦南立新:搭建创新生态,是奔向万亿美金市值的必经之路

创业邦

从零开始学习3D可视化之模型动画

ThingJS数字孪生引擎

可视化 模型 大屏可视化 数字时代 3D可视化

一个超牛逼的 GitHub 项目,标星高达55.3Kstar,附项目源代码

Java架构师迁哥

react源码解析9.diff算法

全栈潇晨

react源码

基于传感器的人体生命体征监控技术

不脱发的程序猿

物联网 传感器 智能医疗 人体生命体征监控技术

面试官:如何给字符串设计索引?

一个优秀的废人

MySQL 索引 字符串 索引优化

程序员需要了解数据库知识么?

escray

学习 极客时间 朱赟的技术管理课 6月日更

准备3个月,面试10分钟,Java中高级岗面试为何越来越难?

Java架构师迁哥

Flink + Iceberg 在去哪儿的实时数仓实践

Apache Flink

flink

油管视频下载: 如何下载油管视频到本地

科技猫

分享 教程 经验 油管视频下载 下载油管视频

毕昇JDK:为啥是ARM上超好用的JDK

华为云开发者联盟

Java 华为 jdk Openjdk 毕昇 JDK

centos7使用

xujiangniao

Linux

用 CloudQuery 管理和操作数据库,更高效更安全

BinTools图尔兹

运维 dba 数据库管理工具

阿里工作8年,肝到P8就剩这份学习笔记了,已助朋友拿到10个Offer

Java 程序员 架构 面试

涵盖了所有计算机底层知识总结与操作系统的实战教程,你确定不看看吗

Java架构师迁哥

24道几乎必问的JVM面试题,我只会7道,你能答出几道?

北游学Java

Java 面试 JVM

建信金科大咖访谈:ISO20000及ISO27001标准体系解读

金科优源汇

Kubernetes学习笔记之Calico CNI Plugin源码解析(二)

360技术

2021年最新版Java后端最全面试攻略,全面对标BATJ

Java 程序员 架构 面试

《原则》(九)

Changing Lin

6月日更

☕️【Java技术之旅】带你一起探究String类不可变的特性

洛神灬殇

string 原理 字符串 6月日更

福利时刻 十年黑客大佬的Web安全渗透技术分享

学神来啦

Linux 黑客 安全 运维自动化

开源之夏来啦,欢迎报名 Apache APISIX 项目!

API7.ai 技术团队

开源 后端 技术人生 API 网关

超全!阿里首发内部微服务架构笔记,再也不用为“微服务”苦恼了

Java架构师迁哥

深入分析Linux操作系统对于TCP/IP栈的实现原理与具体过程

奔着腾讯去

c++ socket 网络协议

博云作为专业独立PaaS厂商,入选中国PaaS市场研究报告

BoCloud博云

PaaS

在外包5年,每天读写删改,突然发现跳不出来了

Java架构师迁哥

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