- 大数据
- 数据分析
- 后端
【免费下载链接】datafusion
Apache DataFusion SQL Query Engine
Apache DataFusion 是一个基于 Rust 与 Apache Arrow 内存模型实现的内存查询引擎,整个项目以 Cargo workspace 的形式拆分为数十个独立 crate(如datafusion-common、datafusion-expr、datafusion-optimizer、datafusion-physical-plan等)。对于贡献者而言,快速理解这些 crate 之间"谁依赖谁"是阅读源码、评估改动影响面的关键前提。本文以 docs/source/contributor-guide/architecture/dependency-graph.md 为骨架,结合仓库中的生成脚本与构建配置,系统讲解 DataFusion 工作区依赖图的图例含义、交互式查看方式,以及如何用cargo depgraph+ Graphviz 自动生成并保持其与代码库同步。读完本文,你将能够阅读依赖图定位跨 crate 的耦合关系,也能在本地一键重新生成这张图。
一、什么是 Workspace Dependency Graph
DataFusion 的文档站点(Contributor Guide → Architecture → Workspace Dependency Graph)内嵌了一张描述工作区内部 crate 之间依赖关系的图。它有两条关键约束:
- 仅包含内部依赖:图中只展示 DataFusion 工作区内部 crate 之间的边,诸如
Arrow、tokio、sqlparser这类外部 crate不包含在内; - 忽略传递依赖:为了保持图的可读性,传递依赖(transitive dependencies)被有意忽略,图中只呈现直接的依赖边。
从仓库根目录的 Cargo.toml 可以看到,工作区成员覆盖了datafusion/core、datafusion/sql、datafusion/optimizer、datafusion/physical-plan、datafusion/physical-optimizer、datafusion/physical-expr、datafusion/functions、datafusion/substrait、datafusion/proto、datafusion-cli、benchmarks、test-utils等 40 余个 crate。依赖图正是以这些成员为节点、以它们之间的[dependencies]、[dev-dependencies]、[build-dependencies]声明为边绘制而成。
二、图例:如何读懂四种连线
原文档为依赖图定义了清晰的图例(Legend),每条边的颜色和线型对应一类 Cargo 依赖声明:
| 线型 | 含义 | 对应的 Cargo 声明 |
|---|---|---|
| 黑色实线 | 普通依赖(normal dependency) | [dependencies] |
| 蓝色实线 | 开发依赖(dev-dependency) | [dev-dependencies] |
| 绿色实线 | 构建依赖(build-dependency) | [build-dependencies] |
| 黑色虚线 | 可选依赖(optional dependency) | [dependencies]中标记optional = true,可通过禁用对应 Cargo feature 移除 |
其中虚线(可选依赖)最值得关注:它意味着该条边可以通过关闭某个 feature 被裁掉。例如datafusion/core的 Cargo.toml 中,parquet = ["datafusion-common/parquet", "dep:parquet", "datafusion-datasource-parquet"]、avro = ["datafusion-datasource-avro"]这类 feature 直接决定了对应数据源 crate 是否被拉入依赖树;图上以虚线呈现的边,正是这些"可通过 feature 开关裁剪"的可变依赖。这也是 DataFusion 保持"最小依赖可用"(默认 features 可控)设计理念的直观体现。
需要强调的是:黑色实线/虚线只描述直接依赖。两个 crate 之间即便存在经由第三方 crate 的间接关系,也不会在图中画出多余的边。
三、交互式图的使用方式
文档页面中嵌入的是一张支持交互的 SVG 图(docs/source/_static/data/deps.svg,该文件为构建产物,见下文第四节),而非静态截图。它具备以下交互能力:
- 平移(pan):在图上按下鼠标/触控板拖动,可漫游整个图;
- 缩放(zoom):滚动鼠标滚轮或触控板即可放大/缩小;页面右下角还提供
+/−两个按钮用于按固定倍率缩放; - 搜索:由于 SVG 保留原始文本节点,浏览器内可直接通过查找功能定位特定 crate 名称。
从源码级看,这些交互逻辑由页面内嵌的一段 JavaScript 实现(见 dependency-graph.md):脚本读取 SVG 的viewBox作为初始状态,通过pointerdown/pointermove事件实现抓取式平移,通过wheel事件按exp(delta * 0.0015)系数实现平滑缩放,并将缩放范围钳制在初始尺寸的 5%(initial.width * 0.05)到 20 倍(initial.width * 20)之间,防止过度缩放导致迷失。若 SVG 加载失败,页面会回退显示 "Unable to load dependency graph." 提示,而不是渲染空白。这张图通过{eval-rst}的raw:: html指令从_static/data/deps.svg内嵌进页面,渲染在带边框和浅色背景的容器中,以保证在明暗主题下都可读。
四、依赖图如何自动生成:脚本源码解析
依赖图的唯一官方来源是仓库中的 docs/scripts/generate_dependency_graph.sh,其核心命令可概括为:
cargo depgraph --workspace-only --all-deps --dedup-transitive-deps \ --exclude gen,gen-common \ | dot -Grankdir=TB -Gconcentrate=true -Goverlap=false -Tsvg \ > docs/source/_static/data/deps.svg逐项拆解:
--workspace-only:只绘制工作区成员之间的内部依赖,这正是"仅包含内部 crate"约束的实现来源;--all-deps:同时考虑普通、开发、构建三类依赖(对应图例中的黑、蓝、绿三种颜色);--dedup-transitive-deps:剔除传递依赖,保证图面只有直接依赖边——与文档中"传递依赖被有意忽略"的说明严格对应;--exclude gen,gen-common:排除仅被内部脚本使用的工具 crate。对应 Cargo.toml 中的datafusion/proto-common/gen与datafusion/proto-models/gen,它们由 protobuf 生成、仅服务于 proto 代码生成流程,不属于业务依赖关系;dot参数:-Grankdir=TB让图自上而下(Top-to-Bottom)分层排列;-Gconcentrate=true合并平行边、减少视觉杂乱;-Goverlap=false避免节点重叠;-Tsvg输出 SVG 格式。
脚本还做了三重前置条件检查(generate_dependency_graph.sh):要求环境中存在cargo、cargo-depgraph(缺失时提示cargo install cargo-depgraph)以及 Graphviz 的dot命令,三者缺一即报错退出。输出路径固定为docs/source/_static/data/deps.svg,脚本会自动创建输出目录并最终打印Wrote dependency graph SVG to ...确认成功。
从依赖图工具链的生态背景看,cargo-depgraph是社区维护的、将 Cargo 依赖关系导出为 Graphviz DOT 文本的标准工具,DataFusion 选择它作为生成器,正是看重其对 workspace、feature 与依赖类型(dev/build/optional)的完整表达能力。
五、与文档构建流程的集成
依赖图能够"始终与代码库保持同步",关键在于它被接入了文档构建流程。仓库根目录的 docs/build.sh 执行顺序如下:
set -euo pipefail cd docs scripts/generate_dependency_graph.sh # 第一步:重新生成依赖图 make html # 第二步:构建 HTML 文档也就是说,每次构建文档都会先重新生成deps.svg,再编译 Sphinx 文档。由于set -euo pipefail的存在,一旦生成失败(例如缺少cargo-depgraph),整个文档构建会立即中止,避免产出过期的依赖图。这正是原文档所说的"脚本现已作为docs/build.sh的一部分自动运行"的落地实现。
在文档目录结构上,docs/source/index.rst 将本页注册到 Contributor Guide → Architecture 章节之下,使其成为贡献者文档体系的正式组成部分。
六、理解图中的节点:工作区 crate 一览
要真正读懂图,还需要对节点(crate)的职责有基本认知。以仓库根 Cargo.toml 的members列表为准,DataFusion 工作区 crate 大致可分为几层:
- 核心引擎层:
datafusion/core(对外的主 crate,聚合全部能力)、datafusion/execution(执行上下文与任务调度)、datafusion/physical-plan(物理执行计划)、datafusion/physical-expr(物理表达式求值)、datafusion/physical-optimizer(物理层优化); - 逻辑与优化层:
datafusion/expr、datafusion/expr-common(逻辑表达式)、datafusion/optimizer(逻辑层优化规则); - SQL 层:
datafusion/sql(SQL 解析为逻辑计划的转换,依赖sqlparser); - 函数层:
datafusion/functions、datafusion/functions-aggregate、datafusion/functions-nested、datafusion/functions-window、datafusion/functions-table及其对应的-common包; - 数据源层:
datafusion/datasource及datasource-{arrow,avro,csv,json,parquet}; - 目录与会话层:
datafusion/catalog、datafusion/catalog-listing、datafusion/session; - 互操作与扩展层:
datafusion/proto、datafusion/proto-common、datafusion/proto-models(protobuf 序列化)、datafusion/substrait(Substrait 计划规范)、datafusion/ffi(C ABI 互操作)、datafusion/spark(Spark 兼容层); - 支撑与应用层:
datafusion/common、datafusion/common-runtime、datafusion/macros、datafusion-cli(命令行)、datafusion-examples、test-utils、benchmarks、xtask、datafusion/sqllogictest、datafusion/wasmtest、datafusion/doc。
观察这张图时,一个值得注意的模式是:datafusion/common与datafusion/expr-common这类-commoncrate 承担了被大量下游共享的"基础类型"角色,因此通常是图中入度最高(被依赖最多)的节点;而datafusion/core则是聚合点,出边覆盖绝大多数 crate。从源码结构看,这种"基础包下沉、聚合包上浮"的分层是 DataFusion 避免循环依赖、支持按需裁剪 feature 的工程基础。
七、实战:在本地重新生成依赖图
如果你想在本地复现或更新这张图,可按以下步骤操作(以仓库根目录为工作目录):
安装依赖工具:
cargo(Rust 工具链,仓库要求 MSRV 1.94.0,见 Cargo.toml);cargo-depgraph:执行cargo install cargo-depgraph;- Graphviz:安装后确保
dot命令可用(如 Debian/Ubuntu 的graphviz包)。
运行生成脚本:
bash docs/scripts/generate_dependency_graph.sh脚本会检查上述三个前置命令,随后在工作区根目录执行
cargo depgraph ... | dot ...,最终将 SVG 写入docs/source/_static/data/deps.svg。验证输出:确认终端打印
Wrote dependency graph SVG to docs/source/_static/data/deps.svg,然后用浏览器打开该 SVG 即可查看(对应文档页右上角 "Open SVG" 链接所指向的文件)。(可选)手动定制:若想探索不同视角,可直接改造脚本第 84-94 行的管道命令,例如去掉
--dedup-transitive-deps查看完整传递依赖,或调整--exclude列表改变排除范围。注意这些改动仅用于本地实验,仓库内的正式产物以脚本默认参数为准。
八、维护注意事项
- 不要手动编辑
deps.svg:它是构建产物。任何对[dependencies]、[dev-dependencies]、[build-dependencies]或 feature 声明的修改,都应通过重新运行 docs/scripts/generate_dependency_graph.sh 反映到图上; - 新增大类依赖时留意图例:为 crate 新增依赖后,图中会相应出现黑/蓝/绿实线;若新增的是
optional = true的依赖,则表现为虚线,说明它受 feature 控制、可在裁剪配置中移除; - 保持"内部依赖 + 直接依赖"两个约束:新增外部 crate 或间接依赖不会、也不应出现在图中;图的可读性正建立在这两条约束之上;
- 文档构建已内置同步机制:由于 docs/build.sh 在
make html之前强制执行生成脚本,正常情况下提交代码时无需手动刷新文档;但本地预览文档前,仍建议确认工具链(cargo-depgraph、dot)已安装,否则文档构建会因前置检查失败而中止。
总而言之,Workspace Dependency Graph 是 DataFusion 贡献者理解模块边界、评估依赖耦合与 feature 裁剪影响的高效入口:黑/蓝/绿/虚线四种图例精确映射了 Cargo 的依赖类型,交互式 SVG 支持自由浏览,而generate_dependency_graph.sh与docs/build.sh的流水线则保证了这张图永远与代码库实际状态一致。掌握它,你就能在数秒内建立起对整个 DataFusion 工程结构的全局认知。
- 大数据
- 数据分析
- 后端
【免费下载链接】datafusion
Apache DataFusion SQL Query Engine
相关推荐
Hugo 依赖关系图(dependency graph)完全指南:读懂 `hugo mod graph` 输出的模块网络
Hugo 依赖关系图(dependency graph)完全指南:读懂 hugo mod graph 输出的模块网络 导读 :本文围绕 Hugo 官方术语表中的
开发工具前端CLI如何用dependency-cruiser生成惊艳的依赖关系图
如何用dependency cruiser生成惊艳的依赖关系图 想要快速理解复杂JavaScript项目的架构?dependency cruiser是您的最佳选
开发工具静态分析代码质量读懂 AG Kit 依赖图谱:Workflow → Agent → Skill 依赖关系的生成机制与阅读指南
读懂 AG Kit 依赖图谱:Workflow → Agent → Skill 依赖关系的生成机制与阅读指南 .agents/DEPENDENCY_GRAPH.
人工智能AI 技能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考