Fork me on GitHub

B站埋点数据标准化实践

以下文章来源于 https://zhuanlan.zhihu.com/p/644137017

导读 用户行为数据管理和对应的行为数据分析的关系十分紧密,如何在产品层面上应用好,前置条件是埋点数据需要做到标准化管理、标准化应用,这是很多行业内公司及团队都会碰到的课题。本文将和大家一起分享B站在埋点标准化方面的实践经验。

全文目录:

  1. 埋点标准化背景
  2. 标准化实践策略
  3. 后续展望
  4. Q&A

分享嘉宾|李奎 哔哩哔哩 资深数据产品经理

编辑整理|lumiuu 西山居

出品社区|DataFun


01

埋点标准化背景

1.埋点的定义



(1)什么是埋点

先举一个实际的例子,比如用户在某一时刻点击了某个APP里面某个页面上的推荐按钮,这一信息将被记录下来,会以一条日志的方式去做上报,存储到服务器当中,这样的日志信息可以定义为一个埋点。

埋点的结构可以抽象为who、when、where、what、how这五个关键词,记录用户在APP、网页或小程序里面一系列的行为。实际上不管是用户在客户端的行为,还是在接口日志的变更记录,都是埋点的一种类型,这就是常见的客户端埋点以及服务端埋点。

(2)埋点的作用

日常工作中,非常常见的一类数据是,统计APP的日活、每一天的新增用户、新增用户路径流转等,这些数据是偏分析用的。另一类是推荐算法的调优等。这些都是常见的埋点的应用场景,需要应用到埋点处理后的数据。

如上图中可以看到,用户点击推荐按钮,就会有JSON格式的日志上报,这份日志整体可以划分为两个部分,是典型的上报埋点日志格式,包括用于定位用户ID、操作的时间戳、操作的类型,以及业务所需要的一些参数,比如点进去的位置,这个页面的名称等等。

2.埋点数据链路

埋点的应用过程会有一个比较长的链路。这里以B站的埋点应用链路为例,做一个简单的拆解。


图中从左到右是埋点数据从生产到消费使用的整个过程,底层的埋点测试与埋点元数据管理是做数据应用支撑管理的一部分。

从生产环节来看,业内都会将埋点采集抽象为可复用的埋点数据模型并集成到SDK内,避免每次业务开发都要重新定义采集的格式规范。这个SDK通常会划分为iOS、安卓、Web、服务端等等,还有以backload的方式批量导入的离线数据,这是数据的生产侧。

在数据流转侧,通过抽取转换加载(ETL)的方式进入到传输流,这里有两条链路,一部分业务需要消费数据实时流,另一部分业务是消费离线数据。实时流的消费可能会用于算法推荐,或者实时的数据分析,实时的监控看板。离线的数据,就是关于数仓的ODS到DWD,再到ADS的这个部分。在离线存储的部分,数据的存储会采用不同的介质,比如常见的HDFS、Parquet等等。查询引擎包含了ClickHouse、Presto、Hive等行业内主流引擎,B站也提供了一个可视化的Web,给产品经理、分析师、运营等同学去操作分析。

B站的同学通过点选的操作去查看埋点常见的PV、UV数据,前端把操作拼接的参数传给查询引擎,作为查询SQL的拼写。业内关于查询引擎的采纳,根据每个公司的数据量会有多种不同的方案。常见的情况是:如果数据量比较小,那就直接用Hive查询,如果数据量多一些,那可能会用Presto。目前对于B站的日增千亿的数据量级,采用的是ClickHouse作为查询引擎。

为支撑整个数据链路,还会采用埋点测试去保障埋点数据质量。再往下是埋点元数据管理,这也是本次分享的重点内容。

3.常见业务问题



在业务服务、业务支持过程中,面对非常多的业务痛点,主要可以归纳为两大方面:生产设计和消费使用。

  • 生产设计方面

首先,最常见的问题就是属性命名,不同的业务和开发团队有着不同的命名偏好,有的人喜欢驼峰命名,有的人喜欢用下划线做分割,有的人喜欢用中划线去做分割,这会导致埋点非常混乱,需要统一命名的规范。

第二个问题是在埋点上报的时候,有记录业务属性的参数,在业务实际的管理过程中,可能会出现参数枚举的映射值找不到了,比如原本是小写的abc,另一个业务用的是大写ABC,业务值的映射方向混乱会导致埋点管理的混乱。

