探秘新一代向量存储格式Lance-format (五) Lance 文件格式详解

第5章:Lance 文件格式详解

概述

Lance 文件格式是整个项目的核心机制。本章讨论 Lance 文件结构、Fragment 组织、Manifest 元数据管理。

Lance 文件体架构

Lance 文件的逻辑结构如下:

erlang 复制代码
页头 0
数据块(编码)
页头 1
数据块(编码)
更多页面...
全局元数据
元数据偏移(8字节)

文件读取流程

文件读取器需要:

  1. 从文件末尾读取元数据偏移量
  2. 根据偏移量读取全局元数据
  3. 解析所有页面的元数据
  4. 根据需要读取特定的列数据

文件读取基本流程:

open(path) -> read_metadata_offset() -> read_global_metadata() -> parse_page_metadata() -> ready for queries

FileReader 接口

FileReader 提供的主要方法:

  • open(path, options): 打开文件
  • read_column(name, row_range): 读取列数据
  • read_batch(): 读取一个批次
  • statistics(): 获取统计信息

Fragment 组织

什么是 Fragment?

Fragment 是 Lance 数据的逻辑分片单位。一个 Fragment 包含:

  • ID:唯一标识
  • 数据文件列表:存储实际数据
  • 删除文件:记录已删除行
  • 行计数:总行数
  • 字节大小:占用空间

Fragment 的结构

每个 Fragment 可以包含多个数据文件,每个文件可以存储不同的列。

Fragment 的优势:

  1. 支持增量更新(添加新 Fragment)
  2. 支持删除操作(通过删除文件标记)
  3. 支持版本演化(添加新列时不需重写旧 Fragment)
  4. 便于并行读取

Fragment 版本演化

当添加新列时:

  1. 新 Fragment 直接包含新列
  2. 旧 Fragment 标记为"需要补全"
  3. 查询时自动补全缺失列的默认值

Manifest 元数据

Manifest 是什么

Manifest 是数据集的完整元数据快照,记录:

  • 版本号:当前版本
  • 时间戳:创建和更新时间
  • Schema:表的列定义
  • Fragment 列表:所有数据分片
  • 统计信息:行数、大小等
  • 索引信息:已建立的索引

Manifest 的内容

一个 Manifest 包含:

yaml 复制代码
version: 1
created_at: 2024-01-15T10:30:00Z
schema:
  fields:
    - name: id
      type: int64
    - name: name
      type: utf8
    - name: embedding
      type: list<float32>
fragments:
  - id: 0
    files: [...]
    row_count: 10000
statistics:
  num_rows: 10000
  byte_size: 5242880

Manifest 序列化

Manifest 可以序列化为 JSON 或 Protocol Buffer 格式,存储在文件系统中。

Manifest 版本管理

版本控制机制

Lance 支持多个 Manifest 版本共存:

markdown 复制代码
_lance/
  _manifests/
    v1.manifest
    v2.manifest
    v3.manifest
  _latest.txt

_latest.txt 指向当前最新版本。

时间旅行查询

用户可以打开任何历史版本进行查询:

open_version(dataset_path, version=2)

这使得 Lance 支持:

  1. ACID 事务语义
  2. 数据恢复
  3. 审计跟踪
  4. 版本对比

版本之间的差异

不同版本可能有不同的:

  • Fragment 集合(添加/删除数据)
  • Schema(添加/修改列)
  • 索引(创建/删除索引)
  • 统计信息(更新行数、大小)

场景

场景 1:添加新列

原始 Schema:id, name, price 新增列:embedding

处理方式:

  1. 创建新 Manifest 版本
  2. 在新 Fragment 中添加 embedding 列
  3. 旧 Fragment 的 embedding 填充为 NULL
  4. 提交新 Manifest

场景 2:数据删除

要删除某些行:

  1. 创建删除文件,记录行 ID
  2. 更新 Fragment 的删除文件列表
  3. 创建新 Manifest 版本
  4. 查询时自动跳过被删除的行

场景 3:版本对比

对比两个版本:

  • 版本 1:100 万行,5GB
  • 版本 2:150 万行,7.5GB
  • 差异:新增 50 万行

性能考虑

随机访问

Lance 文件格式支持快速随机访问:

  1. 通过 metadata offset 快速定位元数据
  2. 根据页面索引快速定位数据
  3. 支持列式读取(不需读取全行)
  4. 支持范围读取(读取特定行范围)

缓存优化

  • 元数据缓存:常驻内存
  • 页面缓存:LRU 策略
  • 索引缓存:按需加载

总结

Lance 文件格式的核心特性:

  1. 分页组织:支持快速随机访问
  2. Fragment 管理:灵活的数据分片
  3. Manifest 管理:完整的元数据管理
  4. 版本控制:支持时间旅行查询
  5. Schema 演化:添加列无需重写

下一章讨论编码与压缩技术。

相关推荐
语落心生2 小时前
探秘新一代向量存储格式Lance-format (六) 编码与压缩技术
架构
语落心生2 小时前
探秘新一代向量存储格式Lance-format (七) 编码器与解码器实现
架构
语落心生2 小时前
探秘新一代向量存储格式Lance-format (四) 容器与缓存机制
架构
语落心生2 小时前
探秘新一代向量存储格式Lance-format (三) Lance 数据类型系统
架构
语落心生2 小时前
探秘新一代向量存储格式Lance-format (二) 项目结构与模块划分
架构
语落心生2 小时前
探秘新一代向量存储格式Lance-format (一)Lance 项目概览与设计理念
架构
TracyCoder1233 小时前
微服务注册中心基础(一):AP架构原理
微服务·云原生·架构·注册中心
Kapaseker3 小时前
十年开发告诉你什么是“烂代码”
架构
Java烘焙师4 小时前
架构师必备:限流方案选型(原理篇)
架构·限流·源码分析