导读:本文介绍了美团外卖流量数据采集、流量数仓的建设以及典型的流量数据应用,其中重点介绍了流量数仓建设过程、在建设过程中需要关注的问题以及对应的解决方案。01流量数据采集
1. 美团外卖流量数据采集历史
数据生产链路主要有以下几个阶段:需求、配置、埋点、验证、上报、日志表。
流程是:在需求确定之后会做埋点的配置,客户端进行测试上线。之后客户端会根据用户行为将日志上报(这里分为实时上报和延迟上报两种)到 nginx 服务器,通过 flume 将日志收集传输到 kafka 里,然后做实时处理,包括数据校验、过滤、字段拆分等比较简单的数据处理,之后将数据落地到离线的 log 表,在离线阶段的会进行比较重的数据处理操作,比如去重、关联、标记等,最后产出公司级别数据表,提供公司各个业务部门使用。
4. 埋点注意事项
前面介绍了埋点的基本信息与规范流程,这里给大家介绍一些埋点的注意事项。个人觉得做埋点还是非常需要经验的,甚至是需要更多的试错,这里给大家列了一些注意事项以供参考:
同质参数的名称和类型保持一致:主要就是体现在通用参数、业务参数、行为标识的统一,尽量做到事前治理,给整个的数据加工、数仓建设减轻工作量,当然在数仓加工过程中也一定要做一些容错;
通用复用:尽量少的创建新的事件,而是想办法复用原来的事件,方便后续的埋点管理;比如某弹窗在很多页面都出现过,弹窗模块曝光标识需要是唯一的,当它出现在不同的页面的时候,我们可以通过页面标识 page_id 来区分,而不是每出现一个新的页面就重新定义一个模块标识;
最小粒度:埋点定义到模块内的最小元素,可以避免重复上报;
合并上报:相同模块的 MV 事件可以合并上报;某一页面中一定出现的元素可以不用上报 ( 这里是指 MV 曝光事件 ),或者和 PV 时间合并上报,在 PV 中加一个字段标识即可;
历史兼容:不能改变已有事件标识的含义,不能改变属性标识的含义,不能改变参数值的含义;一般只做新增,不做修改,可以废弃;
追踪回溯:埋点设计文档可以回退到历史版本,便于排查问题。
02流量数据加工
介绍完了埋点信息,接下来重点讲解流量数仓建设和归因建设,首先介绍流量数仓架构。
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为主键的维度属性表。
主题维度:
应对这样的问题,给出的伪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来使用链路信息字段。
前面介绍了在归因建设中我们使用的链路信息追加的方案,可能在业界其他团队使用的是其它的方案,比如挂单,这里给出不同方案的简单对比:
链路信息追加:典型空间换时间的方案,特点是存储冗余,同时需要写UDF实现,有一定使用成本,但是它比较灵活,可以支持任意的原因行为、目标行为分析指定目标事件归因:这种方案是针对固定场景的,适合在需求比较固定的业务场景。比如在当前阶段,我们只对订单这个事件做归因分析,那就可以在每条日志后面加一个字段记录订单id。相对链路信息追加这种方案的特点是存储不冗余、使用成本低,适用于需求固定的场景
仔细对比我们会发现这两种方案是对称的,链路信息追加存储的是当前行为之前发生的行为,挂单存储的是当前行为之后发生的行为。
勾稽关系:
接下来介绍一个流量数据校验方案,勾稽关系校验。勾稽关系在流量数据加工过程中可以很方便的做监控、校验。比如一个简单场景就是落地页流量要等于来源流量,搜索点击的人数一定是跟搜索页面浏览人数相差不大的。这里将勾稽关系单独列出,也是希望大家在做流量数仓过程中可以灵活使用它。
5. 埋点治理
介绍完数据加工内容之后,我们讲解下数据治理方案,整个的数据治理或者数据资产管理包含很多工作,细节可以参考《美团外卖离线数仓建设实践》,这里简单介绍下埋点治理方案。埋点数据的特点是数据量级很大,因此在做埋点治理时一定要做 ROI 评估,目前的办法就是做血缘追溯,追溯埋点在ETL任务中的使用情况。
我们将埋点使用情况分成了三类:
添加上方▲技术, 在线咨询
复制微信号
声明
一、本站原创内容,其版权属于本网站所有。其他媒体、网站或个人转载使用时不得进行商业性的原版原式的转载,也不得歪曲和篡改本网站所发布的内容。如转载须注明文章来源。
二、本网站转载其它媒体作品的目的在于传递更多信息,并不代表本网站赞同其观点和对其真实性负责;如侵犯你的权益请告诉我们立即删除;其他媒体、网站或个人转载使用自负法律责任。
发表评论
2022-06-15 00:34:32回复