第三个问题是在埋点生产的过程中,会涉及到数据产品、开发人员、测试人员以及线上的应用方,参与方越多,各方的埋点信息越可能对不齐。

最后一个问题是,用Excel或文档来管理埋点,数据量少的时候是可以操作的,但是数据量多、交接的人员多的情况下,信息失真就会比较严重。

  • 消费使用方面

第一个问题是,运营常常会向产品发起拷问,页面上对应的埋点是哪个ID?在数据里面找不到。

第二个问题,查询埋点数据的时候,应该查询哪一张表,过滤哪一个埋点的参数,私有参数是什么。

第三个问题,数仓治理时,存储的压力非常大,并非所有的业务埋点都是一定会使用的。其中有一部分比如曝光的埋点,它的性价比会比较低,那么可以考虑做分级的存储。

第四个问题是关于权限,运营需要查询某一个埋点的数据,是否要全部开放还是只开放一部分,需要精细化管理。

02

标准化实践策略

针对上述问题,B站提出了从埋点生产到消费下线全生命周期的管理。其重点就是在埋点元数据管理这一环节。

1.B站埋点数据的现状和历史迭代



目前,B站线上有1万+的客户端埋点在应用中,整个埋点的元数据量非常大。另外,各类网页Web端有10万+埋点。日增量数据上报,达到了千亿级别,一周就会达到万亿级别,数据量非常庞大。

在历史上,埋点的迭代经历了三个半阶段。

  • 第一个阶段是按业务需求定制化管理,比如采集播放详情页的浏览,一个埋点设计一个字段,存成一张Hive表或日志表。这种做法很明显的弊端就是管理会非常混乱,数据只能一次性使用,没有办法做一个收敛。
  • 第二个阶段,在意识到埋点应该做抽象化跟模型的设计后,就开始引用事件模型,但引入了事件模型以后,没有做产品化工具化的支持,还是由业务去做管理。
  • 第三个阶段,在事件模型的基础上,抽象出了b站业务埋点的特征。统一定义了公共字段,不管这个业务私有的属性要不要上报,公共字段要求统一上报。在SDK里面减小业务重复开发成本,再加上业务自定制事件,已经具备了抽象的雏形。
  • 从19年开始,进入到一个新的阶段,开始逐步规范SPMID的埋点模型,加上沉淀出来的产品化管理,辅助以工具跟模型产品,去进行规范的定义。

2.埋点设计

在埋点标准化设计的过程当中,有4个重要的部分:埋点命名规范,埋点属性管理,工具化支持,以及流程与规范。

(1)埋点命名规范

首先来看一下埋点的命名,很多业务会各自命名埋点的eventID,需要一个低门槛的工具管理埋点的eventID,不需要思考怎么样命名,也不要去做随机的编码,而是要有一个高业务可读性的ID信息。另外,几个版本需要有可延续性,不要过几个版本就混乱了。要求可交接或者可读性,在版本之间的迁移度是较高的。最后,还需要有一个工具保证不同维护人之间可以顺畅交接。



B站在标准化实践中引入了spmid(super-model)模型。在埋点的eventID中包含业务的实际信息,将各业务含义抽象在埋点ID当中,然后将这个ID进行维表化的管理。整体分成五个部分,包括业务ID、页面ID、模块、位置和埋点类型。通过规范的命名可以提升整个业务的可读性,在做埋点数据治理时,可以合理的定位问题,降低埋点的成本。相同的命名,不同的埋点类型可以做到复用。



上图中展示了一个实际的例子,在埋点的首页,推荐按钮应该如何命名?这个埋点可以命名为
bili.homepage.top-tabbar.0.click,这样一个命名中包含了很多业务使用的含义。拆解来看,这个埋点实际上包含四个业务粒度及埋点类型的元信息。业务的粒度从粗到细,覆盖了business_id、page_id、model_id、position_id。

对于使用者来说,拿到这个eventID以后能快速地定位到这个埋点所处的页面模块、位置模块,以及在哪一个页面homepage,所属的业务线是哪一条,能够精确地定位它所处的业务线对应的信息。

这个业务埋点ID,对于做一个定位或者类型的划分,能够做到业务的可读性非常高,分摊业务埋点的成本,并且复用性非常高。点击的埋点命名为click,那同样一个模块,曝光的埋点,命名为show就可以了。

在做埋点的时候,上报的时候会划分为客户端SDK上报以及服务端上报。客户端通过埋点的类型划分,包括启动、浏览、曝光、点击、播放、系统以及其它事件。服务端包括这个API的请求记录,以及业务端业务表的日志变更信息。

上述就是B站关于埋点的命名的一些经验。

(2)埋点属性管理



在埋点上报的时候,有一个很重要的部分是记录埋点的属性参数。埋点属性在业务含义当中是对用户有一些定制采集的信息。会做三个层级的划分:

首先是全局公共字段,包括埋点事件ID、APP信息、触发的时间戳、触发时间的网络、运营商、操作系统的版本等等。

第二个是针对不同的埋点类型,包括页面浏览PV、播放,或者业务特色的业务内容埋点,抽象出这个类型通用字段去做一个具体的预填充。

这两个部分都是预设在SDK当中,业务开发无需二次处理。

第三个部分就是业务定制化的私有参数,比如做海报轮播的时候,需要这个海报轮播的bannerID,或者这个海报对应跳转up主的mid等参数,就是业务它自定义去使用的参数信息。

在业内有另外两种主流的方案,一种是采集参数,平铺预留10-20个param的私有参数,另外一种就是只区分公共属性跟私有字段的属性。这两类方案的问题是扩展性会有一些欠缺,虽然在早期的时候可以快速地去辅助业务的数据采集,但是后期的治理成本比较高。经过长期的实践发现,采用公共字段+类型通用字段+私有字段这种方式,是一个比较通用,而且扩展性比较强的埋点属性规范方式,保证了灵活性和扩展性。



关于埋点属性规范,在数仓中,比如一张Hive表,会有表字段级别的数据标准。在埋点数据当中,把埋点抽象为业务表,埋点的属性实际上映射为表当中的字段,所以引申出来,它也有属性标准。

一个管理的规范会划分为三大类,一类是基础的描述信息,第二类是属性的质量,第三类辅助去做属性管理所使用的信息。

第一类基础属性,常见的有命名规范是否符合下划线连接、点号连接,中划线连接。数据的类型,到底是字符串还是数值,还是枚举类型。

第二个部分是它的数据质量,包括埋点是否为空值、枚举值,默认值应该填充为Null,还是一个中划线,这些是后面做埋点测试的时候使用,测试规则都是基于这部分埋点的属性标准。

第三类是元数据集管理,包括埋点的版本,属性的优先级、安全等级等等。以B站为例,安全等级会划分为S级、A级、B级、C级、D级几个不同的等级,其中S级是最重要的一个安全等级。

(3)工具化支持



我们希望应用工具去做SPMID的模型支持,而避免让业务同学人工选择。B站内部沉淀了一款叫做北极星的埋点管理工具。

上图中可以看到,这是一个埋点事件创建模块,将埋点的业务、页面、模块、位置、类型都抽象为了维表化的选择。创建埋点的运营和产品只需要去做下拉点击的筛选,而不需要去从头去做一个埋点设计。如果有历史的埋点,做一个快速地复制,修改一些参数信息即可。

第一部分是埋点的命名。第二部分是去做埋点属性的标准化,包括属性ID、属性显示名,属性的枚举类型等等。第三个部分是业务比较关注的上报时机,埋点是否需要做抽样上报,以及配置远程是否停止采集。

上述的几个部分都做了维表化抽象,每个环节、每个模块都有一个对应的管理列表,结构化存储在业务表中,方便下游的使用。



以图中模块列表为例,对应的埋点模块已经做了一个标准化的命名,它的英文ID跟中文含义相互映射。

在使用过程当中,只需要做一个查询,就可以知道对应模块是使用在哪一款产品,以及哪一个业务线当中的,做到了层层递进,维表化的复用。

(4)流程与规范



B站把整个埋点流程及规范,划分为了六个环节以及四个重要的参与方。

四个重要的参与方分别如下,业务同学提出了需求以后,给到数据产品同学,数据产品把业务需求抽象为埋点需求文档,称为DRD,然后跟开发进行可行性方案的评审,根据优先级、成本去进行评估,最后落地为开发排期进行需求上线,需求开发完成通过测试,再给到数据同学进行分析。

**六个环节除了包含上述四个参与方的环节,还包含数据采集和验证。**开发根据这个需求文档进行埋点开发,对服务端或者客户端的行为去做接口日志的采集存储,最后交由数据产品或者测试同学进行埋点测试。测试会借助到埋点管理工具当中的一个测试模块。最后测试完成,进行上线使用。上线的场景包括指标分析、算法推荐,输出数仓的中间表、数仓ADS层的应用,以及数据看板等等。

