写点什么

快手自研 Spark 向量化引擎正式发布,性能提升 200%

作者:快手技术
  • 2024-09-14
    北京
  • 本文字数:3723 字

    阅读完需:约 12 分钟

快手自研Spark向量化引擎正式发布,性能提升200%

导语:Blaze 是快手自研的基于 Rust 语言和 DataFusion 框架开发的 Spark 向量化执行引擎,旨在通过本机矢量化执行技术来加速 Spark SQL 的查询处理。Blaze 在快手内部上线的数仓生产作业也观测到了平均 30%的算力提升,实现了较大的降本增效。本文将深入剖析 blaze 的技术原理、实现细节及在快手实际生产环境中的真实表现。 


一、研究背景

当下,Spark 的重要发展方向之一是通过向量化执行进一步提升性能。向量化执行的思想是将算子的执行粒度从每次处理一行变成每次处理一个行组,以此来避免大量的函数调用。通过对行组内部处理按列进行计算,同时利用编译技术减少分支判断检查以及更多的 SIMD 优化执行计划。


Blaze 是快手自研的基于 Rust 语言和 DataFusion 框架开发的 Spark 向量化执行引擎,旨在通过本机矢量化执行技术来加速 Spark SQL 的查询处理。在性能方面,Blaze 展现出显著的优势:在 TPC-DS 1TB 的测试中,Blaze 相较于 Spark 3.3 版本减少了 60%的计算时间、Spark 3.5 版本减少了 40%的计算时间,并大幅降低了集群资源的消耗;此外,Blaze 在快手内部上线的数仓生产作业也观测到了平均 30%的算力提升,实现了较大幅度的降本增效。


如今,Blaze 已开源,拥抱更广阔的开发者社区。开源版本全面兼容 Spark 3.0~3.5,用户能够轻松集成 Blaze 至现有 Spark 环境中,仅需简单添加 Jar 包,即可解锁 Blaze 带来的极致性能优化,享受前所未有的数据处理速度与资源效率。


Github 地址: https://github.com/kwai/blaze


二、Blaze 的整体架构及核心

Spark on Blaze 架构的整体流向

Spark+Blaze 的架构设计原理如下图:



对比 Spark 原生的执行流程,引入 Blaze Session Extension 组件所带来的作用是显著的,特别是在提升数据处理效率和性能方面。


Spark 原生执行流程主要依赖于 Java 虚拟机(JVM)进行任务的执行,尽管 JVM 在提供跨平台、内存管理等方面有着卓越的表现,但在大数据处理场景下,尤其是涉及大规模数据计算和复杂查询时,JVM 的性能开销可能会成为瓶颈。


Blaze Session Extension 组件的引入,巧妙地解决了这一问题。该组件在 Spark 生成物理执行计划之后介入,通过其翻译逻辑将这一计划转换为等效的、native 向量化引擎可以识别的形式,随后提交到 Executor 端由 native 引擎执行计算,从而实现了数据处理效率的飞跃。



而这一切的背后,离不开 Native 向量化引擎这一核心模块的支持。该引擎由 Rust 语言实现,凭借其卓越的性能、安全性和并发处理能力,成功实现了 Spark 中大多数关键算子的等效替代,包括但不限于 Project、Filter、Sort 等。这些经过优化的算子在执行过程中,通过向量化技术显著提升了计算效率,使得数据处理过程更加流畅、快速。


四大核心组件

Blaze 架构中的核心模块有四个,共同驱动着大数据性能的显著提升。这些模块分别为:

  • Native Engine:基于 Datafusion 框架实现的与 Spark 功能一致的 Native 算子,以及相关内存管理、FFI 交互等功能。

  • ProtoBuf:定义用于 JVM 和 native 之间的算子描述协议,对 Datafusion 执行计划进行序列化和反序列化。

  • JNI Bridge:实现 Spark Extension 和 Native Engine 之间的互相调用。

  • Spark Extension:Spark 插件,实现 Spark 算子到 Native 算子之间的翻译。


具体的执行过程中,遵循以下步骤:

  • 物理执行计划的转换:首先,Spark Extension 将 Spark 生成的物理执行计划转换为对应的 Native Plan;

  • 生成和提交 Native Plan:转换完成后,Native Plan 通过 JNI Bridge 被提交给 Native Engine 进行进一步的处理。

  • Native 执行层:最后,Native Engine 利用其高效的内存管理机制和向量化处理技术,对 Native Plan 进行真正的执行。执行结果通过 JNI Bridge 返回给 Spark,从而完成整个数据处理流程。


三、Blaze 的技术优势:面向生产的深度优化

在跑通 tpch 和 tpcds 测试集并取得预期性能提升后,我们面向线上生产环境进一步做了系列深度优化,包括性能和稳定性等方面工作:


细粒度的 FailBac

我们针对 Spark 执行效率的提升,设计并实现了演进式向量化执行方案。这一方案旨在逐步优化算子与表达式的向量化覆盖,同时解决 Java UDF 无法直接转化为 Native 执行的问题。通过引入细粒度的 FailBack 机制,Blaze 在翻译过程中遇到暂无 Native 实现的算子、单个表达式或 UDF 时,支持算子/单个表达式粒度的回退,能够灵活回退到 Spark 原生执行。此机制首先确定算子/表达式的依赖参数列,利用 Arrow FFI 技术将这些参数列作为行传递给 Spark 进行处理,然后将结果以列的形式回传至 Blaze,从而在 JVM 与 Native 执行之间构建了一座桥梁。


此方案不仅加速了向量化执行的全面部署,还确保了即便在用户 SQL 中有少量 UDF 等不支持的场景,细粒度回退单个表达式开销较小,作业整体依然可以得到优化。


更高效的向量化数据传输格式

在 Spark 中,Shuffle 操作因其复杂的数据流转过程成为性能瓶颈,涉及编码、压缩、网络传输、解压及解码等多个环节。原生 Spark 采用基于行的序列化与压缩方式,而业界向量化数据则倾向于 Arrow 格式传输,但实践中发现 Arrow 与主流轻量压缩算法适配不佳,导致压缩率低下且存在冗余信息。针对此问题,Blaze 定制了优化的数据传输格式,不仅去除了列名、数据类型等冗余数据,还使用了 byte-transpose 列式数据序列化技术,通过重组整型/浮点型数据的字节顺序,显著提升数据压缩效率。这一改进大幅减少了 Shuffle 过程中的数据传输量,并在实际测试与 TPC-DS 基准测试中展现出显著的性能提升与资源消耗降低,有效解决了原有问题并优化了系统整体性能。



线上 2000 多个作业的真实数据,上线后输入数据量小幅上涨的情况下,Shuffle 数据量相比 spark 降近 30%


减少用户成本的多级内容管理策略

面对 Spark 与 Native 执行模式在内存管理上的差异,我们设计了跨堆内堆外的自适应内存管理机制。该机制根据任务的向量化覆盖情况智能调整内存分配,确保资源高效利用。同时,我们构建了堆外内存、堆内内存与磁盘文件之间的多级管理体系,有效防止了内存不足及频繁数据溢写的问题。这些措施不仅保障了向量化引擎上线后任务的稳定运行,无需用户手动调整内存参数,大幅降低了用户操作成本,提升了整体系统的易用性与可靠性。



复杂度更优的聚合算法实现

为深度适配 Spark 的复杂需求,Blaze 在 aggregate、sort、shuffle 等关键算子的实现上并未直接采用 DataFusion 的现成方案,而是进行了定制化开发。以 HashAggregate 为例,当面对大规模 group-by 聚合且内存不足时,Spark 会转而采用基于排序的聚合,这涉及高复杂度的排序与归并过程。而在 Blaze 中,我们采用了基于分桶的归并方式,利用基数排序在 spill 时进行分桶、溢写,并在合并阶段通过 hash 表快速合并,整个流程保持 O(n)的复杂度,显著提升了聚合算子的执行效率与资源利用率。



向量化计算场景的表达式重复计算优化

针对 SQL 执行中算子间常见的重复表达式计算问题,Blaze 借鉴了 Spark 的 Whole-stage codegen 技术,应用了这一项优化策略。该策略能够智能识别并合并包含重复表达式的算子,如下图中的 Project 与 Filter 合并为一个大算子,并在其中对表达式计算结果进行缓存、复用,达到了减少重复计算、提高执行效率的目的。这一优化在应对复杂计算逻辑(如 JSON 解析多个字段、UDF 调用)时尤为显著,能将执行效率提升一倍以上。特别是在内部业务场景中,对于高频调用的重负载 UDF,该优化成功减少了约 40%的计算开销,显著增强了系统的整体性能与响应速度。



四、当前进展及未来规划

当前进展

Blaze 作为一款高性能数据处理引擎,已取得了显著进展,全面支持多项核心功能,展现出强大的技术实力与广泛的应用潜力。具体而言,Blaze 目前已具备以下关键能力:


  • Parquet 向量化读写能力:实现了对 Parquet 格式数据的高效向量化读写,极大地提升了数据处理的速度与效率。

  • 全面算子与表达式支持:覆盖了线上常用的所有算子与表达式,少量不支持的表达式和 UDF 也可以细粒度回退,确保用户能够无缝迁移并享受向量化处理带来的性能提升。

  • Remote Shuffle Service 集成:内部集成了自研的 Remote Shuffle Service,同时我们也在和阿里合作,增加对 Apache Celeborn 的支持,预计 9 月份可以提交到社区。

  • TPC-H/TPC-DS 测试优异表现:在业界权威的 TPC-H/TPC-DS 基准测试中,Blaze 成功通过全部测试场景,并以 TPC-H 平均 3 倍以上、TPC-DS 2.5 倍的性能提升展示了其在复杂查询处理上的卓越能力。



在真实的生产环境中,向量化引擎大规模上线应用,算力平均提升 30%+,成本节约年化数千万元。


未来规划

1. 持续迭代优化,内部线上推全:通过不断收集用户反馈与性能数据,我们将精准定位并修复潜在问题,同时引入更多先进的算法与优化策略,以进一步提升 Blaze 的性能与稳定性。

2. 支持更多引擎或场景,例如数据湖等:为了满足用户日益多样化的数据处理需求,我们将不断拓展 Blaze 的应用场景,支持更多类型的数据处理引擎与场景,如数据湖等。通过加强与业界主流技术的兼容性,我们将为用户提供更加灵活、便捷的数据处理方案,助力用户解锁数据价值,推动业务创新与发展。

3. 加强开源社区运营建设,共建生态繁荣:我们深知开源社区对于技术发展与生态繁荣的重要性。因此,我们将在之后加强 Blaze 开源社区的运营建设,积极构建一个开放、包容、协作的社区环境。当前我们已经与阿里、B 站、携程、联通云等公司达成合作。


如果您对该项目感兴趣,欢迎您为项目点个 star。

项目地址:https://github.com/kwai/blaze


本文作者:王磊

用户头像

快手技术

关注

还未添加个人签名 2024-05-15 加入

快手官方技术号,即时播报快手技术实践的最新动态 关注微信公众号「快手技术」

评论

发布
暂无评论
快手自研Spark向量化引擎正式发布,性能提升200%_spark_快手技术_InfoQ写作社区