0

快手数据成本白盒化治理实践

 6 months ago
source link: https://www.6aiq.com/article/1710046203068
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

导读 本文介绍我们最近一年在大数据成本方面的白盒化治理实践,通过深入到引擎、数仓和工具,打开架构,进行拆解和分析,实现有深度的成本治理,同时也拿到了不错结果。

主要内容包括以下几个部分:

  1. 数据治理体系

  2. 引擎白盒化

  3. 数仓白盒化

分享嘉宾|冯赞锋 快手 大数据架构师

编辑整理|苏屿

内容校对|李瑶

出品社区|DataFun


01数据治理体系

image-bd9a010c8aaf4f99adb6c57b4ac7d928.png-imageStyle

和行业大部分公司一样,快手数据治理也是分为四大部分:成本、质量、效率和安全。

1. 效率

分为数据开发效率和数据消费效率。开发效率主要关注模型开发效率,消费效率主要关注模型是否足够易用,查询响应是否足够快。

2. 安全

同样也是分为生产阶段的安全、还有消费阶段的安全。

3. 质量

分为避免发生、主动发现、故障结果、故障复盘。

  • **避免发生:**在设计、开发、测试和验收环节,是否符合规范。
  • **主动发现:**出了问题之后,一定是我们自己先发现,而不是用户告诉我们。首先要做到监控覆盖全面,其次还要实现有效的告警,确认告警的有效率,是非常关键、也是最难的部分。
  • **故障结果:**各个级别故障数量,是否在预期范围内,我们对故障是容忍的,只要控制在一定数量内。
  • **故障复盘:**首先,复盘要足够深刻,抓住问题本质、找到共性。其次,复盘会产生很多待改进问题,这些问题是否被及时解决了。

4. 成本

数据成本由三部分组成:存储成本、计算成本、流量成本。

  • **存储成本:**存储效率是白盒化的重点:压缩比、压缩性能、副本数。压缩比关注存储密度,压缩性能关注压缩耗时,副本数关注能否用较少的副本存储数据,确保数据不丢失。
  • **计算成本:**CPU 平均利用率衡量资源调度能力。如果调度能力不行,很容易出现负载不均,可能部分机器打满,另一部分却很空闲,导致集群整体利用率上不去。单 CU 处理数据量衡量引擎算力水平,随着我们不断去优化计算引擎,单 CU 处理的数据量也会随之升高。
  • 流量成本

本次分享主要是讲成本部分,我们通过三个白盒化实现:引擎白盒化 + 数仓白盒化 + 工具白盒化

02引擎白盒化

image-af05f060b9aa4b51ba4d7df5a648336d.png-imageStyle

"引擎白盒化",是一个具体的项目代号,这个项目包含很多优化点:HBO 自动化调参、压缩算法替换、引擎算子分析......

  1. HBO 自动调参

image-9818cc85060046eeaef343cfb2cb0d4b.png-imageStyle

什么是 HBO 自动调参?可以想象一下,在没有 HBO 之前,调参主要通过人工完成的,但有三大弊端:

**难度高:**对于一个普通数据开发者来说,这无疑是一件很难做好的事情。首先需要理解引擎原理,分析作业的几十个指标,找到性能问题,再调参,还不一定能调好。

**易失效:**随着时间推移,计算逻辑、数据内容可能早已发生改变,之前的调参过一段时间就失效了。

**成本大:**可以想像一下,对几万、十万个作业进行人工调参,基本是不可能完成的事情。

HBO 的出现就可以很好地解决这三大问题,它是通过分析任务运行历史,自动优化作业执行参数,从而使作业一直处于贴近最优的状态。

image-78edcc0e81264359a08bf6b47901c66d.png-imageStyle

HBO 为什么可以提升性能、降低成本?主要通过三个方面来实现的:

**(1)合理资源配额:**通过识别作业对 CPU 和内存的需求,自适应扩缩容,防止错配。

**(2)优化任务分片:**通过分析任务时长,灵活调整分片参数,以防止过短或过长。

**(3)任务优化功能参数:**通过调整小文件合并、压缩算法、Broadcast 等参数,以提升性能。

image-7ffec01a8ccf446cb5e74ddc3d305505.png-imageStyle

HBO 调参过程就是数据驱动的过程:

第1步,构建画像,需要采集几十个决策指标,指标的质量直接决定了 HBO 效果,需要的是严谨。

第2步,参数粗调,通过数据指标+预设规则,进行首次粗调参,粗调时会尽量的保守,比如:CPU/内存会尽可能多预留一些,以防止运行变慢。

第3步,参数下发,将调参的结果下发给各个任务,下发之后,下一个周期就会产生影响。

**第4步,参数精调,**粗调之后,我们能感知调参效果,根据最新反馈进一步精调、再精调。

image-7be8e6210b464509b697e8b90338d8c1.png-imageStyle

以上列举了部分调参列表,供参考。接下来我们看看第二个优化项,存储压缩算法替换。

  1. 压缩算法替换

image-0ab811f94d86418ea423dba09c7e1bfa.png-imageStyle

先看看快手大数据存储现状:

  • 技术选型:湖仓的底层存储是 PARQUET + GZIP。
  • **数据规模:**新增 PB / 存量 EB。
  • 数据读写:读写比大于 20:1,读取数据量远高于写入数据量,所以我们会更加关注解压性能,而压缩性能稍微差点,是可以接受的。
  • **存储周期:**很多数据存储周期比较长,甚至是永久存储,满足审计相关的需求,所以对于存储系统来说,压缩比永远是我们首要考虑的。
image-05e39c9a761343b994677596c5f95248.png-imageStyle

在压缩算法这块,快手选型是 GZIP,纵观行业里的很多公司,一开始也都是 gzip,不过这些公司都逐步切换到了 zstd,因此为他们节省了大量的成本。以上图片列举了:亚马逊、推特、优步几家公司在推特上的一些讨论。

image-b07be1980a2c40ed873e266b299060e2.png-imageStyle

Zstd 既有着和 zlib 相当的压缩率,同时还有媲美 snappy 的压缩性能,可谓是集合了两者的优势。

另外,我们也在线上进行了实测,压缩率提升 3%~12%,压缩级别越高,压缩率也就越高。Zstd 压缩级别分为 1-22,根据我们的观察,压缩级别超过 12 之后,压缩率提升的就不是很明显了,所以我们最终选择的压缩级别,最高不超过 12。

image-994b54fc3ee3431e94414da34e391ea6.png-imageStyle

此外,我们还做了很多其它的测试,稳定性、准确性、兼容性,这三方面都没有问题。提示一下:zstd-jni 1.5.0 以下的版本有不少的 bug,建议升级到 1.5 以上,完全向下兼容。

  1. 引擎算子分析

什么是引擎算子分析?通过对 Spark 引擎进行多视角、多维度深度剖析,提升对引擎的认知,使算力可解释、明确算力瓶颈、挖掘算力潜在优化点。

image-0a01fbdca3754c77ac422f122b23d018.png-imageStyle

通过不同的视角进行深度剖析,在不同的视角下,能发现不一样的问题,找到不同的潜在优化点。本次介绍最重要的 3 个分析视角,分别是执行过程视角、物理算子视角、UDF 函数视角。

**(1)执行过程视角:**将计算划分为十大过程,分析这十大过程的构成、资源开销、时间开销。

**(2)物理算子视角:**物理算子和逻辑算子有着对应关系,一个逻辑算子有多种不同物理实现,在不同的场景下,匹配不同物理算子。物理算子内部实现是否高效,以及是否被正确使用,都对性能有重大影响。

**(3)UDF 函数视角:**对几百个 UDF 函数使用情况进行分析,既包含引擎内置的,也包含用户实现的。

image-42ac1a75c01144bfb9d706864986fff9.png-imageStyle

引擎理解同样也是数据驱动的,拆解引擎需要用到四大数据源:

**(1)QueryPlan:**通过解析 SQL,生成执行计划,从而对算子进行分析.

**(2)StackTrace:**用于分析调用堆栈,生成直方图、火焰图,进行性能分析。

**(3)EventLog:**作业在运行过程中生成的 DAG 图谱以及各种指标,这对引擎理解也有极大的帮助。

**(4)GcLog:**最后是 GcLog,主要用来精准分析内存用量,减少 OOM 发生的概率。

image-36c9035e022e4deba4387b5410db577f.png-imageStyle

接下来看一组数据,以上是对执行过程的分析,我们看看耗时最大的四个过程,有了数据之后,只需要通过进一步下钻分析,就能找到优化方向:

**数据扫描:**占比最大,超过 30%,有点超出预期,说明潜在优化空间是非常大的。

**数据交换:**占比第二,大概 20%,也是非常高的。

**数据聚合:**占比第三,大概 15%。

**UDF 调用:**占比第四,大概 14%。

image-05b18c2bedf4416ab584b51b42f2605f.png-imageStyle

**Aggregate:**整体比较健康

**Join:**SortMergeJoinExec 性能差,但占比 95.3%,可通过 HBO 调参转换BroadcastHashJoinExec。

**Scan:**数据读取和压缩占比低,而数据处理占比 75.94%,后续主要考虑如何提升数据处理的效率(包含 schem 处理,行列转换等)。

image-a10a6a4789da4f9485e72a91f9a564c0.png-imageStyle

(1)首先,Json 处理占了 1/3 还要多,这是非常不健康的,这是重点要去解决的。第一,要优化 JSON 处理性能,第二,我们也得看看为什么有这么多的 JSON 要处理?肯定有哪里不对劲。

(2)其次,平台公共 UDF,整体看起来还算可以。

(3)最后,业务 UDF,可以看到占比也很高,也是需要重点去解决的。

image-c14ebb69de8e4061961d39297aa216cc.png-imageStyle

当我们有了数据、看清了现状,接下来应该如何应对呢?

(1)首先,我们需要去做分析,判断。判断是否合理?是否有优化空间?空间有多大?

(2)其次,需要确保使用方法正确。如果有一辆好赛车,但是不懂驾驶,就很难发挥出应有的性能。

(3)其次,可以看看某些零部件,是否有替代方案。例如 JSON 处理,压缩算法。

(4)最后,如果以上都解决不了,那就只能自己动手去重构某些零部件了,尤其是一些关键零部件。

image-0a18e14544a740af85aeca1051bd455e.png-imageStyle

更多的优化,也还在进行当中。

03数仓白盒化

  1. 数仓架构度量

image-7bcc3e0ac34141ddac6bdf77fa65a9d3.png-imageStyle

讲数仓白盒化之前,我们必须先要弄清楚,好的数仓标准是什么样的?只有搞清楚了数仓架构的量化指标,才能指导我们进行优化:

**完整度:**衡量数据模型建设,是不是足够完整、通用,满足的需求是不是足够广泛。其实就是分析跨层引用多不多?跨层引用过多,数仓模型一定不是完整的。

**复用度:**主要看三个指标(引用系数、重复计算、链路深度)。

**规范性:**这是基础要求,但做好并不容易,尤其是一开始没做好,后续想要捡起来,会非常困难。

  1. 如何减少重复计算

image-b2caf7bf113c43f7a9dbe1caefff442c.png-imageStyle

先来看一个相似算子的示例。图中给出了三个查询,拆解为语法树之后,不难发现,这其中隐藏了非常多的相似代码片段。图上用了四种不同颜色,进行标识,相同的颜色代表此部分计算逻辑是相似的,这些相似片段,通常都会带来数倍资源开销。

image-eebedd6e26f6451985d24c9c712d4759.png-imageStyle

如何识别相似的代码片段呢?

第1步,获取任务列表,我们要获取到所有执行任务的 SQL。

第2步,生成执行计划。

第3步,逐层算子签名,通过后序遍历 AST,逐层向上展开,直到完成整棵数的签名,得到签名集合。

第4步,重复算子识别,通过签名碰撞,去发现重复的算子。

第5步,计算算子代价,代价越高的重复算子,就越应该抽象、沉淀下来。

第6步,合并重复算子,提升处理速度,降低成本。

image-1c880553762c4a23bb3ef2cce49f0b13.png-imageStyle
image-688db3617244480186229dbeb7fd6a76.png-imageStyle

这是我们内部的一组数据,直观的感觉就是重复比例有点大。可以看到聚合的相似算子达到了惊人的 43%,这是非常之高的,连接算子也达到了 23%,最后,还有 4.5% 的 INSERT 算子是相似的,INSERT 是最后输出的模型,这说明了有 4.5% 的模型是相似的。如果说,我们不去自动干预、自动治理,只会越来越恶化。

image-1404b1abe2a341929116456347c16b34.png-imageStyle

当我们识别了相似算子,看清了现状,那么到底有什么价值呢?主要有三个:

**(1)指导治理:**向用户展示当前现状,并给出整改优化建议.

**(2)辅助开发:**主要包含模型选择和优化。

**(3)查询加速:**通过自动物化视图,实现查询加速,这个过程对用户是完全透明的。

  1. 如何降低链路层级

image-7b91a05a48504cc18c8ef8b51bb754a1.png-imageStyle

想要降低链路层级,我们得先了解现状。上图是线上某条生产链路,展示的是任务依赖关系。可以获得一些信息:首先是,链路层级非常深:达到了惊人的 39 层。其次是,跨层依赖非常多:可以明显看出来很多末尾的 ADS 节点,甚至会依赖最源头ODS。这也间接导致了很多问题,例如:数据及时性差、生产成本高、数据质量难以控制。

为什么会出现这种现象?既要满足快速变化的业务需求,又要不断地抽象和沉淀,还要确保不出现质量问题。既要又要还要,通常来说,这三者很难同时兼顾,所以随着时间变化,导致数仓劣化。

image-253fec06e33c4a2cae9055846d4d96ee.png-imageStyle

那么怎么去改变现状呢?第一种解决方案是机器辅助治理。首先,通过构建算子级血缘,还原数据加工逻辑。其次,分析并发现模型中的不合理,生成整改优化建议。最后,由用户根据建议去优化。

image-4626018402724929ba6bcab9fe66fb5b.png-imageStyle

第一种解决方案,只是用于短期治理,并没有从根本解决问题。那么终极方案是什么呢?我认为是逻辑层和物理层解耦,将逻辑模型和物理模型完全分离开来。

**逻辑层:**数据开发者只需要根据业务需求去设计逻辑模型,而完全不用理会底层实现。

**物理层:**物理模型和链路,完全由机器自动化构建,并且根据逻辑模型的变化,不断的迭代和调整,使数仓一直处于贴近最优的状态。

  1. 常规治理自动化

image-8bbd01c9b7c54990865cd521ca723e84.png-imageStyle

首先我们不得不聊一下现状:治理属于一种事后清理工作,善后工作,大家普遍不会太重视,或者说优先级低,没时间处理。做数据治理平台的同学无一例外,都遇到了这个问题,就是推不动业务去治理。

那到底应该怎么办呢?**我们的答案是:常规治理自动化!**但是自动化治理,面临的最大挑战就是怎么确保自动的过程中可靠安全?万一删错了数据怎么办?万一导致了故障怎么办?其实并没那么可怕,再难的事情,只要有体系化的保障,就不用害怕,我们给出的方案是五步法自动治理:

(1)制定标准:自动化治理一定要有严格的标准,只有形成了标准,才有可能自动化,这是先决条件。

(2)问题识别:根据标准、根据规则去识别生产待治理的问题。

(3)质量检验:第一道防火墙,通过波动检测、交叉验证等方式阻断部分问题发生。

(4)治理预告:第二道防火墙,对于非常 critical 的治理动作,通过治理预告,让用户帮助阻拦问题。

(5)快速回滚:第三道防火墙,即使出现了问题,也能快速回滚。所有的治理动作,必须是可以回滚的,否则就不能纳入到自动化范围。

04收益分析

image-3318cfad5a9541a58a6cb672cd0a6607.png-imageStyle

数据存储压缩率: 提升 5%,计算资源收益: 提升 16%,**作业运行时长:**和计算资源收益相当,缩短 14%。此外,作业失败率、GC 时间、OOM 等也有不同程度的下降

05未来规划

image-1350d23c55ea41f3a1c6fb54c6d9f6a5.png-imageStyle

未来工作更多的是延续,因为很多工作才刚开始起步,还比较浅。总的来说,有这么几件事:

**数据压缩:**之前主要是替换压缩算法,这个红利已经吃完了。接下来还要再继续提升的话,就需要在动态压缩、编码等方面下功夫。

**数仓架构:**前面我们讲的数仓白盒化,很多工作都才刚开始,特别是在模型设计、模型生产等方面。

**深度范围:**进一步提升引擎白盒化治理深度。

**下代技术:**要想在效率和成本上产生突破,必须要布局下一代技术,跳出我们现有的认知,在技术范式上取得进展。

以上就是本次分享的内容,谢谢大家。

image-3d03b6e4f45949bb859943580ff5e2fb.jpeg-imageStyle

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK