关于 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 S3 | s3://bucket-name |
| Cloudflare R2 | https://account.r2.cloudflarestorage.com/bucket |
| Google GCS | gs://bucket-name |
| Azure Blob | az://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 | :7001 | LanceDB 兼容的结构化数据与向量搜索 |
| KV HTTP API | :7002 | 键值存储 |
| NFSv3 | :2049 | 网络文件系统挂载 |
| 9P | :5564 | Plan 9 文件协议 |
| NBD | :10809 | 网络块设备 |
| gRPC Admin | :7000 | 管理接口 |
键空间布局
SlateDB 中的键通过前缀进行命名空间隔离:
| 前缀 | 用途 |
|---|---|
0x01 | Inode 元数据 |
0x02 | 目录条目 |
0x03 | 目录扫描条目 |
0x04 | 目录 cookie 计数器 |
0x05 | 统计分片 |
0x06 | 系统计数器 |
0x07 | 墓碑(GC 用) |
0xA0 | KV 服务数据 |
0xFE | 文件块数据 |
Table API 数据流
Table API 的数据流经多层:
LanceDB SDK → Table HTTP API → LanBufferObjectStore → LanBuffer FS → SlateDB → 对象存储
LanceDB 表以文件形式存储在 LanBuffer 文件系统的 /tables/ 目录下,通过自定义的 LanBufferObjectStore 适配 LanceDB 的 ObjectStore 接口。
核心概念
加密
LanBuffer 使用 XChaCha20-Poly1305 AEAD 算法进行透明静态加密。
密钥管理流程:
- 首次启动时,生成一个随机 32 字节的数据加密密钥(DEK)。
- 用户密码通过 Argon2id(内存 64MB,迭代 3 次,并行度 4)派生出密钥加密密钥(KEK)。
- KEK 用于加密(包装)DEK,包装后的 DEK 存储在对象存储中。
- 实际数据加密使用 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 秒运行一次,处理文件删除留下的墓碑记录:
- 读取待处理的墓碑(每轮最多 10,000 个)。
- 分批删除对应的文件块(每轮最多 10,000 个块)。
- 删除完成后移除墓碑记录。
大文件的删除是增量式的,墓碑中记录 remaining_size 以支持跨多轮 GC 完成清理。
后台任务
LanBuffer 运行时包含以下后台任务:
| 任务 | 间隔 | 说明 |
|---|---|---|
| 统计上报 | 5 秒 | 输出文件系统统计到调试日志 |
| 定期刷盘 | 30 秒(可配置) | 将内存中的写入刷到对象存储 |
| 垃圾回收 | 10 秒 | 清理已删除文件的数据块 |
| 检查点刷新 | 10 秒(仅只读模式) | 热切换 DbReader 到最新状态 |