《架构师》2018年12月
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

每日生产万亿消息数据入库,腾讯如何突破大数据分析架构瓶颈

作者 彭渊

背景介绍

对于腾讯庞大的大数据分析业务,几千台的Hadoop集群,近百P级的存储总量,每日产生万亿的消息数据入库,需要针对几十亿IMEI手机设备去重,并关联数千亿的历史全表,进行曝光、点击、PV、UV、日活、新增、留存等统计指标分析,当前所有业务的ETL清洗、统计计算、用户画像都全部依赖离线m/r和Hive SQL,给集群造成很大压力,系统负载高任务积压重,计算耗时久业务响应慢(t+1),难以及时反馈市场信息的变化,不仅是技术上的巨大挑战,同时业务的迅速增长变化也在挑战着当前技术团队的工作模式和流程。如何突破现有大数据分析架构瓶颈?

本文内容将带来腾讯大数据技术的新发展和架构实践,介绍基于自研bitmap技术的大数据系统“锋刃”,以及OLAP全新驱动模式的架构战略,真正做到秒级实时查看每分钟指标、全维度的用户OLAP自助分析、闭环的动态运营体系。

讲锋刃大数据方案之前,我们先整体看看大数据平台架构,有诸形于内必形于外,很多局部状况的问题,需要从整体来看,为此,我们按照集群状况,典型业务流程和数据流、系统架构瓶颈点的思路顺序,以表知里的进行一下梳理。

一、集群状况的反馈

当前Hadoop集群系统性能繁忙(3大区域7大机房),1000多存储机器对应4000多计算机器,cpu平均值70%-80%(晚20点到0点较低),5分钟负载很高,任务积压重;ech1几百兆,峰值几个g;磁盘io约几百兆,峰值几g,读写iops3000。存储计算比为1:2,业务job还在增长之势,1:3到1:4将达到集群瓶颈。

很多时候我们看到集群繁忙,只当作运维问题去解决,扩容集群机器,调整机房部署,优化调度能力和虚拟化,增强任务监控管理等。却很少关心集群上跑的都是些什么任务,为什么会给集群造成这么大的压力,我们接下来通过梳理业务流程和数据流来搞清楚这个问题。

二、典型业务流程和数据流

手机浏览器业务场景典型流程:从手机浏览器的资讯日志数据,统计每板块的PV,并挖掘用户浏览咨讯的内容提取标签,并计算标签权重,进行推荐,再将推荐结果反馈到日志。

三、贯穿业务场景的数据流

多份业务log和产品如灯塔sdk产生多份数据日志,分别有各自的通道和hdfs数据模型,对集群存储和计算有很大重复,也造成各自数据的不完整,目前尚未在“通道采集—基础数据—集市数据——高级画像”数据流链路上形成统一数据模型,这样即能优化节省资源,又能数据建模标准化,所有统计计算和算法挖掘都基于统一数据标准进行,上层可以提供大量工具化用户产品。

四、系统架构瓶颈全链路分析

综上所述,我们通过对集群、采集、通道、统计、存储、数据治理、idc、业务场景的全链路架构分析,归纳出以下瓶颈点:

1.Hadoop集群的繁忙压力

2.所有业务全部依赖离线m/r计算和Hive SQL

3.log采集的大量重复内容

4.MQ集群每日消息总量万亿但无法提供内容过滤

5.冷热存储、短期存储(天内)、长期存储(T+1,周、月、年)混一起

6.做到小时和分钟级别统计很难。

7.没有一个统一精简的数据模型形成标准。

8.业务的存储和计算还在迅速增长……

但是不可能所有的架构瓶颈都能在短时间内进行优化改进,我们需要寻找一个最合适的切入点,先解决最迫切的问题。

五、迁入实时计算的优化和问题

(一)从业务流程和数据处理的逻辑,反思当前架构和处理方式

1.采集源头的log生成:如应用宝产生6000多log,其中30%-40%的内容是重叠(设备信息、身份信息等),开发人员根据需要自定义新的log,每个log产生后续一系列存储表,以及新的工作流job,不断累加。对于每个log,有的超过100个字段,支持很多种统计任务,但是每种统计只需要其中很少字段即可完成。

(1)Log进行重新梳理和合并,减少冗余,制定log规则

(2)考虑从源头进行log梳理和分流,以统计业务维度接收局部消息内容:

2.通过大量hdfs存储表实现数据流处理:以手机浏览器业务,每个log表会产生多个清洗结果表,多张清洗结果表汇合清洗统计表,完成统计计算后,还需要汇合多张统计结果表,形成通过大量的hdfs中间存储表,来实现统计和集市的数据处理逻辑。如果考虑用实时流取代存储表处理流,可以带来很大的资源节省和效率提升:

3.当前离线处理方式,以灯塔为例,每10分钟接收MQ通道的日志数据,在HDFS建立一个分区,一天共144个分区,每个分区建立3600个几K到10M的小文件不等,再提交144个离线JOB去执行清洗任务,产生1500个解析表,再按照小时、天、月建立统计统计任务,反复关联全表热表操作,完成新增用户等典型统计。离线处理方式计算和磁盘耗用严重,解决1天内的实时需求难以满足。除灯塔外,其他的业务也按照这种方式源源不断产生大量的离线任务进行统计,除计算外还会产生大量数据存储冗余,现在我们终于明白集群为什么如此繁忙的症结所在了。

(二)迁入实时计算进行优化的考虑

1.经过分析了灯塔、应用宝、手机浏览器和手机管家,业务的相似主线模式如下,更适合实时处理。

2.清洗部分实时处理DEMO验证:相对于离线计算MAP/REDUCE的时间消耗换算,耗用机器数从84台降低到15台m10,完成了90% 的数据量进行流式清洗,包括:从kafka拉数据->解包->byte2string->清洗->string2byte->,5分钟处理10亿消息数据,333w/s,接近mq纯拉取消费的360w/s。

3.清洗转换步骤,采用实时流处理架构如Storm,通过spout从MQ获取输入流,自定义多个bolt并行处理输入流,再依此组合设计。

4.业务迁移计划,以灯塔广告监测CASE为切入逐步安排计划迁移。

(三)实时计算框架选型问题

其实我们的技术团队当时也考虑过通过实时计算来优化,但是基于传统流处理实时计算方案Storm、Spark Streaming、Flink框架进行实施时,面临一系例问题阻碍,导致无法大范围推行:

当时团队现状:Storm和Spark Streaming研发支持和运维能力较成熟,原始Flink还需要优化,尚不具备直接大规模工程化实施的条件。

· Storm的算子封装和开发成本较大,但是能很好解决1分钟到1小时实时计算和离线资源释放,SQL支持弱,业务分析团队更习惯写SQL做清洗和统计。

· Spark Streaming开发成本低,能解决5分钟10分钟实时批量计算,但是1小时计算无法释放离线资源,统计1分钟级结果会产生大量调度任务。

· Flink提供流式和批量结合的实时处理和完善SQL支持,适合完成清洗和count计算,但其有限时间窗口并不太适合大批量用户去重和统计。

六、锋刃大数据架构方案

到目前为止,我们需要寻找一种新的大数据架构方案,针对海量大数据的实时统计场景进行专门设计,得到更先进的解决办法。我们把业务场景简化一下如下表述,按照因果关系,我们通过手机设备获取到一些app维度的log数据,经过大数据平台的统计处理,最后得到用户相关的结果和一些count类结果(pv,uv,金额,数量等),现在我们想在内存中按照维度组合来实时计算这些结果,削峰填谷把离线累积的数据统计变成每分钟实时流处理。

(一)BitMap位存储和位计算

为了解决海量用户的去重问题,我们发现使用bitmap有两个非常显著的优势:位存储占用空间低,位计算效率高。

1.将需要做统计计算的id转换成数字序号,每个只占1个bit,对于20亿的用户id,只需要20亿bit约238m大小,压缩后占用空间更小,最少只要200k。

2.通过单个bitmap可以完成去重操作,通过多个bitmap的且、或、异或、反等位操作可以完成日活、月活、小时分钟活跃、重度用户、新增用户、用户流向等绝大部分的统计计算,而且能在单机毫秒级完成,真正做到实时计算出结果,同比Hadoop/Hive离线计算执行“select distinct count…from…groupby join…”类似SQL的方式统计,往往需要几百台机器,耗用30分钟才能完成,对比非常悬殊,而且容易形成大量SQL任务调度和大表join给集群带来繁重压力。

(二)BitMap聚合计算

通过多个不同维度的bitmap聚合计算,来解决离线统计里复杂的join问题,几乎可以涵盖所有用户统计相关的场景:

1.去重用户:求1的总数

2.活跃用户:取或bitmap1 | bitmap2

3.非活跃用户:取反:~bitmap1

4.重度用户:取且:Bitmap1 & bitmap2

5.留存用户:取且再求百分比:Bitmap1 & Bitmap2相对于Bitmap1的百分比

6.新增用户:取或加异或:(Bitmap1 | bitmap2)^bitmap1

7.流失用户: Bitmap1相对于bitmap2的新增用户

8.用户流向:app1time1的流失用户 &app2time2

9.多种指标组合:Bitmap1 & bitmap2 & bitmap3 &…

10.等等

按照不同维度生成用户bitmap后,会得到如下面表格描述的数据结构:

我们可以看到,这个数据结构是个大的0,1矩阵,每一行代表某维度取值的用户bitmap,把1累计可以求的此维度取值的用户指标,比如hw机型有多少用户在使用。每一列实际上可以获取到该用户的画像,比如u6用户用oppo机型、经常在北京和深圳等等,维度越多,画像信息越详细。另外,全盘用户的矩阵结构还有更深远的意义,我们在机器学习推荐中,基于特征处理后的01矩阵,可以完成大量的算法训练。

实际上,bitmap的维度组合还有一些复杂性问题需要权衡,比如维度A(共10个取值) 和维度B(共10个取值),如果聚合AB,有两种方式:

· 第1种,An&Bn,共10+10=20个bitmap;

· 第2种,An_Bn,共10*10=100个bitmap。

第1种存在数据叠加的影响,第2种不存在。

第1种消耗更少的空间,第2种消耗更多空间,但是根据业务实际数据出现建立bitmap,实际占用空间小于理论组合全部值(比如mi_kashi不存在)。

(三) Bitmap压缩分析

1.对于bitmap数量很多的场景,压缩有利于节省大量空间,对于20亿的用户id,需要20亿bit约238m大小,压缩后占用空间最少只要200k。

2.按照灯塔当前业务流量,42亿范围的id不会全部来,去重后1-2亿进入bitmap,按照2:42的数据分布,压缩后还是能省很多空间。

3.如果业务流量单位时间内(10秒),42亿用户全部来或者来30多亿,这时bitmap大部分为1,压缩率反而很高,空间耗用不大。反而,对于只来10-20亿去重用户,这是要面临极端最坏的情况,数据分布广且稀疏,压缩有限,空间耗用很大。

4.不同的压缩算法压缩率和耗时成反比,考虑实时性和空间节省,选用压缩率和耗时比较平衡的gzip压缩。

(四)流式处理 +Bitmap实时计算框架

将离线批量处理改成消息流式实时处理,并按照上面基于bitmap做去重和聚合的思路,我们得到下面新的架构:借助flink的SQL能力做清洗逻辑,并提供基于SQL的去重和统计udf的封装给到业务分析人员使用,构建一个分布式的bitmap集群服务来提供bitmap的计算引擎支持,统计结果的数据实时写到数据库里提供报表展示。

注意到,上面的架构里增加来一个ID查询服务的模块,它用来负责将手机IMEI号在线查询转换为数字ID。

1.初始化:通过离线任务,按照最后活跃时间初始化用户ID的数字序号,很久没来的用户放前面,最近的用户放后面,新增的用户在后面加1,这样直接从bitmap的数字ID范围知道是大致什么时间的用户,目前约50亿范围的用户id,除去虚假用户和僵尸用户,还有20亿左右正常用户。结果:仅通过数字序号可以区别最近的用户还是很久以前的。

