Apache Arrow 持续集成体系全解:Docker 构建、Archery 与 Crossbow 的协作架构与实战
2026/9/23 21:37:45 网站建设 项目流程
  • 数据工程
  • 数据分析
  • 大数据

【免费下载链接】arrow

Apache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing

项目地址:https://gitcode.com/gh_mirrors/arrow12/arrow
点击查看免费下载

Apache Arrow 是一个跨语言的数据交换与内存处理工具箱,其持续集成(CI)体系需要覆盖多种包管理器、编译器、依赖版本、操作系统与硬件架构的组合。本篇技术指南以仓库中 docs/source/developers/continuous_integration 系列文档为主线,系统讲解 Arrow 的 CI 总体架构、基于 Docker 的可复现构建流程、开发者日常工具 Archery 的安装与使用,以及用于打包与集成测试调度的 Crossbow 队列机制。读完本文,你将掌握 Arrow CI 的目录结构、关键配置文件的作用、archery docker的完整命令用法,以及如何用 Crossbow 手动触发一次打包/测试构建。

一、Arrow CI 的总体架构:从文件到两类构建模式

Arrow 的持续集成相当复杂:它必须覆盖不同的包管理器(conda、pip、vcpkg 等)、编译器(GCC、Clang、MSVC)、多种第三方库版本、操作系统(Linux、macOS、Windows)以及其他可能的差异来源。其核心组件与关键文件如下。

1.1 CI 中心配置文件

在仓库根目录下,有三份文件直接定义了 CI 的行为:

  • docker-compose.yml(仓库根目录):定义了一组 Docker 服务,可以通过环境变量或环境变量的默认值来配置。例如文件头部注释给出了用法示例$ ARCH=arm64v8 docker-compose build ubuntu-cpp,表明服务通过环境变量参数化。
  • .env(仓库根目录):定义用于配置docker-compose.yml中各服务的默认值,如ARCH=amd64UBUNTU=20.04DEBIAN=12PYTHON=3.8PANDAS=latestREPO=apache/arrow-dev等。
  • appveyor.yml(仓库根目录):定义在 Appveyor 上运行的工作流。

1.2 CI 相关目录

Arrow 项目中有多个与 CI 直接相关的重要目录:

  • .github/workflows/:存放由 GitHub Actions 运行的工作流,由诸如 PR 提交、PR 合并等事件触发。仓库中实际包含archery.ymlcomment_bot.ymldev.ymldev_pr.ymlcpp.ymlpython.ymljava.ymlr.ymlgo.ymljs.ymlswift.yml等大量按语言区分的流程文件。
  • dev/tasks/:存放通过archery crossbow submit ...触发/提交的扩展任务,通常是 nightly 构建或与发布流程相关的任务。
  • ci/:存放脚本、Dockerfile 及补充文件,例如补丁文件、conda 环境文件、vcpkg triplet 文件等。其中的 ci/scripts 目录包含了cpp_build.shcpp_test.shpython_build.shintegration_dask.sh等大量构建/测试脚本。

1.3 两类构建模式

与其按文件和文件夹来理解,更清晰的方式是把 Arrow CI 分为两大类:

  • action-triggered builds(动作触发构建):由 GitHub 上的特定动作(如 PR 打开、PR 合并)触发的 CI 任务。
  • extended builds(扩展构建):手动触发,其中多数按 nightly 节奏运行。

1.4 服务依赖与 archery 的自动解析

需要注意:docker-compose.yml中定义的部分服务之间存在依赖关系。在本地运行服务时,你必须手动先构建其依赖,或者通过archery docker run ...来运行——后者会自动查找并构建依赖。这一点在docker-compose.ymlx-hierarchy节中体现:Archery 依据该层级声明实现嵌套镜像的自动构建,例如调用一次archery docker run debian-ruby即可替代依次执行docker-compose build debian-cppdebian-c-glibdebian-rubyrun --rm debian-ruby的完整序列。

二、动作触发构建:GitHub Actions 工作流解析

.github/workflows/中的.yml文件是响应特定动作运行的 GitHub Actions 工作流。其中绝大多数是针对具体语言实现(C++、Python、Java、R、Go、JS、Swift、Ruby、C#、MATLAB 等)的流程,仅在影响对应语言代码的变更发生时运行。除语言实现外,值得注意的通用工作流有:

工作流文件作用
archery.yml当 Archery 工具或其运行的任务发生变更时,运行必要的验证检查
comment_bot.yml通过监听 GitHub PR 评论触发特定动作(见下文)
dev.yml任何 PR 有活动或 PR 被合并时运行,负责 lint 检查与可合并性测试
dev_pr.yml任何 PR 打开或更新时运行,检查 PR 标题格式、必要时为对应 GitHub issue 添加 assignee(或添加评论要求用户在标题中带上 issue id),并添加相关 GitHub 标签

2.1 comment_bot:用评论驱动 CI

comment_bot.yml 监听 GitHub PR 评论中的以下字符串并触发相应动作(源码中可见对应的autotunerebase等工作流分支):

  • @github-actions crossbow submit ...:运行指定的 Crossbow 命令;
  • @github-actions autotune:运行一批样式/格式化工具、构建部分文档并提交结果;
  • @github-actions rebase:把 PR rebase 到主分支(源码中对应git rebase upstream/${{ github.event.repository.default_branch }})。

另外,还有两份文件定义了动作触发的构建:appveyor.yml在涉及 Python 或 C++ 的提交上运行。

三、扩展构建:Crossbow 与 dev/tasks

Crossbow 是 Archery 的一个子组件,用于手动触发构建。可运行的 Crossbow 任务都定义在dev/tasks目录中,该目录包含:

  • dev/tasks/tasks.yml(tasks.yml):各类可通过 Crossbow 运行的任务配置;
  • 若干子目录,存放不同的任务模板(使用 Jinja2 语法编写),大致按语言或包管理系统划分。

大多数任务作为 nightly 构建运行,但也可以在 PR 上添加以@github-actions crossbow submit开头、后跟任务名的评论来手动触发。

3.1 任务分组机制

为方便起见,dev/tasks/tasks.yml中的任务按“组(groups)”定义,便于一次性向 Crossbow 提交多个任务。例如源码中的分组定义包括:

  • conan:匹配conan-*
  • conda:匹配conda-*
  • wheel:匹配wheel-*
  • linux:匹配almalinux-*amazon-linux-*centos-*debian-*ubuntu-*
  • packaging:汇总 almalinux、conan、debian、java-jars、matlab、nuget、python-sdist、wheel 等打包类任务;
  • test/cpp/c-glib/java/python/r/ruby/go/vcpkg:按语言划分的测试任务组。

任务定义中包含了:在docker-compose.yml中运行哪个服务、在哪个 CI 服务上运行任务、以哪个模板文件作为任务基础等关键信息。

3.2 Crossbow 覆盖的打包与集成测试范围

arrow/dev/tasks目录的目标是自动化 Arrow 的打包与集成测试流程。打包范围包括:

  • C++ 与 Python 的 conda-forge 包(面向 Linux、macOS、Windows);
  • 面向 Linux、macOS、Windows 的 Python Wheels;
  • 面向多个 Linux 发行版的 C++ 与 GLib 包;
  • Java for Gandiva。

集成测试范围包括:各类 Docker 测试、Pandas、Dask、Turbodbc、HDFS、Spark。

四、Docker 构建:可复现的本地化 CI

Arrow 的大部分 Linux CI 任务通过 Docker 与 docker-compose 与公共 CI 服务解耦。把 CI 配置保持在公共服务端最小化,使得本地可复现成为可能。构建镜像本身定义在 ci/docker 目录下的各*.dockerfile中。

4.1 执行 Docker 构建的多种方式

执行基于 Docker 的构建有多种方式,推荐的方式是使用 Archery 工具。

列出可用镜像:

archery docker images

执行一次构建:

archery docker run conda-python

Archery 底层会依次调用如下 docker-compose 命令(等价序列):

docker-compose pull --ignore-pull-failures conda-cpp docker-compose pull --ignore-pull-failures conda-python docker-compose build conda-cpp docker-compose build conda-python docker-compose run --rm conda-python

注意:由于conda-python依赖conda-cpp,Archery 依据docker-compose.ymlx-hierarchy声明自动补齐了依赖镜像的拉取与构建。

4.2 常用运行选项

只显示要执行的 docker-compose 命令而不实际执行:

archery docker run --dry-run conda-python

禁用镜像拉取(用于已有镜像时加速):

archery docker run --no-cache conda-python

等价于:

docker-compose build --no-cache conda-cpp docker-compose build --no-cache conda-python docker-compose run --rm conda-python

仅对叶子镜像禁用缓存(强制构建依赖的开发版本):

PANDAS=upstream_devel archery docker run --no-leaf-cache conda-python-pandas

该命令构建conda-cpp > conda-python > conda-python-pandas这一镜像分支,其中叶子镜像为conda-python-pandas,并注意它不拉取conda-python-pandas镜像、构建时也不使用缓存。等价序列为:

export PANDAS=upstream_devel docker-compose pull --ignore-pull-failures conda-cpp docker-compose pull --ignore-pull-failures conda-python docker-compose build conda-cpp docker-compose build conda-python docker-compose build --no-cache conda-python-pandas docker-compose run --rm conda-python-pandas

这里PANDAS是一个构建参数(见下文“Docker 构建参数”),其默认值定义在.env文件中。

完全跳过镜像构建(应对缓存失效):

docker-compose 的层缓存机制在某些版本、cache_from构建项与不同后端(docker-py、docker-cli、docker-cli+buildkit)组合下并不可靠,即使重复执行相同构建命令也可能产生不同的层哈希,导致缓存未命中、触发整镜像重建。如果镜像已构建好但缓存工作不正常,可以跳过构建阶段:

# 第一次运行确保镜像已构建 archery docker run conda-python # 如果第二次运行又尝试构建镜像、且相关 dockerfile 引用的文件都没有变化, # 则说明出现了上述缓存未命中问题 archery docker run conda-python # 由于镜像已被第一次命令正确构建,无需重建, # 手动禁用 pull 和 build 阶段以节省时间 archery docker run --no-pull --no-build conda-python

向容器传递环境变量:

容器内使用的大多数构建脚本可通过环境变量配置。使用--env-eCLI 选项传入(与docker rundocker-compose run接口类似):

archery docker run --env CMAKE_BUILD_TYPE=release ubuntu-cpp

C++ 构建可用的环境变量详见 ci/scripts/cpp_build.sh 脚本。

以自定义命令运行镜像:

自定义 docker 命令可作为archery docker run的第二个参数传入。以下示例在容器内启动交互式bash会话,便于交互式调试构建:

archery docker run ubuntu-cpp bash

4.3 Docker 卷缓存

大多数 compose 容器会挂载宿主机的特定目录,以复用ccachemaven制品。这些 docker 卷位于.docker目录中。清理缓存只需删除其中的一个或多个目录(或整个.docker目录)。

4.4 Docker 构建参数

构建期参数被下推到 Dockerfile 中以增强镜像构建的灵活性。这些参数通常被称为 docker build args,但 Arrow 以环境变量的形式传给 docker-compose.yml。构建参数广泛用于:

  • 定义用于缓存的 docker registry;
  • 平台架构;
  • 操作系统及其版本;
  • 定义各种依赖的版本。

参数默认值存放在顶层.env文件中。仓库中的 .env 文件实际定义了如下的默认参数(节选):

参数默认值说明
ARCHamd64架构
REPOapache/arrow-dev拉取/推送镜像的默认仓库
ULIMIT_CORE-1coredump 生成开关(设为 0 可禁用)
ALMALINUX/ALPINE_LINUX/DEBIAN/FEDORA/UBUNTU8/3.16/12/39/20.04各发行版默认版本
CUDA11.2.2CUDA 版本
DOTNET8.0.NET 版本
GO1.21.8Go 版本
JDK11JDK 版本
LLVM14LLVM 版本
MAVEN3.8.7Maven 版本
NODE18Node.js 版本
PYTHON3.8Python 版本
R4.4R 版本
PANDAS/DASK/NUMBA/NUMPY/TURBODBClatest各 Python 依赖默认版本
VCPKG指定 commit SHAvcpkg 依赖版本

4.5 构建脚本设计原则

ci/scripts目录下维护的脚本应保持可参数化、但尽量精简,以清晰封装各自负责的任务,例如:

  • cpp_build.sh:构建 C++ 实现但不运行测试;
  • cpp_test.sh:执行 C++ 测试;
  • python_build.sh:构建 Python 绑定但不运行测试;
  • python_test.sh:执行 Python 测试;
  • docs_build.sh:构建 Sphinx 文档;
  • integration_dask.sh/integration_pandas.sh:执行 dask / pandas 集成测试;
  • install_minio.sh:为多平台安装 minio 服务器;
  • install_conda.sh:为多平台安装 miniconda;
  • install_gcs_testbench.sh:为多平台安装 GCS testbench。

参数化(如 C++ 的 CMake 选项)通过带有合理默认值的环境变量实现,使构建配置保持声明式。以 ci/scripts/cpp_build.sh 为例:脚本开头即通过: ${ARROW_USE_CCACHE:=OFF}: ${BUILD_DOCS_CPP:=OFF}等形式为环境变量设置默认值,并将ARROW_CMAKE_ARGSARROW_GANDIVA_PC_CXX_FLAGS等环境变量转发为 CMake 选项——同一脚本可以在多种配置下被调用而无需修改自身。具体的变量传递示例可参见docker-compose.yml中的 C++ 镜像定义。

4.6 开发视角:层次化镜像设计

docker-compose 配置面向可复用的开发容器,采用层次化镜像设计。例如多个语言绑定依赖 C++ 实现,因此无需在多个 Dockerfile 中重复定义 C++ 环境,而是在构建 GLib、Ruby、R 与 Python 绑定时直接复用完全相同的底层 C++ 镜像。这一设计减少了重复并简化了维护,但也使 docker-compose 配置更复杂。docker-compose.yml文件头部还给出了 coredump 相关的内核参数设置建议(如 Linux 主机上执行sudo sysctl -w kernel.core_pattern=core.%e.%p,以及用ULIMIT_CORE=0禁用 coredump 生成)。

五、Archery:日常开发与 CI 的瑞士军刀

为简化日常开发任务,Arrow 开发了一个用 Python 编写的工具,名为 Archery。其源码位于 dev/archery 目录。

5.1 安装

Archery 要求 Python 3.8 或更高版本。推荐以editable模式(-e标志)安装,这样在拉取 Arrow 仓库后安装会自动更新。克隆 Arrow 仓库后,在顶层目录执行:

$ pip install -e "dev/archery[all]"

Archery 的许多操作依赖 Docker 与 docker-compose,你可能也需要安装它们。

5.2 用法概览

通过--help标志查看用法:

$ archery --help Usage: archery [OPTIONS] COMMAND [ARGS]... Apache Arrow developer utilities. See sub-commands help with `archery <cmd> --help`. Options: --debug Increase logging with debugging output. --pdb Invoke pdb on uncaught exception. -q, --quiet Silence executed commands. --help Show this message and exit. Commands: benchmark Arrow benchmarking. build Initialize an Arrow C++ build crossbow Schedule packaging tasks or nightly builds on CI services. docker Interact with docker-compose based builds. integration Execute protocol and Flight integration tests linking Quick and dirty utilities for checking library linkage. lint Check Arrow source tree for errors numpydoc Lint python docstring with NumpyDoc release Release related commands. trigger-bot

Archery 暴露了相互独立的子命令,每个子命令都有专门的帮助输出,例如:

$ archery docker --help Usage: archery docker [OPTIONS] COMMAND [ARGS]... Interact with docker-compose based builds. Options: --src <arrow_src> Specify Arrow source directory. --help Show this message and exit. Commands: images List the available docker-compose images. push Push the generated docker-compose image. run Execute docker-compose builds.

5.3 从源码看 Archery docker 子命令的实现

Archery docker 子命令的 CLI 实现在 dev/archery/archery/docker/cli.py 中,前文介绍的各选项都可以在源码中找到对应声明:

  • --dry-run/--execute:只打印 docker-compose 命令而不执行;
  • --force-pull/--no-pull:控制是否拉取基础镜像;
  • --force-build/--no-build:控制是否构建镜像;
  • --use-leaf-cache/--no-leaf-cache:控制叶子镜像是否使用缓存。

其对应的测试用例位于 dev/archery/archery/docker/tests/test_docker_cli.py,其中验证了run --no-pull --no-build ubuntu-cpp--no-leaf-cache等选项的组合行为。若需完整了解 Docker 与 Archery 的配合使用,可继续阅读 docker.rst。

六、Crossbow:打包与测试的队列化调度

Crossbow 的目标是自动化 Arrow 的打包与集成测试流程,其任务模板与配置集中在dev/tasks目录。

6.1 架构:Executor、Queue 与 Scheduler

Crossbow 的架构由三部分组成:

Executors(执行器):单个任务运行在公共 CI 服务上,当前包括:

  • Linux:GitHub Actions、Travis CI、Azure Pipelines;
  • macOS:GitHub Actions、Azure Pipelines;
  • Windows:GitHub Actions、Azure Pipelines。

Queue(队列):由于 CI 服务的调度方式限制,任务调度通过一个额外的 git 仓库进行,该仓库充当任务的作业队列。任何人都可以托管一个 queue 仓库(通常命名为<ghuser>/crossbow)。一个 job 就是某个 git 分支上的一个 git commit,其中包含运行请求构建所需的配置文件(如.travis.ymlazure-pipelines.yml,或供 GitHub Actions 使用的crossbow.yml)。

Scheduler(调度器):Crossbow 负责版本生成、任务渲染与提交,任务定义在tasks.yml中。

6.2 安装与准备(以 GitHub 为例)

以下指南以 GitHub 为例,但理论上任何 git 服务器都可以使用。如果你不打算使用现成的 queue 仓库(如 ursacomputing/crossbow),需要先完成前两步,否则直接从第 3 步开始:

  1. 创建 queue 仓库

  2. 为新创建的 queue 仓库启用 Travis CI 与 Azure Pipelines 集成;

  3. 克隆 queue 仓库到 arrow 仓库旁边:默认情况下脚本会在arrow目录旁边查找crossbow克隆,但可以通过命令行参数配置。

    git clone https://github.com/<user>/crossbow crossbow

    重要提示:Crossbow 仅支持基于 GitHub token 的认证。虽然它会覆盖以 ssh 协议提供的仓库 URL,仍建议使用 HTTPS 仓库 URL。

  4. 创建 Personal Access Token,需要repoworkflow权限(不需要其他权限);

  5. 在本地把 token 导出为环境变量:

    export CROSSBOW_GITHUB_TOKEN=<token>

    或作为 CLI 脚本的参数传入:--github-token

  6. 把上述 GitHub token 添加到Travis CI:使用名为CROSSBOW_GITHUB_TOKEN的加密环境变量,可在 Travis CI 的仓库设置页面中配置。同时确认分支构建的 auto cancellation 功能已关闭(通常为默认设置);

  7. 安装 Python(最低支持版本为 3.8):推荐使用 Miniconda;

  8. 安装包含 crossbow 的 archery 工具集:

    $ pip install -e "arrow/dev/archery[crossbow]"
  9. 尝试运行:

    $ archery crossbow --help

6.3 使用流程

Crossbow 脚本执行以下步骤:

  1. 检测当前仓库,支持 fork:例如下面的片段会构建 kszucs 的 fork 而不是上游仓库:

    $ git clone https://github.com/kszucs/arrow $ git clone https://github.com/kszucs/crossbow $ cd arrow/dev/tasks $ archery crossbow submit --help # 显示可用选项 $ archery crossbow submit conda-win conda-linux conda-osx
  2. 获取当前 checkout 分支的 HEAD commit,并基于 setuptools_scm 生成版本号。因此要构建某个特定分支,请在运行脚本前先 checkout:

    $ git checkout ARROW-<ticket number> $ archery crossbow submit --dry-run conda-linux conda-osx

    注意:arrow 分支必须事先推送,因为脚本会克隆选定的分支。

  3. 读取并渲染所需的构建配置,替换其中的参数;

  4. 为每个任务创建一个分支,以 job id 为前缀。例如构建 Linux 上的 conda recipes 时,会创建名为crossbow@build-<id>-conda-linux的新分支;

  5. 将修改后的分支推送到 GitHub 以触发构建,认证使用安装一节中描述的 GitHub OAuth token。

6.4 查询构建状态与下载制品

submit命令会返回 build id(它在 queue 仓库中对应一个分支):

$ archery crossbow status <build id / branch name>

下载构建制品:

$ archery crossbow artifacts <build id / branch name>

6.5 实战示例

submit 命令接受任务名列表和/或任务组名列表来选择要构建的任务。

运行多个构建:

$ archery crossbow submit debian-stretch conda-linux-gcc-py37-r40 Repository: https://github.com/kszucs/arrow@tasks Commit SHA: 810a718836bb3a8cefc053055600bdcc440e6702 Version: 0.9.1.dev48+g810a7188.d20180414 Pushed branches: - debian-stretch - conda-linux-gcc-py37-r40

只渲染而不应用或提交变更(dry-run):

$ archery crossbow submit --dry-run task_name

只运行 conda 包构建与一个 Linux 构建:

$ archery crossbow submit --group conda centos-7

运行 wheel 构建:

$ archery crossbow submit --group wheel

tasks.yml中还有多个任务组,如 docker、integration 和 cpp-python,用于运行基于 docker 的测试。archery crossbow submit支持多个选项与参数,更多内容请查看其帮助页:

$ archery crossbow submit --help

七、CI 全景速查与延伸阅读

综合来看,Arrow 的 CI 体系可以概括为一张速查表:

组件位置作用
GitHub Actions 工作流.github/workflows按 PR/合并等动作触发的语言级与通用校验(lint、标题检查、评论机器人)
Appveyor 工作流appveyor.yml与 Python/C++ 提交相关的 Windows 构建
Docker 服务定义docker-compose.yml参数化定义全部构建/测试镜像及其层次依赖
构建参数默认值.env提供架构、发行版、依赖版本的默认值
构建/测试脚本ci/scripts可参数化的单任务脚本,作为容器内执行入口
Dockerfileci/docker各镜像的具体构建定义
Crossbow 任务配置dev/tasks/tasks.yml定义可调度的打包与测试任务及任务组
任务模板dev/tasks 子目录基于 Jinja2 的各类任务模板(conda、wheel、linux 包等)
Archery 工具源码dev/archery提供 docker、crossbow、lint、benchmark 等子命令

若希望深入某个主题,仓库内提供了完整的原始文档:CI 概览见 overview.rst,Docker 构建细节见 docker.rst,Archery 日常使用见 archery.rst,Crossbow 打包与测试见 crossbow.rst。实际动手时,请以当前仓库中的配置与脚本为准——例如docker-compose.yml中的服务名、.env中的默认版本,都会随项目迭代而变化。

  • 数据工程
  • 数据分析
  • 大数据

【免费下载链接】arrow

Apache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing

项目地址:https://gitcode.com/gh_mirrors/arrow12/arrow
点击查看免费下载

相关推荐

上一篇:GitHub_Trending/rea/react-conf-app:React 项目中的计算机视觉应用
下一篇:让 AI 安全跑 shell 命令:Hermes Agent 的 7 种终端后端 20 分钟上手

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

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

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

立即咨询