鲲鹏平台Gluten+Velox的编译与搭建
发表于 2025/06/20
0
背景介绍
在大数据处理领域,Apache Spark 作为统一的分析引擎,凭借其内存计算、多场景支持(批处理、流处理、机器学习等)以及易用性,已成为企业构建数据平台的核心工具。然而,随着数据量的指数级增长和业务对实时性要求的提升,Spark 在某些复杂查询和高并发场景下逐渐暴露出性能瓶颈。例如,传统基于 JVM 的行式处理模式在序列化开销、CPU 利用率以及内存管理效率上存在局限,导致查询延迟较高,资源消耗较大。
为了解决这一问题,Apache Gluten 与 Meta 开源的 Velox 引擎的结合,成为业界关注的焦点。Gluten 作为 Spark 的扩展插件,通过引入 向量化执行 和 列式内存计算 的理念,将 Spark 的执行逻辑下沉至高性能的本地计算引擎(如 Velox 或 Arrow),从而实现性能的跨越式提升。而 Velox 作为 Meta 为 PrestoDB 和 Spark 等引擎设计的 通用向量化执行框架,其核心优势在于通过列式内存布局、批量处理和底层硬件优化(如 SIMD 指令集加速),显著减少函数调用开销和内存访问延迟。最终可将 Spark 查询速度提升 2-10 倍,内存消耗降低 30% 以上,同时兼容 ORC/Parquet 等主流格式,无需重构数据管道即可实现性能飞跃。
为了在大数据处理领域获取更高的性能,本篇文章详细介绍了 Gluten-Velox 的源码获取、构建、调用,以及问题解决等内容,帮助大家快速应用最新的技术。
环境配置
项目 | 版本说明 |
---|---|
CPU | Kunpeng 920 |
OS | OpenEuler 24.x |
JDK | 8u332+ |
Spark | 3.2.x,3.3.x,3.4.x,3.5.x |
源码获取
通过下面命令获取Gluten代码,并在后面的构建命令中获取Velox代码。
git clone https://github.com/apache/incubator-gluten.git
对于Centos-7、Centos-8、Centos-9、Ubuntu-20.04 和 Ubuntu-22.04系统,可以直接使用官方提供的二进制包,获取地址
源码构建
由于鲲鹏是arm架构,在gluten源码目录下执行以下命令一键构建Gluten+Velox
export CPU_TARGET="aarch64"
./dev/builddeps-veloxbe.sh
在初次构建完成后,如果仅仅修改了gluten的代码,可以执行下面命令跳过velox以及arrow的构建和依赖配置
./dev/buildbundle-veloxbe.sh --enable_ep_cache=ON --build_arrow=OFF --run_setup_script=OFF
此外,也可以分步进行构建,当Gluten/velox部分代码放生改变可以对变化的部分单独进行构建。
# 获取Velox并编译
./dev/builddeps-veloxbe.sh build_velox
# 编译Gluten cpp模块
./dev/builddeps-veloxbe.sh build_gluten_cpp
# 编译Gluten java模块并创建jar包
cd /path/to/gluten
# 对于Spark3.2.x
mvn clean package -Pbackends-velox -Pceleborn -Puniffle -Pspark-3.2 -DskipTests
# 对于Spark3.3.x
mvn clean package -Pbackends-velox -Pceleborn -Puniffle -Pspark-3.3 -DskipTests
# 对于Spark3.4.x
mvn clean package -Pbackends-velox -Pceleborn -Puniffle -Pspark-3.4 -DskipTests
# 对于Spark3.5.x
mvn clean package -Pbackends-velox -Pceleborn -Puniffle -Pspark-3.5 -DskipTests
最后,无论是一键构建还是分布构建,都可以在{pathToGluten}/package/target目录下面查看生成的Jar包
Gluten+velox的使用
# 配置jar包路径,jar包默认在 /path/to/gluten/package/target 生成,根据自己的路径、spark版本进行修改
export gluten_jar=/path/to/gluten/package/target/gluten-velox-bundle-spark3.3_2.12-linux_aarch64-1.4.0.jar
# 根据自己环境修改对应配置项
spark-shell \
--master yarn --deploy-mode client \
--conf spark.plugins=org.apache.gluten.GlutenPlugin \
--conf spark.memory.offHeap.enabled=true \
--conf spark.memory.offHeap.size=20g \
--conf spark.driver.extraClassPath=${gluten_jar} \
--conf spark.executor.extraClassPath=${gluten_jar} \
--conf spark.shuffle.manager=org.apache.spark.shuffle.sort.ColumnarShuffleManager
这里使用一个简单的用例进行测试:
# 生成1到999999的ID及拼接字符串列str1和str2
val largeData = spark.range(1, 1000000).selectExpr("id", "'text_' || id as str1", "'velox_' || id as str2")
# 持久化数据到内存(默认存储级别)
largeData.persist()
# 新增concat列,合并str1和str2并用|分隔
val testDF = largeData.withColumn("concat", concat(col("str1"), lit("|"), col("str2")))
# 打印详细执行计划(逻辑/物理计划及统计信息)
testDF.explain("extended")
# 触发执行并统计行数
testDF.count()
执行结果:
从上图可以发现,执行计划中的算子被替换为gluten以及velox的算子
编译中遇到的问题与解决方案
1、Abseil编译失败
解决方案:从源码构建:
# 克隆仓库
git clone https://github.com/abseil/abseil-cpp.git
cd abseil-cpp
# 切换到特定版本(如 Its_2025_05_12)
git checkout Its_2025_05_12
# 创建构建目录
mkdir build && cd build
# 运行 CMake 配置
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local
# 使用多核加速编译
make -j$(nproc)
# 安装
sudo make install
删除系统自带的absl
rm -rf /usr/include/absl
2.ninja问题
解决方案:
进入velox脚本目录{pathToGluten}/ep/build-velox/src,修改get_velox.sh脚本内呢绒,删除红框内的velox自动更新模块
进入velox编译目录{pathToGluten}/ep/build-velox/build/velox_ep,修改Makefile文件,删除-DTREAT_WARNING_AS_ERRORS选项
3.libgeos问题

# 获取源码
git clone https://github.com/libgeos/geos.git
cd geos
# 创建构建目录
mkdir build && cd build
# 配置编译选项,启用静态库(必须)
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_SHARED_LIBS=OFF
# 编译并安装
make -j$(nproc)
sudo make install
# 验证 libgeos.a 是否生成
ls /usr/local/lib64/libgeos.a
4.time zone问题
解决方案:
手动编译更新time zone
# 下载最新时区数据库
wget https://www.iana.org/time-zones/repository/tzdb-latest.tar.lz
# 1. 用 lzip 解压 .lz 文件 → 生成 .tar 包,输出文件:tzdb-latest.tar
lzip -d tzdb-latest.tar.lz
# 2. 用 tar 解压 .tar 包
tar -xf tzdb-latest.tar
# 编译并安装,指定安装目录
make TOPDIR=/usr/local/tzdata install
# 覆盖系统文件
cp /usr/local/tzdata/usr/share/zoneinfo/* /usr/share/zoneinfo/
# 重新链接时区,示例:设为上海时区
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime