项目整体架构
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:Index、IndexParams、IndexType
|
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 |
主入口 crate:Dataset 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.rs → dataset.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.rs、blocking_scanner.rs、index.rs、ffi.rs 等,Java 侧由 Maven(pom.xml)管理构建。
关键设计原则
-
格式稳定性契约:标记为 stable 的格式必须保证向后/向前兼容;unstable 格式可自由变更
-
编码与 I/O 解耦:
EncodingsIo trait 让编码层不依赖具体存储后端
-
RowAddr vs RowId 分离:物理行地址和逻辑行 ID 是不同类型,永不混用
-
CPU 池隔离:
spawn_cpu() 仅接收纯计算任务,禁止 I/O/锁/阻塞,避免死锁
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。