(1)lance 的架构与模块划分

项目整体架构

Lance 是一个面向 ML 和 LLM 的列式数据格式(v11.0.0-beta.7,Rust 2024 edition,Rust 1.91.0),定位为 Parquet 的替代品,核心优势在于随机访问速度、自动版本化和向量搜索。整个仓库采用 Rust 核心 + Python/Java 薄绑定 的架构模式。

顶层目录如下:

目录 角色
rust/ Rust 核心引擎(Cargo workspace,含 25 个子 crate)
python/ Python 绑定(maturin 构建,Rust FFI)
java/ Java 绑定(JNI + Maven)
protos/ Protobuf 序列化 schema(文件格式、索引、事务等)
benchmarks/ 性能基准测试(SIFT、BigANN、TPC-H 等数据集)
docs/ 文档站点(MkDocs)
ci/ CI 发布和测试脚本
memtest/ 内存泄漏检测工具
notebooks/ Jupyter 快速入门示例

Rust 核心引擎 — 分层模块体系

Rust workspace 包含 25 个子 crate,从下到上可划分为 6 个层级:

第一层:基础类型与工具

Crate 核心职责
lance-core 最底层基石:统一错误类型 LanceError、系统列定义(_rowid/_rowaddr 等)、数据类型扩展、缓存工具、内存深拷贝
lance-arrow Arrow 扩展层DataTypeExt/RecordBatchExt/SchemaExt trait,列投影、批次合并、bfloat16 支持、IPC/JSON 序列化、零拷贝 buffer 操作
lance-derive 派生宏工具
lance-test-macros / lance-testing 测试基础设施(数据生成、profiler、进度回调)
lance-datagen 测试数据生成器

第二层:编码与存储

Crate 核心职责
lance-encoding 列编码引擎:Encoder/Decoder/Compression 三层架构,FSST、bit-packing 等压缩算法,EncodingsIo trait 解耦 I/O 与编码
compression/bitpacking 变长整数 bit-packing 编码
compression/fsst 高频字符串表(FSST)压缩
lance-linalg 线性代数层:L2/余弦/点积距离计算、SIMD 优化(AVX2/NEON)、dist-table 构建
lance-io I/O 抽象层:本地文件系统、对象存储(S3/GCS)、Linux io_uring、调度器(spawn_cpu CPU 池)、溢写、stream 支持
lance-file Lance 文件格式:单个 .lance 文件的 reader/writer,兼容旧版(compatibility_tests

第三层:索引系统

Crate 核心职责
lance-index-core 索引核心 trait:IndexIndexParamsIndexType
lance-index 完整索引实现:向量索引(IVF-Flat/PQ/SQ/RQ/HNSW)、标量索引(BTree/Bitmap/ZoneMap/BloomFilter/Inverted/NGram/RTree/FM)、全文搜索、索引优化/合并、prefilter、mem_wal
lance-tokenizer 文本分词引擎:jieba(中文)、lindera(日文)、ICU(通用)、code tokenizer

第四层:表与事务

Crate 核心职责
lance-table 表级抽象:Manifest(表元数据)、事务提交(transaction.proto)、行ID管理(rowids.proto)、系统索引、feature flags
lance-select 行选择引擎:RowAddrMask、掩码合并、索引表达式求值

第五层:数据查询

Crate 核心职责
lance-datafusion DataFusion 集成:SQL 规划、表达式、聚合、投影、UDF、Substrait、spill 处理
lance-geo 地理空间:bbox 计算、geoarrow 集成、UDF

第六层:命名空间与入口

Crate 核心职责
lance-namespace Namespace trait 定义与统一错误码
lance-namespace-impls Namespace 实现:本地目录、REST 适配器
lance-namespace-datafusion Namespace + DataFusion 集成(SQL 创建/查询表)
lance 主入口 crateDataset API、open_dataset、blob 存储、session、datafusion/io/index 模块重导出
lance-tools 工具集

依赖关系示意(自下而上)

lance (入口)
  ├── lance-index ──→ lance-index-core
  ├── lance-datafusion ──→ lance-select
  ├── lance-table ──→ lance-file ──→ lance-encoding
  ├── lance-io
  ├── lance-linalg
  ├── lance-core
  └── lance-arrow

Protobuf 层(protos/

文件级序列化协议,定义了所有持久化数据的二进制格式:

.proto 文件 用途
file.proto / file2.proto 单个 Lance 文件的格式定义
encodings_v2_0.proto / encodings_v2_1.proto 列编码格式(含版本号演进)
table.proto 表 Manifest(schema、fragment 列表)
transaction.proto 事务提交记录
index.proto / index_old.proto 索引元数据格式
filtered_read.proto 过滤读取格式
ann.proto 近似最近邻搜索结果
rowids.proto / table_identifier.proto 行ID 与表标识

Python 与 Java 绑定

两个绑定层均遵循 薄包装 原则:验证和核心逻辑集中在 Rust,绑定层只负责类型转换和 FFI 调用。

Python(python/:通过 maturin 构建,src/ 目录下是 Rust FFI(lib.rsdataset.rs / scanner.rs / fragment.rs 等),python/lance/ 目录下是纯 Python 模块(dataset.py / query.py / optimize.py 等 26 个模块,tests/ 下约 40 个测试文件)。

Java(java/:通过 lance-jni(Rust JNI crate)暴露接口,模块包括 blocking_dataset.rsblocking_scanner.rsindex.rsffi.rs 等,Java 侧由 Maven(pom.xml)管理构建。


关键设计原则

  1. 格式稳定性契约:标记为 stable 的格式必须保证向后/向前兼容;unstable 格式可自由变更
  2. 编码与 I/O 解耦EncodingsIo trait 让编码层不依赖具体存储后端
  3. RowAddr vs RowId 分离:物理行地址和逻辑行 ID 是不同类型,永不混用
  4. CPU 池隔离spawn_cpu() 仅接收纯计算任务,禁止 I/O/锁/阻塞,避免死锁
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容