导读
spark 是大数据业内最常用的分布式数据引擎之一,广泛运用于数据清洗、数仓建设、报表分析、机器学习等领域。当前快手数据平台上绝大多数例行作业为 Spark SQL 作业, 每天例行计算数十万个 SQL,处理数据量达到 EB 级别,使用计算资源数百万 CU、年化资源开销超亿元。为了能够降本增效,内部研发了 Blaze 引擎,Blaze 是快手自研的基于 Rust+ 向量化技术开发的一套 Native 执行引擎,执行过程充分利用 Native 代码和 SIMD 指令向量化计算的优势,实现在用户无感知或少感知的情况下给线上 Spark SQL 作业节约平均 30% 的资源开销。目前 Blaze 引擎已经在公司 Spark 引擎上大规模应用,并且 在大数据资源成本优化项目起到了重要的作用。本文会对 Blaze 引擎的技术实现做详细介绍,以及应用案例的分享。
今天的介绍会围绕下面五点展开:
1. Blaze 引擎介绍
2.
Blaze 在快手内部的应用
3.
业界推广应用
4.
社区合作
分享嘉宾|张力 快手 数据引擎架构师
编辑整理|陈振
内容校对|李瑶
出品社区|DataFun
Blaze
引擎介绍
1.
Blaze
引擎是什么
-
Blaze 是快手自研的基于 Rust+向量化技术开发的一套 Native 执行引擎,执行过程充分利用 Native 代码和 SIMD 指令向量化计算的优势,实现在用户无感知或少感知的情况下给线上 Spark SQL 作业节约平均 30% 的资源开销。
-
目前 Blaze 引擎已经在公司 Spark 引擎上大规模应用,并且在大数据资源成本优化项目起到了重要的作用。
-
简单概括,给 Spark 装上 Blaze 引擎,其它不用改,就能大幅提高 SQL 执行效率。
2.
原生 spark
SQL 的架构
-
前端(Spark
Catalyst): 负责 SQL 解析、优化、生成使用火山模型描述的物理执行计划。
-
后端(Spark
Tungsten): 对物理执行计划进行代码生成优化,并以 RDD 的形式提交到 Spark-Core。
-
执行层(Spark
Core): 对 RDD 进行调度、使用分布式资源完成实际计算
。
3. Blaze
引擎是如何工作的
-
前端无改变,对用户透明。
-
后端通过 Spark 插件机制,将 Spark 物理算子翻译成等价的 Native 向量化算子。
-
执行层基于 Datafusion + Arrow 框架实现 Native 向量化算子的高性能计算。还包含一些其他能力,包括重复表达式识别/去重,方式重复表达式的多次计算;算子/表达式的回退,比如用户的 UDF,Native 不支持,会进行回退;内存统一管理;Remote Shuffle 的支持,已经对接了 Celeborn。
4. TPC-DS
测试
在1TB TPC-DS 测试中,Blaze 相比 Spark-3.5 在相同配置下,执行时长下降 50%。
5.
业界 Spark 向量化引擎概览
业界主流的 Spark 向量化引擎有 4 个,分别是 Databricks 主导的 Photon,百度主导的 BMR,Intel、Kylin、Facebook 主导的 Apache Gluten,快手主导的基于 Rust 的 Blaze。
6.
为什么选择 Blaze
-
我们有很多用户群来支持用户使用,Blaze 非常适合小团队来使用。
-
经过大规模线上验证,适用于生产环境 SQL 复杂、配置多变的场景。
-
优秀的 Benchmark 和生产环境性能,大幅提升线上 SQL 作业的执行速度,降低资源销。
-
与多个相关社区机密合作,已支持 celeborn 等三方组件。
02
Blaze
在快手内部的应用
1.
上线规模和优化效果
目前 Blaze 已在快手内部上线约一半的 Spark ETL 作业,上线效果显著。
2.
优化案例
我们在数仓上线的一个逻辑简单,但数据量较大的作业 SQL 作业。上线 Blaze 向量化引擎后,观察到作业运行资源开销平均下降 40%,节约了 200CU/天的计算资源。换算成成本会有几万块的收益。
3.
针对生产环境的深度优化
在理想情况下,我们希望 Spark 在执行的全过程中都能够实现向量化能力。现实情况下是实现全方位的算子/表达式向量化覆盖需要时间和过程。另一方面是业务编写的 Java UDF 函数没办法直接转化为 Native 执行。回退逻辑就会涉及到 Spark 算子和 Native 算子之间的行列互转过程,会很影响执行性能。Blaze 可以讲回退细化到单个表达式,比如一个 Select 查询涉及到 100 个字段,其中有一个字段涉及 UDF 表达式,不能使用 Native 算子执行,那就只对这一个 UDF 计算进行回退,其余列不需要全部都回退,进而减少行列互转带来的开销。
如果一个 SQL 中一个表达式出现了多次,就会尝试将该表达式的计算结果缓存起来,减少重复计算,以此来减少重复计算的开销。
介绍一个快手 ABTest 平台的实战案例,SQL 中包含较多的 UDF 调用和重复计算,业内一般的 Spark 向量化引擎无法有效优化。一般会将所有的 Select 表达式全部回退,
但 Blaze 独有的 UDF 细粒度回退能够只对含有 UDF 的表达式进行回退,减少了不必要的开销。
再次会发现 Select 和 Where 中都用到了同样的 UDF 表达式,使用 Blaze 表达式重复计算合并功能,减少一次 UDF 调用,上线后发现开销是有明显下降的。
在快手内部包含大量使用 get_json_object()函数来解析 JSON 的 SQL 作业,Blaze 依托表达式重复计算合并机制,支持 JSON 解析结果复用,对多次解析同一 JSON 字段的 SQL 带来高额性能提升。
右图 benchmark 结果显示,spark 解析开销和字段数成正比,而且得益于解析结果复用,blaze 解析同一 JSON 多个字段开销基本不变。在 Spark4.0 中新增了 variant 类型,能够显著提升对 json 类型的处理,但是 Blaze 有表达式重负计算合并能力,所以开销比 Spark4.0+variant 性能还要好一些。
以上 SQL 片段来向快手数仓生产作业,SQL 中包含了对两个大 JSON 字段使用 get_json_object()函数解析多次的操作。
Blaze 独有的 UDF 细粒度回退和表达式重复计算合并功能,以低成本进行表达式级别回退,并且减少一次 UDF 调用,使得作业切换到 Blaze 之后开销下降近 60%。
4.
其它面向生产环境的优化特性
Blaze 中完全通过 JNI 复用了 spark 的数据 IO 功能,使得 Blaze 可以完全支持 spark 中可用的存储系统,如 HDFS、s3 等。
Blaze 有完善的内存管理和 Spill 支持,可有效利用 JVM 的堆外内存和堆内内存,小内存配置下也有较好的优化效果,普通作业不需要调整内存配置即可切换到 Blaze 执行。
Blaze 采用定制的 shuffle 数据格式,shuffle 数据量相比 spark 平均下降 30%,显著节约 shuffle 传输带宽。
Blaze 中实现了完整的 RSS 框架,在社区版本已经有了 Apache Celeborn 的实现,后续也会继续增加 Uniffle 的支持。
业界推广应用
竞技世界在使用 Blaze 后在执行时间上有了很可观的提升。
汽车之家也使用了 Blaze,数据格式主要是 ORC,这部分主要是社区在支持,在 Spark3.5.3 上也可以达到 0.46 倍的性能提升。
58 同城也在调研和测试 Blaze 的过程中,线上环境 TPC-DS 测试性能提升 40% 以上,2025Q1 尝试落地部分生产任务。
社区合作
2024Q4 我们和阿里云进行合作共建,完成了 Blaze 对 Celeborn 的支持。
快手内部主要使用 Parquet 存储格式,对 ORC 没有支持。Blaze 开源后,社区用户贡献了对 ORC 文件格式的集成。
社区用户实现了 Paimon Scan 算子,支持了 Blaze 读取 Paimon 表功能。
2025 Roadmap
2025 年主要会对 8 项核心功能进行开发或增强,会支持 Spark4.0 及 ARM 架构的适配,在数据湖方面会对 Hudi 和 Paimon 做重点支持。