前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【腾讯微视】百亿数据、上百维度、秒级查询的多维分析场景的实践方案

【腾讯微视】百亿数据、上百维度、秒级查询的多维分析场景的实践方案

作者头像
腾讯大讲堂
发布2021-03-15 16:40:08
1.9K0
发布2021-03-15 16:40:08
举报
文章被收录于专栏:腾讯大讲堂的专栏

作者:teachzhang  腾讯PCG工程师

|导语  大数据多维分析是业务中非常常见的分析场景,目前也有许多落地方案,但是在遇到上百亿数据、维度个数不限、秒级返回结果这样的场景时,实现的时候还是遇到了一些挑战。本文介绍了一种参考kylin的预聚合模式实现的存储方案,支持对上百亿数据以及数百个维度的多维分析,并且能在秒级返回查询结果。该方案可以运用于多维指标拆解分析,异动归因分析业务场景。希望给其他有类似分析场景的同学提供一种参考方案,对本内容感兴趣的同学,欢迎一起交流学习。

1. 背景

周报场景:微视的分析师每周一需要对上周的业务情况进行分析,整理成周报向领导进行汇报。以前的流程是在灯塔上通过执行大量复杂的sql查询需要的数据,然后下载数据,整理成许多多维分析树。查询的数据以周为单位,需要查询4周的数据,数据量达几百亿,因此每次查询都需要很长的时间(小时级),并且经常碰到查询超时的情况。当分析模型变动时,又得需要改动sql重新查询。总结就是,查询流程长,人工成本非常大,整个团队的分析师周一一大半时间都fork在周报整理上。

即席分析:当业务指标大幅变动时,需要快速找出变动原因,例如当DAU下跌时,分析师需要从多个维度钻取,找出具体的下跌原因。

除此之外,希望在微信小程序查看多维分析报表,从数据中发掘出更多的价值。

因此急需建设一个多维分析平台,解决目前的业务痛点。

2. 产品介绍

最终我们开发了一个归因分析平台,产品演示如下:

特殊说明:1.展示数据经过脱敏处理;2.为了演示直接使用了已运行好的报表。

功能特色:

  • 零SQL实现数据多维分析,直接选择指标和维度,快速构建多维分析报表;
  • 速度快,对于每天4000W数据量的用户报表,回溯30天只需5~10分钟;对于每天上亿的消费数据报表,回溯30天需要30~60分钟;
  • 对于例行的报表,秒级返回结果;
  • 精确设置每个节点数据波动范围,当时数据波动超过阈值,在报表上进行告警提示;
  • 可以将分析报表以图片和excel的方式导出;
  • 支持在小程序上查询报表,随时随地看数;
  • 快速添加维度和指标,维度和指标支持逻辑计算,可以快速配置添加新指标和维度,对于大宽表存在的指标,无需回溯历史数据。

归因分析:

以上是分析师创建的归因报表(注:数据为假数据),用于分析拉活对内软下各渠道的影响。

3. 技术难点

要实现这样一个多维分析系统,有以下难点需要解决:

  • 数据量大:每天的数据量数10亿,一次查询28天数据,数据量达几百亿;
  • 时间范围不确定:查询的时间范围不确定,可能是一周的数据,也可能是任意选择的某几天数据。
  • 维度多:目前常用的维度约50个,以后还会继续增加,上不封顶;
  • 秒级查询:因为需要在小程序上支持多维分析,因此需要在1秒内返回分析结果;
  • 动态增减维度和指标:随着业务的发展,会不断的添加维度和指标,并且需要支持自定义计算逻辑。

4. 实现思路

4.1 分析树拆解

首先我们来看一下一棵多维分析树是如果查询数据的。上面是一棵多维分析树,m1代表指标,例如DAU、总时长等,D1代表维度,例如城市、首启方式等。对于这棵树,转化成sql去查询数据,一次sql无法实现,只能多次查询才能取得结果,分为以下组合查询:

(D0)

(D1), (D2) (D1, D3), (D1, D4) (D1, D4, D5), (D1, D4, D6)

例如(D1, D3)转化成sql如下

select D1, D3, m1 from table group by D1, D3;

 D0代表对全部聚合查询。对于一颗具有n个维度,m个指标的分析树,查询sql的次数为m*(n+1)次。

4.2 存储引擎调研

接下来需要选择一个合适的大数据分析引擎,目前常用的有ES、Spark、Kylin、Clickhouse、灯塔、Hermes,我们分别对这些引擎进行了调研,进行了对比:

  • Spark:spark查询时间较长,不采用。
  • 灯塔:灯塔提供对外接口,可以执行sql语句,但是经过测试,对一个几千万数据量的表,进行单维度、单指标聚合查询需要15s左右,无法满足要求。
  • Kylin:Kylin采用预聚合的方式,提前将所有聚合维度和指标计算好,因此能实现亚秒级响应,查询时间上满足要求,但是Kylin对cube的维度有限制,正常情况在10个维度左右,本次的需求需要至少40个维度,以后还会继续增加。虽然Kylin提供了剪枝功能,但我们的场景中,分析师会选择任意的多个维度进行组合,所以无法利用剪枝进行优化,因此Kylin也无法采用。
  • ElasticSearch:ES对于千万级数据的聚合查询可以很好的支持,一旦遇到较为复杂的多维度组合查询并且聚合的数据量比较大(如数十亿),就可能会产生大量的分组,对 ES 的性能压力很大,查询时间很长。并且本次需求中有许多指标需要进行distinct计算,然而ES不支持精确去重,并且也不好支持复杂的计算指标,因此不采用ES。
  • ClickHouse:ClickHouse是一款PB级的OLAP数据库,采用列式存储,适合大数据多维分析,但是目前资源不够。申请资源至少需要1个月时间,且需要保存明细数据,需要大量的存储和计算成本。
  • Hermes:Hermes是公司内部自研的一个实时秒级分析平台,采用类似ES的索引机制,支持sql查询,查询性能也不错(一次查询秒级),但是也无法支持上百亿数据的查询。

4.3 预聚合

通过对现有分析引擎的调研,发现它们都无法满足我们的业务场景。从查询时间要求出发,只有Kylin这种预聚合的引擎才能满足,但Kylin维度爆炸问题无法解决。以40个维度,最多5层维度组合为例,组合方式有C(40,5)=658008种,在上亿数据量的情况下Kylin无法聚合出结果。

通过对需求进一步分析,发现虽然维度非常多,但是分析师在使用中根本不会用到这么多维度组合,对于一个包含10个维度的报表,用到的维度组合为10,并且业务的分析逻辑基本上有迹可循,最终的维度组合最多只有几千。但是Kylin不支持指定维度组合的方式构建cube。因此我们决定参考Kylin的原理自己实现预聚合。

最终实现方案:将报表拆解为多个维度组合的cube,按天预聚合去查询每个cube的数据,将结果缓存起来。用户查询报表时,直接从缓存中取数。当新数据产出后,只需要增量缓存最新一天数据即可。

底层存储的选择上,只有Hermes和clickhouse比较适合,但是由于clickhouse现在资源紧张,并且业务方希望尽快上线,因此最终选择了Hermes作为查询存储引擎。

5. 实现方案

5.1 整体架构

整体架构分为四层

汇总层:根据前端传入的查询时间,按照本期、同比周期、环比周期、基期分别去聚合层查询分析树,然后将4颗树的数据汇总到一颗树上,计算出指标的同比、环比、同比等指标。

聚合层:解析多维分析树,拆分为多个cube,按照cube到聚合层查询数据,根据聚合指标的计算逻辑计算出指标绝对值,构造出一颗多维分析树。

预聚合层:维护所有分析树中用到的cube集合,自动调度cube任务,解析成sql语句,从Hermes查询聚合数据,最终缓存到ES。

源数据层:采用Hermes存储底层明细数据,利用Hermes的sql能力查询聚合数据;采用ES存储聚合数据,最终报表的查询直接从ES中查询缓存数据,做到秒级响应。

接下来重点介绍预聚合层的实现原理。

5.2 预聚合层

5.2.1 kylin的存储结构

因为本架构是参考Kylin实现的,所以首先介绍一下Kylin的存储结构。

Apach Kylin是一个开源分布式数仓,提供超大规模的多维分析能力,这里就不详细介绍了,网上有很多文章,这里重点介绍Kylin Cube的实现方式。Cube也就是多维立方体,提前将所有维度的可能的组合提前聚合分析好,以Cube为单位存储起来。

这里以查询DAU场景为例,假如有城市(city)、渠道(channel)、消费层次(consume_level)三个维度,那么所有维度的组合有2^3=8种。

一维度(1D)的组合有:(city)、(channel)、(consume_level)

二维度(2D)的组合有:(city, channel)、(city, consume_level)、(channel, consume_level)

三维度(3D)的组合有:(city, channel, consume_level)

另外还有(0D),总共8种。

假设有以下数据:

城市

消费层次

渠道

qimei

北京

c1

10

北京

c2

20

北京

c2

30

北京

c4

40

上海

c1

50

上海

c3

60

现在计算DAU=count(distinct qimei),按照上面的方式计算所以维度组合

为了压缩存储,需要对维度和维度值进行编码,生成维度字典。

维度编码:

维度值编码:

最终对所以cube编码如下:

其中code和itemKey中的0代表全部。

5.2.2 预聚合层架构

首先给出cube和cube任务的定义。维度编码+指标代表一个cube,例如(101, m1);cube再加上日期代表一个cube任务,例如(20210101, 101, m1)。

目前预聚合层会缓存30天的数据,一个分析报表创建好之后,需要缓存近30天的数据,当所有数据都缓存好之后,该报表才可用。第二天新的数据产出后,预聚合层自动缓存最新的数据,然后报表的时间范围就更新到最新。即用户创建好报表后,以后无需操作,就能查询最近一个月的数据。

创建一个报表的流程如下:

  1. 用户在界面上拖拽维度和指标构建多维分析树,创建好之后保存报表,点击“运行”按钮,此时报表状态为“运行中”;
  2. 将分析树拆分成多个cube,插入cube集合,如果cube已经存在则无需再次插入。
  3. 预聚合层定时调度,检测cube集合中的每个cube,是否最近一个月都有数据,如果没有,则创建相应日期的cube任务。
  4. 任务执行器执行cube任务,解析成sql,去Hermes查询聚合数据,然后对结果进行编码,最后将结果存储到ES当中。
  5. 当一个月数据缓存完成后,更新报表状态为“运行成功”,此时报表就可以查询数据了。

5.3 其他功能

缓存数据多版本:对于同一cube的数据,可以存在多个版本。这是因为当一个报表的数据缓存好之后,如果此时某几天数据出问题了需要重跑,那么需要将所有数据重跑好了之后,再一次全部切换,否则会让用户看到中间态的数据。

动态添加指标和维度:可以根据现有的维度和指标配置出新的维度指标,无需重跑源表数据。

支持留存维度和指标:支持不同留存时间的维度和指标,比如次留、3日留存、7日留存等等。

6.未来优化

1.优化底层存储。目前支持的数据分析时间范围为一个月,未来可能会增加到3个月或者半年,相应的缓存时间就会变长,Hermes的存储成本也会变大,未来准备支持多个数据底层数据源,比如灯塔、presto、clickhouse等,加速缓存。

2.添加各种归因算法。未来准备在归因分析树上应用一些归因算法,比如JS散度等,智能的找出指标的影响因素。

3.添加报表全局过滤功能。在报表上添加过滤条件,限定整棵树的分析范围。

4.支持维度间的层级关系。比如支持城市、区域维度之间的层级关系。

近期热文

【Node开发】分布式调用限频限流的开发设计

解决单点故障 - 有状态服务的高可用

如何输出有价值的商业解决方案?

让我知道你在看

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯大讲堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 【Node开发】分布式调用限频限流的开发设计
  • 解决单点故障 - 有状态服务的高可用
  • 如何输出有价值的商业解决方案?
相关产品与服务
大数据
全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档