2.运行时。

未来:手机设备上,灯塔sdk直接携带设备ID的数字序号进入通道,逐步减少id查询,也就是说,未来对市场上几十亿手机设备,腾讯都能有一个除imei外自己的数字编号,这样会极大提升后台的大数据统计分析能力。

(五)BitMap的空间耗用

1.大范围数字的空间浪费问题,如果不分区,一个值为20亿的数字需要耗用238m的空间。

2.分区bitmap的优势和问题,对于数字最大范围为20亿,按照不同的大小分区如下:如果每个分区很大,那么少量分布均匀的数字很容易占满所有分区;如果每个分区很小,分区数(key的数量)就很多,key的空间开销也很大。那么如何做到最优的空间消耗呢?

3.RoaringBitmap的核心原理和不足。

· RoaringBitmap(官网地址论文地址)是Druid、Spark、Hive等很多大数据框架依赖的bitmap核心组件,我们先看看它是怎么做到空间优化的。

· RoaringBitmap将一个整型数字拆分成高低2个短整型,并共用高位做key,可以知道最大分区为65535,低位做value,可以用一个short[][] 来存储,相同key的value存储在同一个short[] 里,进行二分查找去重,当value的数量到达4096时,空间消耗已经等同于一个长度为65535的bitmap,这时进行bitmap转换。RoaringBitmap在理论上通过高低分位成两个short类型数字,从而有效节省数据量小时的空间开销,并在数据增长到临界点4096时转换成bitmap,数据量大时不再增长空间开销。

但是RoaringBitmap在落地的实现和应用中仍然通常在面临以下问题,不能做到性能和空间最优:

· 高低分位后,实际上形成一个65535*4096的固定分区,对不同的数据特点,不能灵活设置分区大小和分区数量以满足不同数据范围和不同增长幅度的场景需求;

· 在其Java的实现版本里,由于short数组的动态变长,产生大量的无用对象不能及时垃圾回收(gc),而且只有当每个分区抵达4096数量时才能转为bitmap停止内存增长,容易导致在分区均匀情况下接近4096的时候空间开销很大,这时bitmap的数量很少,而65535个short[] 动态增长产生的大量垃圾内存,其实际空间消耗已经远远超出理论的预估值。

· 耗时慢,由于二分查找去重需要进行数组排序,会产生额外的性能消耗,特别是数据量低于5000万时,二分查找的性能并不比线性查找有优势,反而耗时更多。当数据量很大时,数组结构已经转成bitmap,此时二分查找已经不再起作用。

4.原创实现的高效ArrayBitmap。

为了克服数据量小而且稀疏时导致的bitmap空间浪费问题,经过实践摸索寻找到一种动态增长的分桶数组结合bitmap数据结构的新设计方案来解决,经过大量测试证明,相对于RoaringBitmap有更好的性能和更优的内存空间消耗。

性能测试对比。经过和roaring bitmap不同数据大小的测试对比(20亿范围随机),情况如下:

· 10万、50万、100万、500万、1000万数据范围:内存占用略同于roaring bitmap,但耗时只有一半;

· 5000万数据:由于超过3000万转bitmap存在拷贝空间耗用,内存占用大于roaring bitmap,但是耗时更低;

· 1亿数据:内存占用和roaring bitmap接近,但是耗时只有三分之一。

· 2亿及以上数据:内存占用低于roaring bitmap,耗时只有四分之一。

为了方便读者理解上面的思想,作者抽取出了两个简化的Java实现类供参考,CoolBitSet.java实现了bitmap的所有操作,CoolBitMap.java是集成了数组和bitmap存储的高级结构,可在附件下载。

(六)锋刃大数据平台的建立

在成功解决了以上bitmap的各种问题后,经过1年多的建设,基于流式处理结合bitmap技术,从最开始的架构方案和程序demo,已经实施落地为完整的大数据计算系统“锋刃”,系统边界不仅解决实时计算,还包括离线提速和OLAP,和当前数据工厂(Hadoop+Hive)互补,并且作为平台提供bitmap结构的文件存储,以及OLAP的大数据分析系统。PCG运营数据应用框架团队提供锋刃平台开发和场景实施支持。

七、业务场景实施及架构升级

(一)腾讯灯塔实时统计上线

腾讯灯塔产品介绍。

腾讯灯塔是基于腾讯海量大数据开发的移动应用智能数据分析平台,聚焦数据驱动用户增长,为业务提供分析云与营销云服务。提供包括应用分析、广告效果监测、广告渠道反作弊、DMP标签、市场指数等全链路大数据运营服务。腾讯灯塔秉承独立第三方的数据服务理念,去伪存真,指引有价值的增长。目前日均处理4000亿 +日志,覆盖MAU 13亿,积累7大类,1000+ 标签。产品官网:beacon.qq.com

1.灯塔实时计算经历“实时清洗上线—实时统计开发实施—试运行1个月—故障演练”共3个月,目前已经全量上线,所有产品可以查看一维1分钟和10分钟到实时新增、启动用户、启动次数。当前运行状况正常。

2.确定了实时系统服务保障量化指标,保证实时查看结果,对延迟情况保障:平均延时不超过5分钟,异常延时(版本更新重启等)不超过30分钟,超过30分钟属故障。vip产品(1分钟,10分钟,日)保证和离线统计结果偏差不超过万分之五,长尾产品结果偏差不超过千分之五。

3.数据核对情况:以10分钟为标准,目前实时计算结果和离线统计结果核对一致。1分钟离线没有统计,日统计离线有策略补充基准不一样,经过和灯塔业务确认,统一了核对结果。

资源耗用情况:约35台机器(去重服务:6台m10,flink:11台m10,去重dcache:4台m10共200g,id server:10台docker合计1台m10,id server dcache:10台m10+3ts80)。

(二)腾讯某安全产品场景离线提速上线

· 需求:当前离线hive计算每日25亿数量大app的卸载留存很难算出,复杂任务计算耗时从早上8点到晚上11点。

· 方案:现改用bitmap方案对1200个app进行优化提速,按app_渠道 _日划分为12万个bitmap进行聚合计算。

· 效果:现统计留存卸载的耗时为,日10秒,周20秒,月1-2分钟(90个bitmap聚合)

· 耗用资源:20台机器(flink2台、去重服务7台、dcache10台(400g)、id查询1台)

目前已经上线一期、二期。

(三)腾讯某大数据分析产品离线分析架构升级

· 需求:当前离线hive跑3000亿全表join1000亿日表耗时7小时以上,难以满足模型频繁验证。

· 方案:3000亿全表按照app维度理论生成3000万的bitmap(其中用于统计的数量在100以上有200万),1000亿日表用于统计的数量100以上的有48万,20亿用户大盘表生成1个bitmap,通过三类bitmap求新增并更新历史全表和大盘用户表。

(四)ABTest实时数据分析平台

1.ABTest的应用场景可以分为两大类型。

(1) 算法类:浏览器资讯、广告、搜索、推送。

(2) 运营活动:浏览器框架改版、浏览器vivo装机新用户推送、应用宝活动类。

2.ABTest需求。

为了衡量算法投放前后或者是运营行为活动前后的效果,我们需要实时计算下述指标及综合指标的前后变化,并且通过用户标签(搜索类、看资讯类、点快链类、无行为类)划分人群来分析。

(1) PV,UV,CTR;活跃,留存,新增,收入… 等实时/离线指标提升

(2) 模型量化计算综合提升

如下图,需要通过实时计算将表格内的统计指标完成:

3.Abtest系统架构方案。

4.ABtest实时数据分析平台上线。

之前几个小时才能看到线上数据,现在只要五分钟!

实时数据能让我们能更快的看到实验数据,及时发现并下线异常实验。同时也能实时监控实验,及大盘核心指标,发现异常数据。更快发现问题就能更及时解决问题,从而降低异常对线上用户的的影响。

(五)业务实施推动架构升级

