导读:随着业务的发展,业务上报的埋点数据会越来越多,杂乱的埋点数据不仅会消耗计算和存储成本,造成巨大的成本浪费,也无法有效的应用于业务,给业务带去数据价值,因此埋点数据的治理就很有必要。
今天分享的主题是在字节跳动应用的埋点成本治理实践,本次分享从如下几个方面来介绍:
治理背景
治理策略
治理经验回顾
规划与展望
一、治理背景
埋点数据是用户在使用产品过程中产生的一系列行为日志,比如用户使用抖音过程中点击、滑动等操作。对了解用户、优化业务来说,用户行为日志是非常重要的数据来源。
在字节的数据处理链路中:
第一,埋点从各端的 SDK 上报数据到日志采集服务。
第二,日志采集服务则将收集到的埋点数据统一汇集到实时的 topic 中。
第三,在实时 topic 中进行统一实时 ETL 处理,包括数据清洗、数据分发、标准化等。数据在进行处理之后会分发到各个下游应用,包括实时消费、离线数仓、UBA(即用户行为分析)、推荐系统、A/B 测试等。
埋点在字节跳动广泛应用,因此数据规模也非常庞大,峰值流量达到1亿+/秒,增量数据达到10万亿/天。为处理这些数据,HDFS的存储增量达到10+PB/天。
庞大的数据量会给日常运维造成很多问题,如机器资源问题、成本问题、运维问题、SLA 保障问题。
以机器资源问题为例。去年,团队遇到了 HDFS 无法及时交付的情况,埋点数据治理机制及时删除了无用埋点和低优埋点。如果当时没有这套机制,全部数据产出可能受到影响。
以运维问题为例。日常运维中最常遇到的 case 就是异常数据上报导致流量的突增。在有埋点治理机制的情况下,我们可以及时处理异常流量,否则束手无策。
埋点治理的核心思想是把有限资源投入到有效数据上报中,而不是浪费在无效的数据上报上。
字节的埋点治理机制在公司内取得的效果与收益也是比较大的:
目前埋点治理已经应用到抖音、头条等多个业务,并且可以覆盖内部 85% 的业务线。
通过无用埋点下线机制,2021 年节省了近亿元的成本。
通过埋点分级机制,节省了 100+ PB 的 HDFS 存储。
通过埋点采样机制,2022 年截止目前已经节省了 3000 万+的成本。
接下来会进一步推广埋点治理机制,节省更多成本。
二、治理策略
在从 0 到 1 建设埋点成本治理的过程中,我们针对各种不同的场景采取不同的策略。
1、 先控增量,再治存量
如果在业务发展过程中引入的治理,那么首先面临的问题是,业务侧既有存量埋点数据上报,同时也在不断设计和增加新的埋点数据上报。
假设要治理的数据是一个大水池(且进水口在不断的往里进水),目标是净化大水池,则需要先在进水口加装净化器,避免边治理边污染。
该道理应用于埋点治理,则需要先把新增埋点控制起来,再逐步治理存量数据。
为了控制新增,我们增加埋点上报管控的机制。在过去,业务上报埋点是*的;增加了埋点上报管控后,则需要先将上报信息登记到“允许上报”列表中,只有该列表中的埋点才能够正常上报。
为了让上报管控机制生效, 我们在数据链路中的 SDK 上报、实时 ETL 两个环节分别增加了对应的处理。这两个环节可以形成互补作用:
在 SDK 侧实现上报管控,让管控生效时机更加接近源头,节省更多网络带宽和计算资源。
依赖 SDK 侧进行管控存在一定限制因素:需要业务将SDK升级到“支持上报管控”的版本。
如果要推动全产品线升级 SDK,耗时较长,也很难避免一些老旧版本迟迟无法升级。
通过实时 ETL 进行上报管控处理,则可以很好弥补这一缺陷:它可以管控所有的上下游, 也能快速推广到全产品线。
目前这一套机制,已经在在字节 1 亿+/秒流量及 50+万条元数据情况下正常运转。
为了让业务能动态地维护和管理“允许上报”列表,我们提供了平台化的功能:业务在字节内部可以通过流量平台 ByteIO 做埋点的录入、登记、状态管理。
上报管控的机制可以实现直接管控流量上报,这也是后续开展治理的基础。
2、降低无用埋点上报
控制好新增的埋点数据以后,接下来要对存量的数据进行治理。存量数据治理里广泛存在的现象是:某些埋点已经不再使用了,但它仍在持续上报,造成资源的浪费。针对这种情况,我们希望提供给业务一项能力:将无用埋点筛选出来,将其从“允许上报”的列表中移除出去,不再上报。
为了定义无用埋点,我们会分析对比各个埋点的价值、成本,如果某个埋点的成本很高,而价值很低,那么它就是需要优先被治理的。
① 埋点的成本直接与上报量相关:如果埋点的上报量越高,对它投入的计算和存储成本就越高。
② 埋点的价值则从三个维度进行分析:
离线查询,例如在 Hive 表中是否用到这个埋点;
实时分流,例如这个埋点是否通过特定的实时分流规则,分流到了其他的 topic 中进行消费;
是否有UBA的查询。
如果在这三个维度上某个埋点的使用非常少,那么我们认为它的价值就是略低的。
为了降低无用埋点的上报,我们支持业务通过 ByteIO 平台筛选无用埋点,并且发起治理;最终确认下线的埋点将不再允许上报。
通过无用埋点下线这一机制,在 2021 年节省了近亿元成本。
3、按重要性区分埋点等级
无用埋点治理下线之后,留下的埋点业务仍需使用,但它们的重要性不同。比如核心指标要用到的埋点数据和 RD 排查问题要用到的埋点数据,在重要性和优先级上有明显区别,因此在 TTL 和 SLA 上要求是不一样的。而在过去的设计中,计算资源和存储资源没办法优先向高优的埋点进行倾斜。当计算或存储资源短缺或遇到问题时,会导致所有数据一起出问题,并没有哪些埋点数据会优先得到保障。
为了应对这个问题,我们提出了埋点分级的方案,即通过区分埋点的重要性给埋点标注等级,对不同的埋点等级提供不同的运维保障,达到平衡计算资源和存储资源的目的。
为了让埋点分级机制生效,首先需要把埋点分级信息发送给实时 ETL,实时 ETL 会根据该元数据信息对收集到的埋点数据增加等级标注,之后数据再整体流向下游。当下游拿到打上等级标注的数据后,会根据等级标注的信息再区分 TTL 和 SLA 的保障。
以下图数仓中的处理为例,可以看到实时 topic 里的数据已经带上等级标注信息了(priority 参数),数仓要做的是根据不同的分级结果将 topic 中的数据分发到对应的 dump 目录,再由不同的任务产出、加载到对应的分区中。
通过这一套埋点分级的处理,我们可以针对优先级不同的埋点数据提供不同的 SLA 和 TTL 保障,同时可以达到平衡计算和存储资源的目的。以任务为例,P0 的任务可以用高优的队列、专线的资源,在 dump 产出的时候就进行产出;而 P2 的任务可能就用低优的队列、混部的资源, 在错峰的时间产出。通过这样的方式,计算资源就实现了向 P0 任务倾斜。再以分区为例,P0 分区可能保持更长的 TTL,比如说保存一年以上,而 P2 可能只保存 90 天左右。通过对 P2 分区进行更频繁的删除,有限的存储资源也是向 P0 的分区倾斜的。
业务可以通过 ByteIO 平台的功能直接对埋点分级信息进行管理。而通过埋点分级这套机制,我们节省了 100+PB 的 HDFS 存储。
4、支持采样上报
除了重要性不同外,还有一些埋点需要使用、但不需要全量上报。对于这一类埋点,我们提供埋点采样化的配置,来支持埋点采样上报。和前边的上报管控类似,采样上报也是在 SDK 和实时 ETL 两个环节生效,在这里就不再额外赘述。
业务可以在 ByteIO 平台配置埋点是否需要采样及采样比例。通过埋点采样的机制,在 2022 年已经节省了 3000+万的成本。
三、治理经验回顾
在推动埋点成本治理的过程中,我们遇到了一些问题:
第一,在业务发展过程中开始的治理,需要先控新增再治存量。
第二,如何推动业务完成治理。我们需要向业务侧提供明确的 3W1H:即我为什么要治理(WHY)、我要治理什么(WHAT)、我怎么治理(HOW)以及我什么时候应该去治理(WHEN)。
第三,随着治理程度的加深,场景和方案需要逐步细化。在“无用埋点下线->埋点分级->采样上报”的过程中可以体现这一点。
针对问题二,具体分享一些心得。
作为中台,我们需要向业务侧提供明确的 3W1H,而 3W1H 中的治理什么(WHAT)、怎么治理(HOW),从前面的“治理策略”部分可以大致总结出:治理的对象是无用的、不重要的、可采样的埋点,治理的方式是采用上述的策略和工具。
为什么要治理(WHY):业务存在不合理的资源浪费,并且通过治理可以降低成本。
什么时间应该治理(WHEN):在业务资源浪费超过预期、成本超过预期的时候。
为了证明这一点(WHY&WHEN),我们向业务提供了一组明确的观测指标。
埋点上报总量:平均每天业务会上报多少条数的埋点数据。
埋点成本:为了处理这部分数据,对应业务每天会花多少钱。
无用埋点占比:在当前的埋点数据上报总量中,无用埋点所占的比例是多少。
埋点密度:通过对比计算埋点上报总量与用户活跃总时长,来衡量业务数据量级的增长与业务规模的增长是否成正比。比如现在产品处在快速增长期,埋点数据上报量大增长则符合预期。但如果用户活跃总时长一直没变化,只有上报总量一直在飞速增长,则数据上报存在一定问题。
以上指标为业务判断是否需要治理的标准。当业务通过上述指标确认需要治理后,则直接串联使用“治理策略”中的策略和平台功能,对埋点进行治理,以达到治理优化的目的。
由此,指标监控和治理策略就形成了一个循环。
在推动治理的过程中也发现,虽然提供了指标,也提供了策略,但业务很难定期的、主动的去观测相关指标,并发起治理。经过了解后发现这主要和工作模式有关系,如果把依赖业务主动的指标观测变成由系统自动的监测并发起治理,业务也可以接受。因此我们就逐步建设和推广了自动治理的机制。
自动治理的主要思想是由系统自动监测指标变化,并且自动筛选可能需要治理的埋点,之后推送给业务,再由各个埋点的负责人来确认对应埋点是否需要治理。
基于这个机制,我们可以逐步迈向治理常态化的目标。
在自动治理机制中,面向不同的业务场景,又分出了两种模式:监督式和无监督式。
监督式的自动治理适合规模比较大一点的业务,这类业务有成本上的考虑,对治理的成果也比较关注。所以我们允许业务自定义监测规则,并且可以指派明确的治理监督人监督治理的进度和成果。监督人在这个过程中可以进行一些拉群、催办、成果 review 等等操作。
监督式治理目前在字节内部主要应用于抖音、头条等业务,平均每两个月会进行一次治理,在 2022 年已经节省了 4000 万元的成本。
无监督式自动治理适合广泛存在的小业务,这类业务结构较简单,可以完全托管给系统、使用统一规范进行治理。无监督式自动治理目前在字节内部主要落地应用于一些小的业务,它实现的一个效果是将这部分业务的平均无用埋点占比从 60% 降到了 20%,并且维持在一个比较稳定的状态。
另外,分享一些在埋点使用情况分析上的思考。
在“治理策略”部分提到,为了让业务降低无用埋点的上报,我们需要对埋点的使用情况进行分析。其中,UBA 查询因为可以直接对接特定系统,相对来说比较容易获取。而离线和实时的使用分析,则需要通过一些分析手段,去获取对应的使用情况、并进行血缘建设。
在字节的埋点数据使用过程中,离线和实时数据的传播有一定的相似性。如下图,其中每一个节点可以认为是一个离线 hive 表或实时 topic,节点之间存在明确的上下游关系。数据从根节点开始,一层层的向下传递,最终传递到各层级的节点中。除了节点间的传播外,数据也可以从节点中取出直接进行消费,比如对 hive 表的直接查询、对 topic 的直接消费等。节点间的传递、对节点的直接查询/消费,构成了整体的数据传播链路。
在这个传播链路中,埋点数据最原始的形式是根节点的一行记录。假使有一条下图所示的 ETL,查询范围是「app in ('X','Y') and event in ('a','b')」,它就能够明确的表示出这部分埋点会传播到该下游节点。这个明确的范围对埋点使用情况分析以及埋点治理来说是非常重要的信息,所以需要尽可能获得。
然而实际上并不总有这么理想的 ETL 和节点,更多的是:明确范围的 ETL 不在第一层,可能在第二层或第三层;或者不是直接出现这么完整的条件,而可能是多层组装之后才出现,如在第一层 ETL 中指定了 app 限制而第二层 ETL 指定了 event 限制。针对这些复杂多样的情况,理想的分析结果是:无论这个明确范围出现在了哪一层的节点、以及它是如何出现的,我们都可以分析出对应信息。
综上,为了达成完整的使用情况分析,需要达到:能够解析出各个层级 hive 表和 topic 里包含的埋点,以及各个层级 hive 表和 topic 被查询消费的埋点。
为了达到上述目标,实施方法里需要包含两个要素:第一,能够解析 ETL/查询/消费里和埋点相关的逻辑;第二,能够结合 hive 表/topic 的上下游关系,将解析做逐层的传播,得到最终各个层级的结果。
目前我们初步具备了这一能力,在当前的基础上接下来会做进一步的细化。
四、规划与展望
后续,我们将以下三个方向推动治理优化。
第一,打通成本与资源。针对各个业务治理情况,评估结果是否会影响业务后续资源申请。例如某业务的数据治理评分不太乐观,后续则不再允许业务新增埋点上报,反向推动业务进行主动治理。
第二,根据业务现状推荐个性化的治理方案。不同的业务有各自独特的业务特性,数据规模也不一致,导致的结果就是数据表现形式也不一样。未来希望根据业务的数据表现情况,自动诊断业务当前面临的最主要问题,基于此为其推荐个性化、高收益的治理方案。
第三,拓展治理范围。当前的数据治理方案更多着眼于高成本数据的治理,后续会考虑对异常数据、低质量数据进行治理。例如:治理体积过大、流量增长不合理的异常数据,降低日常运维中遇到的问题;治理低质量数据,减少下游数据产出问题,整体提高数据的质量。
以上介绍的埋点成本治理是数据治理的重要组成部分,主要在字节跳动内部应用。
目前,字节跳动也将沉淀的数据治理经验,通过火山引擎大数据研发治理套件 DataLeap 对外提供服务。作为一站式数据中台套件,DataLeap 汇集了字节内部多年积累的数据集成、开发、运维、治理、资产、安全等全套数据中台建设的经验,助力 ToB 市场客户提升数据研发治理效率、降低管理成本,欢迎大家来体验。