关于 LanBuffer

什么是 LanBuffer?

LanBuffer 是一个受 turbopuffer 启发的、以对象存储为中心的高速检索引擎。

系统状态存放在 S3 兼容对象存储上,计算侧使用内存 + NVMe 做热缓存,从而做到热数据很快、冷数据很省。

LanBuffer 基于 Lance 提供向量检索、全文检索与混合检索,并额外提供文件系统(NFS/9P/NBD)与 KV 接口便于集成。

核心特性

  • 多协议统一内核 — 同一个进程同时提供 Table API、NFS、9P、NBD、KV API,按需选择接口,无需部署多套系统。
  • 内置加密 — 透明静态加密(XChaCha20-Poly1305 + Argon2id 派生密钥),数据在写入对象存储前自动加密。
  • 内置压缩 — 透明压缩(LZ4 / Zstd),可随时切换算法,已有数据无需重新编码。
  • 多级缓存 — 内存 + NVMe 磁盘缓存(基于 Foyer),加速热点数据与查询路径。
  • 时间点恢复 — 命名 checkpoint 支持快照与回滚到任意历史状态。
  • 云原生 — 面向对象存储后端(S3/R2/GCS/Azure),计算节点无状态。

支持的后端

后端URL 格式
AWS S3s3://bucket-name
Cloudflare R2https://account.r2.cloudflarestorage.com/bucket
Google GCSgs://bucket-name
Azure Blobaz://container-name

架构

                    SlateDB (共享实例, 单 LSM-tree)
                   /        |         \
             LanBuffer    KvStore      (未来扩展)
            /  |  \        |
         NFS  9P  NBD   KV HTTP API (:7002)
               |
         Table HTTP API (:7001, LanceDB 兼容)

分层设计

LanBuffer 采用分层架构,自底向上分为四层:

1. 存储层 — SlateDB + 对象存储

底层使用 SlateDB,一个基于对象存储的 LSM-tree 存储引擎。所有数据最终持久化到 S3/R2/GCS/Azure 等对象存储。写入时经过 BlockTransformer 管线:先压缩、再加密,读取时反向操作。

2. 缓存层 — Foyer 内存 + 磁盘缓存

基于 Foyer 实现两级缓存:

  • 内存缓存:存放热点 block,默认 0.25 GB,可配置。
  • 磁盘缓存:NVMe SSD 上的 SST 文件缓存,默认 10 GB,可配置。

3. 文件系统层 — POSIX 实现

完整的 POSIX 文件系统实现,包括:

  • Inode 管理(文件、目录、符号链接、FIFO、Socket、设备节点)
  • 分块存储(32 KB 块大小)
  • 硬链接支持
  • POSIX 权限(uid/gid/mode)
  • 文件大小配额
  • 后台垃圾回收

4. 协议层 — 多协议接口

协议默认端口用途
Table HTTP API:7001LanceDB 兼容的结构化数据与向量搜索
KV HTTP API:7002键值存储
NFSv3:2049网络文件系统挂载
9P:5564Plan 9 文件协议
NBD:10809网络块设备
gRPC Admin:7000管理接口

键空间布局

SlateDB 中的键通过前缀进行命名空间隔离:

前缀用途
0x01Inode 元数据
0x02目录条目
0x03目录扫描条目
0x04目录 cookie 计数器
0x05统计分片
0x06系统计数器
0x07墓碑(GC 用)
0xA0KV 服务数据
0xFE文件块数据

Table API 数据流

Table API 的数据流经多层:

LanceDB SDK → Table HTTP API → LanBufferObjectStore → LanBuffer FS → SlateDB → 对象存储

LanceDB 表以文件形式存储在 LanBuffer 文件系统的 /tables/ 目录下,通过自定义的 LanBufferObjectStore 适配 LanceDB 的 ObjectStore 接口。


核心概念

加密

LanBuffer 使用 XChaCha20-Poly1305 AEAD 算法进行透明静态加密。

密钥管理流程:

  1. 首次启动时,生成一个随机 32 字节的数据加密密钥(DEK)。
  2. 用户密码通过 Argon2id(内存 64MB,迭代 3 次,并行度 4)派生出密钥加密密钥(KEK)。
  3. KEK 用于加密(包装)DEK,包装后的 DEK 存储在对象存储中。
  4. 实际数据加密使用 DEK,通过 HKDF-SHA256 派生子密钥。

更换密码 只需重新包装 DEK,无需重新加密所有数据:

lanbuffer change-password -c config.toml

块格式: [nonce 24字节][压缩+加密数据+AEAD标签]

压缩

支持两种压缩算法:

  • LZ4(默认)— 速度快,压缩比适中,适合大多数场景。
  • Zstd(级别 1-22)— 压缩比更高,可通过级别调节速度与压缩比的平衡。

配置方式:

[filesystem]
compression = "lz4"      # 或 "zstd-3"、"zstd-19" 等

读取时自动检测压缩算法,因此可以随时切换压缩方式,已有数据无需重新编码。

处理管线: 写入时先压缩再加密,读取时先解密再解压。

Checkpoint(检查点)

Checkpoint 是数据库状态的命名快照,支持时间点恢复。

# 创建检查点
lanbuffer checkpoint create -c config.toml my-snapshot

# 列出所有检查点
lanbuffer checkpoint list -c config.toml

# 查看检查点详情
lanbuffer checkpoint info -c config.toml my-snapshot

# 从检查点启动(只读模式)
lanbuffer run -c config.toml --checkpoint my-snapshot

# 删除检查点
lanbuffer checkpoint delete -c config.toml my-snapshot

在只读模式下,系统每 10 秒自动创建临时检查点并热切换 DbReader,确保读取到最新数据。

垃圾回收

后台 GC 任务每 10 秒运行一次,处理文件删除留下的墓碑记录:

  1. 读取待处理的墓碑(每轮最多 10,000 个)。
  2. 分批删除对应的文件块(每轮最多 10,000 个块)。
  3. 删除完成后移除墓碑记录。

大文件的删除是增量式的,墓碑中记录 remaining_size 以支持跨多轮 GC 完成清理。

后台任务

LanBuffer 运行时包含以下后台任务:

任务间隔说明
统计上报5 秒输出文件系统统计到调试日志
定期刷盘30 秒(可配置)将内存中的写入刷到对象存储
垃圾回收10 秒清理已删除文件的数据块
检查点刷新10 秒(仅只读模式)热切换 DbReader 到最新状态