3.基于埋点标准化元数据的提效应用

B站在关于数据标准化的实践上,还提出了应用提效,存储、规范的埋点元数据,这并不是为了管理规范而规范,而是有实际应用场景,发挥埋点的价值。可归纳为三个应用场景,第一个是数据报得更准确,第二个是存储成本变得更低,第三个是查询变得更方便。

(1)上报更准确



为了让上报变得更准确,有一个很重要的工具,埋点测试的时候能够快速精准、半自动甚至是全自动能够发现业务上报的问题点在什么地方。在埋点设计的时候,根据业务的需求抽象为DRD,这部分会录入到结构化的埋点管理工具当中,埋点管理工具去生成测试校验或者DQC校验的一些规则,比如枚举空值、默认值以及值范围等等。

同时在埋点进行抽样,配置元数据信息下发到客户端SDK。通过这个环节,测试机可以在测试后台进行扫码,通过SDK上报埋点参数,服务端进行埋点的接收,对埋点日志进行解析,包括实时的Kafka或者JSON格式的数据,解析到测试链路当中。

测试链路分成两个部分,一个是汇总展示的日志报告,另外一个就是明细测试数据的解析,在测试机上触发哪些埋点的规则,命中了模块中哪些校验规则,哪些是达标的,哪些不达标?不达标的原因是什么?通过整个从生产到测试传输链路流程的支持,提升埋点上报校验的质量和效率。



从实际效果来看,可以通过手机客户端的APP扫码连接埋点测试模块,测试模块能够实时地接收到上报端使用到的埋点数据,并且能够映射到之前在源数据中已经录入的中文名、埋点的属性、DQC等规则,进行实时的校验判断,汇总并生成可视化的测试报告。基于埋点标准化的元数据,B站能够做到近实时的效果检验,覆盖了APP、web端以及服务端的埋点测试。

如果测试环境中的埋点数据出现缺失,通过这个链路能够迅速回填到埋点管理的环节当中,做到埋点数据标准、快速的回补。从而保证上报得更准确,而且让测试工作变得更简单、更直观。

(2)存储成本变得更低



数据存储的压力,实际上在埋点部分会更突出、更严重。如果埋点的数据不做存储的降本增效,那么成本是非常高的,因为有很多的业务会出现这种情况,不管有没有用,先上报上来,这意味着埋点数据有泛滥的倾向。

所以我们在埋点源数据下游的管理方向上,按照业务进行分库分表,这样存储管理就变得更容易,中间表按照业务类型进行划分,按照业务的businessID,也就是埋点的首位ID,做业务的分表,在数仓DWD层或者DWS层,按照这个分层是一个很好的依据。

除了业务的分区分表,同时也可以降低存储周期。有了eventID的元数据,将埋点的等级划分为S级、A级、B级、C级,不同的等级对应到不同存储的周期,不同的存储粒度。同时针对不同的埋点类型,不管是点击曝光页面浏览,针对性地去做埋点的抽样上报。

对于曝光类的埋点,很多时候业务价值是比较低的,重点只是想看一下模块曝光PV跟UV。但是对于点击类的埋点,它的业务价值会高一些,会详细地区分用户主动触发的这一类埋点,比如点击、启动。不同埋点类型,对应不同的性价比,根据不同的性价比可以做埋点的抽样,比如抽10%、20%或1%,或者埋点已经下线了,远程进行下线开关的配置。

(3)查询变得更方便



在做埋点分析的时候,希望尽量去代码化,以工具和前端交互UI页面提供给分析师和产品经理,这样的方式会更友好、更直观。

已经准备好了埋点的元数据,提供一个前端查询的页面,通过获取用户前端的操作,跟埋点管理的元数据模块相互结合,以及DB层面上存储好的埋点的元数据,发起查询的SQL,返回查询结果的结果集,进行一个可视化的BI展示,支持折线图、柱状图的等多种可视化图形。

在这一过程中可以看到,查询的SQL或者查询的字段,会依赖前置的分区去做查询的加速,并降低成本,提升整体的效率。

B站内部已有服务于业务团队的产品,图中上方是做埋点分析的模块,通过读取埋点的元数据,做可视化展示,包括前置已经抽象出来的埋点私有属性,这里能够做两个部分的分析,一个是去做快速筛选过滤,另一个是做分组展示。这里实现的分析的提效,都是依赖埋点数据标准化的存储和管理。

