時間過得好快,不知不覺已經來到第二週了,從這週開始會和大家一起閱讀 DataFusion 的原始碼,
從專案的模組架構逐步理解 DataFusion 在程式碼層面如何從解析查詢語法到實際讀取資料的過程。也相信透過這樣的方式能對 DataFusion 有更深入的理解。
閱讀原始碼之前,我們整個 DataFusion 專案大致的結構,可以看到專案中 datafusion
內有非常多的子目錄,這些子目錄其實都是一個個 crate,也可以說是一個獨立的模組。
......
├── datafusion
│ ├── CHANGELOG.md
│ ├── catalog
│ ├── catalog-listing
│ ├── common
│ ├── common-runtime
│ ├── core
│ ├── datasource
│ ├── datasource-avro
│ ├── datasource-csv
│ ├── datasource-json
│ ├── datasource-parquet
│ ├── doc
│ ├── execution
│ ├── expr
│ ├── expr-common
│ ├── ffi
│ ├── functions
......
DataFusion 主要依照功能拆分這些 Crate,這樣的設計有以下三個優點:
為了能有效的管理多個 Crate,DataFusion 使用 Cargo Workspace 來共享 Crate 間相同的引用,避免重複編譯相同的依賴。
# 專案根目錄的 Cargo.toml
[workspace]
members = [
"datafusion/common",
"datafusion/expr",
"datafusion/sql",
"datafusion/optimizer",
"datafusion/physical-expr",
"datafusion/physical-plan",
"datafusion/core",
# ... 還有更多
]
由於 DataFusion 的 Crate 實在太多了,所以我們今天只介紹幾個和主要功能相關的 Crate
datafusion
主要入口位置:datafusion/core/
作用:對外的統一介面,重新匯出所有核心功能
主要功能:
SessionContext
- 查詢的入口關鍵檔案:
src/execution/context.rs
- SessionContext 實作src/dataframe/mod.rs
- DataFrame APIsrc/prelude.rs
- 常用的重新匯出datafusion-common
- 共用基礎設施位置:datafusion/common/
作用:提供各模組共用的基礎型別和工具
主要內容:
DataFusionError
型別ScalarValue
、Column
、DFSchema
為什麼需要 common?
多個 crate 都需要相同的基礎型別,放在 common 避免循環依賴。
datafusion-expr
- 邏輯表達式和計劃位置:datafusion/expr/
作用:定義查詢的邏輯表示(與執行無關)
關鍵特性:
datafusion-sql
- SQL 解析器位置:datafusion/sql/
作用:將 SQL 字串轉換成 LogicalPlan
工作流程:
SQL 字串
↓
DFParser (基於 sqlparser-rs)
↓
AST (抽象語法樹)
↓
SqlToRel
↓
LogicalPlan
datafusion-optimizer
- 查詢優化器位置:datafusion/optimizer/
作用:優化 LogicalPlan,提升查詢性能
datafusion-physical-expr
- 物理表達式位置:datafusion/physical-expr/
作用:可執行的表達式實作,直接操作 Arrow 資料
與 datafusion-expr 的差異:
特性 | datafusion-expr::Expr |
datafusion-physical-expr::PhysicalExpr |
---|---|---|
目的 | 描述邏輯 | 實際執行 |
資料 | 不涉及資料 | 操作 Arrow Arrays |
型別 | Schema-aware | 需要具體型別 |
優化 | 可被優化器重寫 | 針對執行優化 |
datafusion-physical-plan
- 物理執行計劃位置:datafusion/physical-plan/
作用:定義和實作可執行的查詢計劃
理解各個 Crate 之間的依賴關係很重要:
┌─────────────────┐
│ datafusion │ ← 使用者入口
│ (core) │
└────────┬────────┘
│
┌────────────────────┼────────────────────┐
↓ ↓ ↓
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ datafusion- │ │ datafusion- │ │ datafusion- │
│ optimizer │ │ sql │ │ physical- │
│ │ │ │ │ plan │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ ┌──────┴───────┐ │
│ ↓ ↓ │
│ ┌────────────┐ ┌─────────────┐ │
└─────→│ datafusion-│ │ datafusion- │←─ ┘
│ expr │ │ physical- │
│ │ │ expr │
└─────┬──────┘ └──────┬──────┘
│ │
└───────┬───────┘
↓
┌──────────────┐
│ datafusion- │ ← 共用基礎
│ common │
└──────────────┘
依賴層級說明:
datafusion-common
:所有其他 crate 的基礎datafusion-expr
:定義邏輯表示datafusion-sql
, datafusion-optimizer
:處理輸入和優化datafusion-physical-expr
, datafusion-physical-plan
:實際執行datafusion
:組合所有功能