Apache Arrow 基准测试构建环境全解:conbench_envs 与 @ursabot 钩子机制实战
2026/9/13 17:51:26 网站建设 项目流程

Apache Arrow 基准测试构建环境全解:conbench_envs 与 @ursabot 钩子机制实战

【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow

Apache Arrow 作为通用列式内存格式与多语言工具箱,其性能演进高度依赖一套稳定、可复现的基准测试(benchmark)体系。本文聚焦仓库中dev/conbench_envs目录下的 benchmarks.env 与 hooks.sh 两份核心文件,完整讲解它们如何支撑@ursabot please benchmarkPR 评论触发的自动化基准构建:包括环境变量全量解析、钩子函数与 CI 脚本的调用关系、baseline/contender 对比机制,以及一条从零搭建 Arrow C++/Python/R/Java/JavaScript 基准环境的 14 步实战流程。读完本文,你将能够理解 Arrow 官方基准基础设施的工作原理,并能在自己的仓库中复用这套机制来评估不同构建选项、依赖版本对性能的影响。

一、dev/conbench_envs目录的两大核心资产

dev/conbench_envs/README.md 开宗明义:该目录包含两个文件,分别解决「构建与运行环境怎么配」和「基准构建流程怎么挂钩」两个问题。

1.benchmarks.env:基准构建的运行环境变量清单

benchmarks.env 是一个纯环境变量文件,用于配置 Arrow C++/Python/R/Java/JavaScript 的构建参数以及运行基准测试时的环境。它通过set -a/source的方式被载入 shell 环境(见后文set_arrow_build_and_run_env_vars钩子)。

环境变量取值含义
CMAKE_BUILD_TYPEreleaseCMake 构建类型,基准必须使用 release 优化
ARROW_BUILD_TESTSOFF关闭单元测试编译,加速构建
ARROW_BUILD_BENCHMARKSON开启 Arrow C++ 基准(benchmark)目标编译
ARROW_BUILD_BENCHMARKS_REFERENCEOFF关闭参考实现基准(避免与主基准混淆)
ARROW_BUILD_TYPEreleaseArrow 顶层构建类型,与 CMake 构建类型对应
ARROW_DEPENDENCY_SOURCEAUTO第三方依赖来源自动探测(系统/捆绑/conda)
ARROW_DATASETON启用 Dataset 组件(基准数据读取需要)
ARROW_DEFAULT_MEMORY_POOLmimalloc默认内存池使用 mimalloc
ARROW_FLIGHTOFF关闭 Flight RPC 组件
ARROW_GANDIVAOFF关闭 Gandiva 表达式引擎
ARROW_HDFSON启用 HDFS 文件系统支持
ARROW_HOME$CONDA_PREFIXArrow 安装前缀指向 conda 环境
ARROW_INSTALL_NAME_RPATHONmacOS 上写入安装名 RPATH
ARROW_JEMALLOCOFF关闭 jemalloc 内存池(与 mimalloc 二选一)
ARROW_MIMALLOCON启用 mimalloc 内存池
ARROW_ORCON启用 ORC 文件格式支持
ARROW_PARQUETON启用 Parquet 文件格式支持
ARROW_S3ON启用 S3 文件系统支持
ARROW_USE_CCACHEON使用 ccache 加速重复构建
ARROW_WITH_BROTLION启用 Brotli 压缩编解码
ARROW_WITH_BZ2ON启用 Bzip2 压缩编解码
ARROW_WITH_LZ4ON启用 LZ4 压缩编解码
ARROW_WITH_SNAPPYON启用 Snappy 压缩编解码
ARROW_WITH_ZLIBON启用 zlib 压缩编解码
ARROW_WITH_ZSTDON启用 Zstandard 压缩编解码
CMAKE_VERBOSE_MAKEFILEON输出完整编译命令行,便于排查构建问题
GTest_SOURCEBUNDLEDGTest 使用捆绑源码编译
ORC_SOURCEBUNDLEDORC 使用捆绑源码编译
PARQUET_BUILD_EXAMPLESON编译 Parquet 示例程序
PARQUET_BUILD_EXECUTABLESON编译 Parquet 命令行工具
PYTHONpythonPython 解释器名称
LD_LIBRARY_PATH$CONDA_PREFIX/lib:$LD_LIBRARY_PATH运行时动态库搜索路径指向 conda 前缀

值得注意的组合语义:该配置刻意选择了ARROW_DEFAULT_MEMORY_POOL=mimalloc并关闭 jemalloc、开启全部主流压缩编解码、开启 Parquet/ORC/Dataset/S3/HDFS 等大组件、同时关闭 Flight 与 Gandiva,构成一套「贴近真实分析负载且组件齐全」的基准基线。

2.hooks.sh:可被外部基准构建调用的钩子函数集合