在实施上线以上实时统计、离线加速的业务场景,业务系统获得了高性能的同时,也暴露了在高可用性和高可靠性的某些不足,为此,也推动着锋刃实施团队进行自身的架构升级。

1.首先flink的清洗和去重改造成基于消息通道的生产消费模式,借助消息offset消费位可以更准确的故障恢复消费。

2.增加配置平台工具化方便业务配置自己的清洗逻辑、统计逻辑、聚合逻辑等。

3.我们发现,锋刃系统大部分的时间精力耗在上面的虚线框内,实现一个分布式的bitmap计算引擎、内存结构、及持久化存储上,以及稳定性保障上。将bitmap引擎迁移到部门kv存储产品decache和bdb上,并提供专门的热备、故障恢复、冷热切换、内存管理、分布式扩容等特性。这样锋刃复杂繁重的去重服务模块就简化成一个代理模块,可以更专注在业务需求的满足上。如下图:

八、OLAP的愿景目标

我们的大数据统计需求其实可以归纳为两大类型:

· 关键维度的实时监控:适合少量关键维度比如app的去重用户、新增用户指标监控,周期性强,每分钟每天都需要统计输出。

· 所有维度的OLAP查询:适合业务的自定义排查分析,比如一次促销活动后,新增用户指标上去了,业务人员想通过地区、版本、版面栏目、动作等多种维度信息分析新增用户的构成,这是一种非周期性的排查分析需求。之前这样的特定需求都是业务方提交给数据分析人员专门写hive离线任务去完成。如果我们的大数据OLAP能力足够强大,可以让业务和产品人员完成所有维度的自定义查询,而且能在5秒内接近实时得到查询结果。可以很大提升我们的大数据统计效率和满足业务的灵活多样型,同时这样我们的数据分析人员也可以从繁琐的统计工作中得到释放,去转型做模型分析。

总的来说,做到让用户“关键维度自助看实时监控、所有维度分析自助OLAP”,彻底解放我们的技术人员,这是我们想通过技术手段实现的愿景。

锋刃系统可以很好满足第1点的关键维度实时监控,但是要支持所有维度的统计,会产生大量的维度组合生成的bitmap,并不适合走实时内存处理,并且高度灵活的根据维度取值来自定义查询,需要增加维度列式存储和索引设计。锋刃系统接下来需要在设计上增强对OLAP能力的满足。

我们先看看以Druid为代表的大数据OLAP技术的主要设计原理。

(一)Druid的主要原理

简言之,Druid的设计原理可以通过上述步骤归纳:

1.提出rowid、时间戳、维度(多个)、指标(多个)的OLAP数据模型,并按列压缩存储,导入明细数据时设置rollup为true可以实现自动上钻合并,比如点击数累加。

2.在数据导入时,进行预计算,根据维度取值生成rowid的bitmap索引,而锋刃系统则是根据业务的特点,基于手机用户(IMEI)生成bitmap索引,这是两者的本质区别。

3.和4.当执行带维度条件的SQL语句时,将gd和1.1对应的bitmap做聚合后得到关联的rowid

4.通过关联的rowid找到列存储对应的指标点击数,进行累加得到最后结果。

由于列存储和bitmap索引机制的高效性,Druid不需要遍历整个数据集也不需要读取整行数据就能接近实时的计算出结果。

但是Druid在解决海量用户精确去重存在以下不足:

· 由于Druid的指标只能是数字,IMEI无法当作指标,只能当作维度,几十亿imei会产生几十亿的bitmap索引,对内存会产生压力导致益出风险;

· Druid是按行号建立bitmap索引,只能做根据维度取值的关联,找出关联行,但是bitmap索引不做IMEI去重。去重只能通过常规的distinct方法完成,对于几十亿的IMEI去重耗时长,容易超时。

Druid要保证统计高精确性,必须要以明细存储,要牺牲导入时做聚合处理,增加查询时的处理压力。

(二)Druid、锋刃、Impala各自适用场景

Druid最擅长解决“点击数/下载数”这样的指标,并且维度取值不是太大的业务场景;解决几十亿IMEI统计场景比较吃力,需要约束业务范围和数据量,按app和业务分类分表,针对不同业务特定分析。但是对于含有历史新增imei去重的OLAP、以及多宽表关联仍然不太合适。

