介绍完了埋点信息,接下来重点讲解流量数仓建设和归因建设,首先介绍流量数仓架构,美团外卖信息如何采集。
1. 流量数仓模型架构
在整个流量数仓建设过程中还是面对很多挑战的,比如,美团外卖信息如何采集:
数据量大,每天几百亿条的日志,数仓模型要使用成本低、查询性能较好;采集的客户端种类多、日志种类多,数仓建模过程中维度建设复杂、数据整合复杂;业务系统变更频繁,特别是资源位、广告位变更频繁,数仓模型要及时响应、运维成本低;多变的归因统计需求 ( 目标行为和来源行为都不固定 ),需要归因模型使用成本低且易用性高。
整个流量数仓架构如图中所示,与之前惠明老师介绍的《美团外卖离线数仓建设实践》基本相同,具体细节可参考原文,这里稍微讲下:
ODL:Operational Data Layer,操作型数据层,这一层主要对采集到的数据进行无损着陆、基础字段清洗加工。ODL是原始日志明细宽表,完成了日志数据清洗过滤、归因建设、公共维度建设等。全链路归因建设在这一层实现。公共维度建设比如地理位置维度生成、常用维度代理键生成等,下沉到ODL来进行,降低了运维和下游使用成本,需要依赖于DIM层的环境维度表。
IDL:Integrated Data Layer,集成数据层,这一层在ODL之上,主要完成领域数据建模,描述业务对象属性、业务对象间的关系、业务行为属性、业务行为与业务对象的关系等。IDL层是明细宽表层,根据数据域和业务过程进行主题划分,在主题内描述业务对象和业务行为,特别是对主题内常用的扩展维度字段进行提取,并且进一步使用维度退化手段,提高明细宽表的易用性、降低使用成本。例如搜索主题筛选了用户搜索行为相关的日志,并将描述搜索业务的扩展字段进行提取。
CDL:Component Data Layer,元件数据层,这一层在IDL之上,主要完成分析实体识别,在主题划分基础上,形成分析实体/实体关系特征模型,对模型的指标进行加工,分为明细数据视图和聚合数据表两类。
MDL:Mart Data Layer,集市数据层,这一层在CDL之上,建立在主题划分基础上,通过维度层级汇总形成汇总表,通过维度主键关联形成宽表,给数据应用提供便利应用的半成品数据集,例如,常见的商家流量宽表(商家的点击、曝光、进店统计)。
ADL:App Data Layer,应用数据层,不属于OneData内统一建设,这一层在MDL之上,直接面对数据应用,优先使用MDL的数据,当MDL不满足时,可以向下使用CDL、IDL的数据。ADL作为数据应用的个性化数据一般不对外提供数据服务。
DIM:公共维度层,包括了流量数仓建设过程中使用的流量维表,分成主题维度表和环境维度表。其中主题维度表将埋点标识(用户行为标识)映射成主题维度,是IDL、CDL进行主题划分的核心维度表。环境维度表包括了流量静态属性中常见的维度,例如app名称、启动渠道、设备类型等,主要应用于ODL层的公共维度建设。
2. 流量数仓建设原则
在数仓建设中有很多原则,这里拿出其中三个在流量数仓中比较重要的原则跟大家分享下:
① 高内聚和低耦合
将业务相近或相关、粒度相同、高概率同时访问的数据放在一起。具体在流量数仓建设过程中,合理的主题划分其实就是遵循高内聚低耦合的原则。不合理的主题划分会导致数据使用成本、运维成本增大。主题划分是和业务强相关的事情,需要大家定期 review 自己的主题划分是否合理,一定要紧跟业务需求。
② 公共处理逻辑下沉且单一
越是底层公用的处理逻辑,越要放在数据底层封装与实现,不要让公共逻辑多处存在且暴露给上层的表。流量底层数据的公共处理逻辑主要是环境维度建设和归因建设。
③ 成本与性能平衡
适当的进行数据冗余来换取查询和刷新性能,但不要过度冗余与数据复制。这是最通俗易懂的原则,但在流量数仓建设过程中,需要综合考虑各种使用场景,实践起来很难。美团外卖每天的数据量几百亿条,这样一份数据,如果在多处出现复制,对存储资源就是很大的浪费。成本与性能平衡确实需要多思考,在做数仓规划时就需要把这个事情考虑到。具体实践如下:
仅在IDL层保留了明细的日志数据,且通过维度退化手段提高明细宽表表的易用性、降低使用成本。IDL层的主题划分过程,如果B主题是A主题的子集,两个主题的区别在于业务描述(业务扩展维度字段)不同,那么A主题使用表来存储逻辑和数据,B主题在A主题表之上使用视图的方式存储数据加工逻辑。举例来说,在美团外卖app首页存在着很多资源位,资源位中有有一部分是营销活动的位置,那么营销活动主题就是B主题,美团外卖app首页资源位主题就是A主题。在CDL层对明细数据也使用了视图,不再占用物理存储。
3. 维度建设
为什么常说流量数据在做数仓建设时比业务数据困难,个人觉得是因为流量数据的数据源本身是一些半结构化的数据,没有分析维度的概念,所以在数仓的建设时我们要做很多的维度建设工作。因此维度建设是整个流量数仓工作中最核心工作,同时也是最大的难点。
我们维度建设分为两种,环境维度和主题维度。
环境维度:
环境维度是指用户行为所处的环境描述,例如用户的定位城市、用户的设备类型、用户使用的app名称等,这些维度是在主题划分基础上,分析实体维度模型中最主要的维度,即用户在选定业务过程后最主要的分析视角。环境维度建设主要遵守公共处理逻辑下沉且单一这个原则,在ODL完成建设。环境维度建设过程中,如果分析的维度在日志中已经存在明确字段,且该字段具有业务含义并是自然主键,那么就会直接使用这个自然键和相对应的维度属性表。如果分析的维度需要日志中的多个字段联合,这时我们会对这多个字段生成一个代理键,并构建以这个代理键为主键的维度属性表。
举例来说,终端维度需要由日志中的操作系统类型、app名称、启动渠道这三个字段联合生成。如下表所示,我们使用这三个字段生成了一个代理键终端id。特别说明的是,终端id的映射维表并不是简单的可以通过操作系统、app名称、启动渠道这三个字段关联得到。比如,终端id=3的这一行,操作系统字段可以为任意值(对上报日志不做要求)。这就要求我们在生成代理键的时候需要采取一种更加灵活的方式,以应对上游数据的不确定性冲击。所以我们使用了UDF来实现:
UDF ( 操作系统,app名称,启动渠道 )=终端id
UDF中可以适配各种灵活多变的映射逻辑,这样大大提高了我们的灵活性,降低了运维成本。代理键生成之后,我们构建了终端id为主键的维度属性表。
主题维度:
原始日志在采集上来之后,是不具备业务过程分类的,仅仅能通过埋点标识来做区分。所以我们需要对日志进行主题划分,也就是业务过程划分。举例来说,我们想知道一个用户在外卖搜索页的全部行为,我们就需要先找到外卖搜索页的全部埋点标识,然后从原始日志中过滤出来。主题划分就是,将原始日志进行按照埋点标识划分到不同的主题表中。
我们将外卖整体的业务过程按照实体加行为进行抽象。外卖业务中,常见的实体包括用户、商家、菜品、订单。实体和实体之间通过行为来连接。比如,用户和商家之间的行为可以有搜索、使用智能助手、使用购物车、点击商家资源位等。
我们将这个埋点标识与主题表中的业务标识构建成主题维度表,用于管理埋点标识与业务标识的关系。在主题维表中,业务标识使用代理键,并在IDL中通过主题维表关联出代理键。主题划分过程中,我们还需要将主题内常用的扩展维度字段进行提取,对于不同的埋点提取这些字段的方式不太一样,我们也将埋点标识与主题扩展维度提取方式的对应关系维护在主题维度表中。
以资源位主题为例讲解一下建设的过程:
业务过程描述:在做主题建设时我们首先要确定业务过程,这里的业务过程就是从外卖的资源位点击开始,用户在点击之后会进入商家页,然后进入提单页提交订单,最后下单。
业务过程提取:描述清楚业务过程之后,要对业务过程进行提取,即从 ODL 日志中找出所有浏览和点击的日志,具体做法是:
首先维护一张资源位主题维度表,表中记录下埋点与资源位的对应关系然后通过 ODL 日志表与资源位主题维度表关联即可获得资源位埋点的浏览、点击明细日志。同时我们在描述资源位这个业务活动的时候需要看资源位位置,这个位置就是描述用户点击的商家在商家列表的第几位,资源位位置在各个埋点里上报的值可能不一样,所以需要在资源位主题维度表里记录埋点标识,记录好之后在加工 IDL 表时就可以根据埋点标识将资源位位置加工出来。同理进入商家页、进入提交订单页还有提交订单的业务过程提取也是一样的,先找出他们的日志,再根据维表信息关联加工出 IDL 表,只不过这里的关联字段使用的链路信息字段
维度管理:
在维度建设这边,最后再聊下维度管理的事情,从刚才的内容大家应该也可以感受到,在流量数仓中维度建设是最核心的内容,它决定流量数仓的分析视角以及流量数仓的运维成本,在做流量数仓建设时建议认真做下维度管理。
我们是专门做了一个工具来做维度管理。所有维度信息在管理平台统一录入、校验、更新,最后同步到数仓的 DIM 层,给数仓的生产使用。这样降低了数仓的运维成本。
4. 归因建设
归因需求介绍:
前面内容我们讲了数仓整体架构以及维度建设方面内容细节,接下来我们介绍流量数据最核心的、也是大家会经常遇到的归因建设。在流量数据分析场景中,有一类需求是基于单一埋点或埋点集合的且不需要进行日志关联的分析,比如某种用户行为的人数、次数等;另一类需求是需要将日志进行关联并且对日志的先后顺序有要求的分析,比如常见的统计经过外卖首页商家列表点击后的成单行为人数、次数。第二类需求其实就是我们说的流量数据归因。
流量数据归因建设在外卖业务场景下是非常难的,难点有二:数据量大,在几百亿条的日志中,将需要的日志进行关联是非常耗时、耗资源的;需求不固定,通常我们无法预知需求方想将哪些日志做归因分析。
因此,流量数据归因建设要重点解决这两个难点问题,特别是难点二,由于需求的不固定,我们要实现全链路的归因建设,而不是只针对某些行为的日志做归因建设。
首先,我们要将需求简化并且标准化,我们将所有的归因统计抽象成如下问题描述:
统计经过A行为的B行为的次 ( 人 ) 数
应对这样的问题,给出的伪SQL:
select count(1) from 日志 where 行为=B and 链路信息 包含 A
经过这样抽象后,我们发现问题变得清晰一些,这个伪SQL就是所有归因分析场景的标准化查询。问题聚焦在"链路信息"的建设。我们要为每一个用户行为建立一个链路信息字段。
什么是链路信息呢?在外卖业务场景下,链路信息是:某一行为的时间前序行为集合,集合中不包含相同页面之间的行为。
链路信息建设:
在目标表中,为每一行数据新增一列链路信息,使用数组格式来存储当前行的行为的链路信息。数组中每一个元素即代表一个时间前序行为(排除了MV事件),其中包含的字段会选取一些业务独特的、与当前行为不同的字段(不包括通用环境字段),这是由于一个行为的时间前序行为中,通用环境字段一般是相同的(比如设备号、操作系统等),且通用环境字段已经作为了分组排序的条件。这样设计表结构的好处是:目标表的行数没有变多;对所有的用户点击行为和用户进入某一页面行为加工了链路信息字段。
可能会有同学质疑这个字段会不会特别长,特别是当用户行为链路特别长的时候,后面的行为日志这个字段值会很长。这种场景下我们就需要考虑到底哪些行为应该放在这个字段里,这里我们使用因果关系来判断哪个行为是这行日志的原因行为。
我们将因果关系定义为为与相同页面之间的事情无关。如上图中事件序列记录某用户从 P1 点击进入 P2 再点击进入 P3,然后又回到 P2 接着回到了 P1 又点击了其它模块。在这段用户行为中 P3 的链路信息如图中所示彩色部分只包含第一次到达 P3 时经过的路径;M5 模块的链路信息如图中彩色模块所示,我们认为图中所示的两个 P2 之间的链路与 M5 链路信息无关;M7 的链路信息同理。
这样我们屏蔽掉用户操作过程中的回退操作,最终记录的链路信息字段值不会很大,当然这种因果关系一定要契合业务情况。
定义好链路信息和目标表结构之后,我们进行数据加工,链路信息字段使用udf(自定义函数)来加工得到,伪SQL代码如下:
insert into target table select log表中的字段,udf(归因处理输入字段) as 原因行为 from 分组排序后的log表
归因处理输入字段选取了部分通用环境字段和业务字段,通用环境字段用来判断当前行数据中的环境参数是否发生变化(例如是否换了一个设备),业务字段主要用于udf的输出结果。具体数据处理流程如下:
1. 对日志进行分组排序,使用distribute by按照通用环境字段进行分组,使用sort by按照时间戳顺序排序,这样保证了相同分组的数据分配到同一个reducer当中进行处理,并且是按照时间戳排序之后进行有序处理;
2. 在日志分组排序之后,进行链路信息字段加工,使用hive udf来实现。在udf中,通过栈来存储链路信息,一次udf执行过程简述如下图所示:udf输入参数的通用环境字段用来判断是否更换了设备或app,如果通用参数发生变化,说明上一个分组内的数据全部处理完,清空栈内的数据,把当前行为入栈。如果通用参数没有发生变化,说明仍然在处理相同组内的数据。需要判断当前行为的加入是否发生页面回退,如果发生页面回退,则需按将相同页面之间的行为出栈,最终将当前行为入栈。
3. 结果数据输出过程中,会首先进行行为标记,比如将每个页面的最后一次点击行为进行特殊标记,然后再将栈中所有的元素放入数组中,作为最终的链路信息字段。
链路信息字段加工之后,我们要使用这个字段来解决流量归因统计需求。我们回过头来看一下之前提到的流量数据归因建设两个难点。其实,把问题标准化成统计经过A行为的B行为的次(人)数,并且加工出链路信息字段,就已经解决了上述的两个难点问题:链路信息字段是经过分组排序加工出来的,等同于提前做好了日志关联;对所有的用户点击行为和用户进入某一页面行为都加工了链路信息字段,实现了全链路归因。链路信息字段加工过程是与业务需求解耦的,即不根据业务需求定制化开发,这就使得我们的方案具有很强的灵活性和拓展性。在IDL层可以根据主题的需要取出任何主题所需要的归因数据。
其中,链路信息包含某行为需要通过udf来实现,因此我们开发了一系列的udf、udtf来使用链路信息字段。
前面介绍了在归因建设中我们使用的链路信息追加的方案,可能在业界其他团队使用的是其它的方案,比如挂单,这里给出不同方案的简单对比
添加上方▲技术, 在线咨询
复制微信号
声明
一、本站原创内容,其版权属于本网站所有。其他媒体、网站或个人转载使用时不得进行商业性的原版原式的转载,也不得歪曲和篡改本网站所发布的内容。如转载须注明文章来源。
二、本网站转载其它媒体作品的目的在于传递更多信息,并不代表本网站赞同其观点和对其真实性负责;如侵犯你的权益请告诉我们立即删除;其他媒体、网站或个人转载使用自负法律责任。
发表评论
2022-06-14 15:51:37回复