hooks.sh 是一份bash脚本,末尾的"$@"使其支持以source dev/conbench_envs/hooks.sh <函数名>的形式按名调用内部函数。脚本以set -ex开头——任何命令失败立即退出并打印执行轨迹,保证基准构建在出错时能第一时间暴露问题。

脚本定义了以下钩子函数:

钩子函数作用
create_conda_env_for_benchmark_build用 conda-forge 创建名为${BENCHMARKABLE_TYPE}的 conda 环境,安装 ci/conda_env_cpp.txt、ci/conda_env_python.txt、ci/conda_env_unix.txt 中的依赖,外加compilerspython=${PYTHON_VERSION}pandasr
activate_conda_env_for_benchmark_build执行conda init bash并激活上述环境
install_arrow_python_dependencies通过 pip 安装 python/requirements-build.txt 与 python/requirements-test.txt
set_arrow_build_and_run_env_varsset -a方式 source benchmarks.env,将全部变量导出到环境
build_arrow_cpp/tmp/arrow-cpp-$(uuidgen)目录调用 ci/scripts/cpp_build.sh 编译并安装 Arrow C++
build_arrow_python调用 ci/scripts/python_build.sh 构建 Arrow Python 绑定
build_arrow_r追加 ci/etc/rprofile 到 R 的 Rprofile,必要时为 R 的 Makeconf 补写 C++20 配置(conda-forge 的 R 可能缺少CXX20项,而 Arrow 要求 C++20),再执行 ci/scripts/r_deps.sh 安装 R 依赖并R CMD INSTALL安装 R 包
build_arrow_java调用ci/scripts/java_build.sh构建 Arrow Java
install_archery以可编辑模式安装 dev/archery(Arrow 开发工具链,C++ 基准运行依赖)
install_java_script_project_dependenciesjs目录执行yarn安装 JavaScript 依赖
create_conda_env_with_arrow_python组合钩子:依次执行创建环境、激活环境、安装 Python 依赖、设置环境变量、构建 C++、构建 Python 六步

其中create_conda_env_with_arrow_python是「一条命令完成 Arrow Python 基准环境」的总入口,README 第 6 步正是使用它。

二、钩子机制为什么必须放在 Arrow 仓库内

README 专门用一节解释了hooks.sh存在的必要性,其核心逻辑是「版本随提交走」:

  • @ursabot基准构建本身维护在 Ursa 的私有仓库中,但构建过程需要根据被基准的某个 Arrow commit来创建 conda 环境、编译 Arrow C++/Python/R/Java/JavaScript。
  • 如果将钩子定义放在外部,那么当 Arrow 仓库中安装依赖的脚本(如 ci/conda_env_cpp.txt)或构建脚本(如 ci/scripts/cpp_build.sh)发生重命名、移动或增删时,外部钩子会与目标 commit 的脚本失配。
  • 把钩子定义在 Arrow 仓库内,基准构建针对某个 commit 执行时,使用的就是该 commit 自带版本的钩子与脚本,天然保证兼容。

这使 Arrow 贡献者可以通过修改hooks.shbenchmarks.env来评估不同构建选项、依赖版本对性能的影响——这是该机制最核心的用途。

三、@ursabot please benchmark:baseline 与 contender 对比工作流

README 给出了通过 PR 评论触发基准的完整闭环:

  1. 创建apache/arrowPR;
  2. 在 dev/conbench_envs/benchmarks.env 中更新或新增环境变量;
  3. 在 PR 下评论@ursabot please benchmark
  4. 基准构建完成后,结果通过 PR 评论中的 compare/runs 链接查看,其中:
    • baseline= PR 基础分支(base)HEAD commit,使用未改动的benchmarks.env
    • contender= PR 分支 HEAD commit,使用被覆盖(改动过)的benchmarks.env

这种「同 commit 双份环境变量」的设计,使性能对比严格隔离了代码差异与配置差异:baseline 与 contender 的差异仅在于benchmarks.env的改动,从而可以精准归因性能变化来自哪个构建选项或依赖版本。

四、在自有仓库复用这两份文件的前提

README 明确表示其他仓库和服务欢迎复用benchmarks.envhooks.sh,但必须遵守三条约束:

  1. 不得移除或重命名现有钩子;
  2. 现有钩子的函数定义只能在 Arrow commit 中构建脚本或依赖文件发生重命名、移动、新增时更新;
  3. 函数定义更新后,必须通过@ursabot please benchmark评论实际运行一次基准构建,确认更新没有破坏构建。

这套约定保证了钩子 API 的向后兼容性,避免外部依赖方因钩子签名悄然变化而静默失败。

五、从零搭建基准环境的 14 步实战(Ubuntu)

以下按 README 原始步骤完整复现,并结合仓库脚本补充必要说明。所有命令在 Ubuntu 上以 root(sudo su)执行。

步骤 1:安装 Arrow 系统依赖

sudo su apt-get update -y -q && \ apt-get install -y -q --no-install-recommends \ autoconf \ ca-certificates \ ccache \ cmake \ g++ \ gcc \ gdb \ git \ libbenchmark-dev \ libboost-filesystem-dev \ libboost-regex-dev \ libboost-system-dev \ libbrotli-dev \ libbz2-dev \ libgflags-dev \ libcurl4-openssl-dev \ libgoogle-glog-dev \ liblz4-dev \ libprotobuf-dev \ libprotoc-dev \ libre2-dev \ libsnappy-dev \ libssl-dev \ libthrift-dev \ libutf8proc-dev \ libzstd-dev \ make \ ninja-build \ pkg-config \ protobuf-compiler \ rapidjson-dev \ tzdata \ wget && \ apt-get clean && \ rm -rf /var/lib/apt/lists* apt-get update -y -q && \ apt-get install -y -q \ python3 \ python3-pip \ python3-dev && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*

此清单覆盖了 Arrow C++ 编译所需的压缩库(brotli/bz2/lz4/snappy/zstd)、序列化库(protobuf/thrift)、正则引擎(re2)、性能分析基础(libbenchmark-dev)、构建工具(cmake/ninja/pkg-config)等。与 ci/conda_env_cpp.txt 中的 conda 依赖清单(含benchmark>=1.6.0,!=1.8.4,<1.9.5orc<2.1.0xsimd>=14.2等)互为补充:前者面向 conda 环境,此处面向系统 apt 环境。

步骤 2:安装 Java 依赖并校验版本

sudo su apt-get install openjdk-11-jdk apt-get install maven

校验最低版本:

# java -version openjdk version "11.0.22" 2024-01-16 .. # javac -version javac 11.0.22 ... # mvn -version Apache Maven 3.6.3 ...

步骤 3:安装 JavaScript 依赖并校验版本

sudo apt update sudo apt -y upgrade sudo apt update sudo apt -y install curl dirmngr apt-transport-https lsb-release ca-certificates curl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash - sudo apt-get install -y nodejs sudo apt -y install yarn sudo apt -y install gcc g++ make

校验最低版本:

# node --version v14.17.2 ... # yarn --version 1.22.5 ...

(注:以上版本号是 README 编写时的示例基线;当前仓库对 Node.js 的最低要求以 ci/conda_env_cpp.txt 中的nodejs>=16为准。)

步骤 4:安装 Miniconda

sudo apt install curl curl -LO https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh sudo bash Miniconda3-latest-Linux-x86_64.sh

步骤 5:设置基准构建环境变量

export ARROW_REPO=https://github.com/apache/arrow.git export BENCHMARKABLE=e6e9e6ea52b7a8f2682ffc4160168c936ca1d3e6 export BENCHMARKABLE_TYPE=arrow-commit export PYTHON_VERSION=3.8 export CONBENCH_EMAIL=... export CONBENCH_URL="https://conbench.ursa.dev" export CONBENCH_PASSWORD=... export MACHINE=...

其中BENCHMARKABLE是待基准的 Arrow commit SHA,BENCHMARKABLE_TYPE同时用作 conda 环境名,PYTHON_VERSION传给create_conda_env_for_benchmark_build钩子(该钩子用python="${PYTHON_VERSION}"创建环境),CONBENCH_*MACHINE用于后续向 conbench 服务端提交结果。

步骤 6:用create_conda_env_with_arrow_python钩子构建 Arrow C++ 与 Python

git clone "${ARROW_REPO}" pushd arrow git fetch -v --prune -- origin "${BENCHMARKABLE}" git checkout -f "${BENCHMARKABLE}" source dev/conbench_envs/hooks.sh create_conda_env_with_arrow_python popd

这条命令内部依次完成:基于 ci/conda_env_cpp.txt、ci/conda_env_python.txt、ci/conda_env_unix.txt 创建 conda 环境 → 激活环境 → 安装 Python 构建/测试依赖 → 导出 benchmarks.env 全部变量 → 调用 ci/scripts/cpp_build.sh 编译 C++ → 调用 ci/scripts/python_build.sh 构建 Python。cpp_build.sh会把benchmarks.env中的ARROW_*变量逐项映射为 CMake 参数(例如ARROW_BUILD_BENCHMARKS=ON-DARROW_BUILD_BENCHMARKS=ON),python_build.sh则据此导出PYARROW_WITH_*系列变量决定 Python 绑定编译哪些组件。

步骤 7:安装 conbench CLI

git clone https://github.com/ursacomputing/conbench.git pushd conbench pip install -r requirements-cli.txt pip install -U PyYAML python setup.py install popd

步骤 8:准备 benchmarks 基准仓库

git clone https://github.com/ursacomputing/benchmarks.git pushd benchmarks python setup.py develop popd

步骤 9:配置 conbench 凭据

pushd benchmarks touch .conbench echo "url: $CONBENCH_URL" >> .conbench echo "email: $CONBENCH_EMAIL" >> .conbench echo "password: $CONBENCH_PASSWORD" >> .conbench echo "host_name: $MACHINE" >> .conbench popd

步骤 10:运行 Python 基准

cd benchmarks conbench file-read ALL --iterations=3 --all=true --drop-caches=true

--drop-caches=true在每次迭代前清空操作系统文件缓存,避免缓存命中造成性能虚高,是保证结果可复现的关键参数。

步骤 11:安装 archery 并运行 C++ 基准

pushd arrow source dev/conbench_envs/hooks.sh install_archery popd cd benchmarks conbench cpp-micro --iterations=1

install_archery以可编辑模式安装 dev/archery(pip install -e dev/archery),其为 C++ 微基准的运行提供配套工具链。

步骤 12:构建 Arrow R 并运行 R 基准

pushd arrow source dev/conbench_envs/hooks.sh build_arrow_r popd R -e "remotes::install_github('ursacomputing/arrowbench')" cd benchmarks conbench dataframe-to-table ALL --iterations=3 --drop-caches=true --language=R

build_arrow_r钩子内部会调用 ci/scripts/r_deps.sh 安装 R 包依赖。针对 conda-forge 的 R 可能缺失CXX20配置的问题,该钩子会在 R 的Makeconf中补写CXX20 = g++CXX20FLAGS = -g -O2 $(LTO)CXX20STD = -std=gnu++20等条目,以满足 Arrow 的 C++20 编译要求。

步骤 13:构建 Arrow Java 并运行 Java 基准

pushd arrow source dev/conbench_envs/hooks.sh build_arrow_java source dev/conbench_envs/hooks.sh install_archery popd cd benchmarks conbench java-micro --iterations=1

步骤 14:安装 JavaScript 依赖并运行 JS 基准

pushd arrow source dev/conbench_envs/hooks.sh install_java_script_project_dependencies popd cd benchmarks conbench js-micro

install_java_script_project_dependencies会在js目录执行yarn拉取全部 JavaScript 依赖,随后conbench js-micro直接运行 JS 微基准。

六、钩子函数的内部调用链一览

综合 hooks.sh 与ci目录脚本,可以梳理出完整的调用关系:

create_conda_env_with_arrow_python ├── create_conda_env_for_benchmark_build │ └── conda create --file ci/conda_env_{cpp,python,unix}.txt ... ├── activate_conda_env_for_benchmark_build ├── install_arrow_python_dependencies │ └── pip install -r python/requirements-build.txt -r python/requirements-test.txt ├── set_arrow_build_and_run_env_vars │ └── source dev/conbench_envs/benchmarks.env ├── build_arrow_cpp │ └── ci/scripts/cpp_build.sh <repo> /tmp/arrow-cpp-$(uuidgen) └── build_arrow_python └── ci/scripts/python_build.sh <repo> /tmp/arrow

单语言钩子(build_arrow_rbuild_arrow_javainstall_archeryinstall_java_script_project_dependencies)则分别复用 ci/scripts/r_deps.sh、ci/scripts/java_build.sh、dev/archery 的 pip 安装入口与js/yarn入口。

七、复用这套机制时的注意事项

  • 环境前提:完整流程基于 Ubuntu + apt + Miniconda,且步骤 1~5 需要 root 权限;若在 conda 环境内构建,依赖应优先取自 ci/conda_env_cpp.txt 等清单,避免 apt 与 conda 两套依赖互相污染。
  • 版本随 commit 走:务必在 checkout 到目标 commit 之后、执行钩子之前使用该 commit 自带的hooks.shbenchmarks.env,这正是钩子机制设计的初衷。
  • 构建目录隔离build_arrow_cpp每次使用uuidgen生成唯一构建目录,避免并发或重复构建相互覆盖;ci/scripts/cpp_build.sh 构建完成后还会删除*.o以节省磁盘。
  • 性能对比语义:通过 PR 评论触发时,baseline 与 contender 的唯一变量就是benchmarks.env的改动,因此修改任何ARROW_*构建选项或依赖版本后,都应回归一次基准构建以确认钩子与脚本的兼容性。

结语

dev/conbench_envs是 Apache Arrow 性能工程基础设施的「可移植单元」:benchmarks.env 以声明式方式固化了一套贴近真实分析负载的构建配置,hooks.sh 以「版本随 commit 走」的钩子模式保证了外部基准构建与任意历史 commit 的脚本兼容。无论是 Arrow 贡献者评估构建选项对性能的影响,还是其他仓库借鉴这套基准 CI 体系,本文的 14 步流程与源码级调用链分析都可以作为直接落地的操作手册。

【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询