如前面提到的,锋刃当前适合解决预先定义的关键维度的实时统计和离线统计,是针对IMEI场景的高清确性的,但是设计上还不能覆盖所有维度的自定义OLAP。

Impala适合解决数据范围不大的集群内存能覆盖的业务场景,超出内存限制性能会直线下降。

(三)统一的OLAP架构方案

如果在OLAP架构上没有统一规划,完全由各业务团队自由搭建,就会形成基于Druid,Impala,Kudu,Kylin等各式各样框架的方案解决各自业务小范围需求的局面,造成功能重叠及人员浪费,而且长期来看业务团队自身也不具备强大的运维能力。如果我们完全自研一套OLAP系统,比如在锋刃上实现自研rowid反向索引、分布式节点存储、查询、任务调度等Druid的功能,到最后测试稳定可运行,也需要耗费很久时间,业务团队面临用户压力,没有足够的耐心等待。

所以我们在保持自研能力的同时,也在构思可以用于马上满足业务需求的架构集成方案,把锋刃和druid的优势整合进来,虽然底层设计没打通,但是通过上层的集成和封装能得到一套统一的OLAP架构方案。

1.Cube模型归纳

经过思考,首先架构方案需要满足一个cube的索引模型,才能很好支持自定义OLAP查询,由于维度长短不齐,这是一个看上去不规整立方体(cube),可以通过时间、维度、取值切蛋糕似得拿到rowid和imei的bitmap索引。这样就能很快找到维度条件关联的rowid计算count类指标,并拿到对应的imei的bitmap计算用户去重类指标。

Cube[t][d][v] = bitmap(rowid) ,bitmap(imei)

t:时间 (Z轴) ,d:维度 (Y轴) ,v:取值 (X轴)

横切:查找t2时间数据,cube[t2][ ][ ]

竖切:查找d2维度数据,cube[ ][d2][ ]

切块:查找t0-t1时间,d0=v0 and d0=v1的数据,cube[<2][d0][<2](红框内)

2.锋刃 + Druid的OLAP架构方案

如果我们不是直接自研实现,而是把锋刃和Druid通过如下架构方案集成,也是可以间接满足上面的cube的索引模型,虽然看上去有一点小别扭。

(1)锋刃继续承担消息的接入、实时清洗、和用户去重,这里把用户去重分成上面归纳的两种类型,一类是实时出的关键指标,基于内存结构;一类是可适当延迟出的所有维度指标,基于持久化存储,把这两部分的用户去重结果都导入到Druid。

(2)Druid承担所有维度的自定义查询,由于锋刃完成了用户去重的功能,Druid除了可以快速根据自定义维度过滤,并完成count类指标统计外,还可以同时查到用户去重的结果,结果记录是按照group展开的。

我们注意到上面的方案还有一点缺陷,如果查出一个时间范围内的多条用户结果,不能通过Druid直接合并显示,这时需要返回锋刃系统找到对应的用户bitmap再做去重后返回结果。

(3)我们把用户的自定义查询过程封装成一个统一的输入输出如下,这样看上去就是一个基本实现OLAP功能的完整方案了。

总结

本文从集群压力到大数据平台整体架构,再到实时优化的切入,一步步阐述了锋刃大数据系统产生的来龙去脉,重点介绍了流式处理结合bitmap技术架构方案的主要原理,相关业务场景实施上线,以及后续的OLAP目标规划。关于锋刃大数据系统更多的内容,请参考锋刃团队后续的设计文档、使用指南、以及开源计划。

作者介绍

彭渊,现任腾讯T4专家,历任阿里资深专家,华为中间件首席架构师,淘宝高级专家等。在中国IT互联网技术领域从业多年,曾撰写多款开源软件,代表作有Fourinone(四不像)分布式核心技术框架、CoolHash并行数据库引擎等,曾出版书籍《大规模分布式系统架构与设计实战》,拥有多项软件著作权和专利。