03

后续展望

关于未来的展望,最近B站在做的探索是基于已经标准化的埋点元数据做自动化分流。业内经常所做的数据架构链路是分成两个部分,一个是消费数据的实时流,经常使用的是Kafka;另外一个是消费离线的Hive表,去做ODS、DWD、DWS数仓分层的建设。如果已经接入了埋点的元数据,是否可以做流批一体的统一化管理,或者统一化的消费使用,做到一次的分流配置,它的实时跟离线均能够生效,而且两边的口径是对齐的。

对于下一步业务的分流使用,可以预设业务的中间表,有业务想要定制消费某几个埋点,或者是某一些业务数据,通过埋点ID的划分去做一个中间表,或者叫视图级别的消费,减少下游读取全表的查询成本。

最后通过流批一体的链路做到线上实时高优消费埋点数据流,用于业务端的推荐算法等等。



以上就是本次分享的内容。欢迎大家关注B站的技术公众号,进行更多的交流。

04

Q&A

Q1:关于埋点的标准化管理,上线以后如何保障新旧数据兼容?

A1:假设在web端的埋点,有一套埋点管理的标准,在APP的埋点也有好几套不同的埋点标准,在上报的埋点中,公共参数、私有参数埋点的命名规范不太一样。有两种处理的方案,第一种是在离线的数仓层面,做一个中间层的整合,通过离线数仓backload的方式,把历史重要的埋点写入到埋点数仓当中,增加埋点的eventID字段,做一个埋点兼容的处理。第二个方案是比如业务的埋点命名,相对还可以再抢救一下,它的埋点虽然有不规范,但是不规范程度并不是那么严重,还可以修改。对于增量的这一类需求,面向业务宣讲,命名应该按照SPMID的模块标准化进行,历史可以用批量导入的方式做兼容。总体来讲,就是按照存量跟增量以及业务不规范的严重程度,做两类划分处理。

Q2:B站埋点标准化的实践,会展开ToB的产品化服务吗?是否会做一个ToB的商业化?

A2:目前B站还是在内部去做ToB的服务,短期暂时内应该不会对外部做SaaS服务,但是可以和大家做一个交流。

Q3:如何理解曝光数据的抽样上报?如果是曝光抽样点击全量上报的话,点击率计算是否有问题?

A3:元数据记录这个抽样比例,下发给客户端SDK。比如抽样10%,一共触发有10条数据,那SDK会上报1条。分析的时候要做一次转化,比如PV上报的是1万条,那实际上抽样10%,那实际的PV那应该是1万/抽样率10%,也就是PV是乘以10倍,按这样的方式进行转换计算。

Q4:埋点需求如何满足上线的时效性?如何做到跟业务的需求同步上线?

A4:其实就是文章中提到的协同环节过程,如何协同各方在合适的时间节点做埋点的上报,或者规范统一。比如运营提的需求已经提前先上线了,但是埋点需求还没有补,实际上是流程中不太规范。

在B站这边,实际在进行业务方案评审的时候,业务的需求文档一定会包含埋点需求文档,业务评审是包含数据采集的。业务模块上线,那埋点采集也就同步上线了,同时录入管理是一个通过流程协作规范的方式,评审环节就已经解决掉这些问题了。

还有一个同步上线的问题,可能存在历史的模块,它的埋点没有采集,需要统一提某个版本的需求,做一个集中补充采集。

Q5:SPMID的规范设计工作会不会很繁琐?

A5:如果纯人工的方式去做埋点,SPMID的设计确实是非常繁琐的,但是B站上线了这些功能:快速复制、一键复制、一键导入,用户在做埋点设计的时候,是不需要从头进行设计的。点击复制,然后修改对应的模块参数就可以了。SDK目前能够下发到对应的埋点参数信息,部分公共参数是全部做到自动化采集。网页端可以做到自动上报,APP端还需要做相互的check。

今天的分享就到这里,谢谢大家。



▌2023数据智能创新与实践大会

数据架构/数据效能/智能应用/算法创新......

4大体系,专业解构数据智能

16个主题论坛,覆盖当下热点与趋势

70+演讲,兼具创新与最佳实践

1000+专业观众,内行人的技术盛会

点击下方链接了解详情:

DataFunCon2023(北京站):数据智能创新与实践大会 �-�百格活动


本文地址:https://www.6aiq.com/article/1689589211422
本文版权归作者和AIQ共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出