DESIGN
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
## 这一步做了什么
|
||||
|
||||
- 一个基于 **libfuse3** 的 C++ FUSE Daemon(`etvd_fuse`),挂载一个目录,拦截全部文件系统调用。
|
||||
- **透传后端(passthrough)**:所有操作转发到真实后端目录(默认 `./backend`)。这是第一阶段的后端;第二阶段会替换为 COW append-only 后端(`data.raw` + Segment + `cur` 快照),FUSE 拦截层与日志层保持不变。
|
||||
- **透传后端(passthrough)**:所有操作转发到真实后端目录(默认 `./backend`)。这是第一阶段的后端;第二阶段会替换为 COW append-only 后端(`data.raw` + Segment),第三阶段再引入 `cur` 快照加速读,FUSE 拦截层与日志层保持不变。
|
||||
- **操作日志层**:每一次拦截到的调用都结构化打印到 stderr(`[etvd] <op> <path> <detail>`),`write` 额外带 `off/size/rc` 与前 16 字节 hex 预览 —— 满足「从底层观察到每一次写入」。
|
||||
- 回调里直接 log + syscall 透传,**没有额外抽象层**(FUSE3 自己的 `struct fuse_operations` 就是接口)。第二阶段做 COW 后端时再按需引入存储抽象 —— 届时 `write` 语义是 append+Segment,和现在的 pwrite 形状不同,现在猜接口多半对不上。
|
||||
|
||||
@@ -105,7 +105,7 @@ fusermount3 -u mnt
|
||||
|
||||
- **绝对路径**:libfuse3 在跑事件循环前会 `chdir("/")`,因此 daemon 在请求时解析的所有路径(后端根目录)必须是绝对路径。`main` 在挂载前把 `backend` 与 `mountpoint` 都 `realpath` 成绝对路径。
|
||||
- **文件句柄**:`open/create` 打开真实 fd 存入 `fuse_file_info->fh`;`read/write` 用 `pread/pwrite`;`release` 关闭。
|
||||
- **锁**:`lock` 回调对 `F_GETLK` 返回 `F_UNLCK`、对 `F_SETLK` 返回 0,使 SQLite 的 fcntl 建议锁在单进程下正常运行。**真实互斥留到第十阶段的分布式写租约。**
|
||||
- **锁**:`lock` 回调对 `F_GETLK` 返回 `F_UNLCK`、对 `F_SETLK` 返回 0,使 SQLite 的 fcntl 建议锁在单进程下正常运行。**真实互斥留到第十一阶段的分布式写租约。**
|
||||
- **未实现的 op**(xattr / fallocate 等)保持 NULL,FUSE 返回 `-ENOSYS`,SQLite 等会自动回退。
|
||||
|
||||
## 第一阶段边界(明确不做)
|
||||
|
||||
+29
-21
@@ -1,23 +1,24 @@
|
||||
# etvd设计文档
|
||||
|
||||
> 分十阶段递进实现:FUSE 拦截 -> 内存段 Diff + 聚合快照 -> SQLite 真实写入记录 -> KV 持久化 -> KV 事务模式 -> Prefix 策略 -> MVCC 恢复 -> etcd 协议兼容 -> QUIC mTLS Raft -> 分布式租约。
|
||||
> 分十一阶段递进实现:FUSE 拦截 -> 内存段 Diff -> cur 快照与聚合版本 -> SQLite 真实写入记录 -> KV 持久化 -> KV 事务模式 -> Prefix 策略 -> MVCC 恢复 -> etcd 协议兼容 -> QUIC mTLS Raft -> 分布式租约。
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [第一阶段:FUSE 拦截验证](#第一阶段fuse-拦截验证)
|
||||
2. [第二阶段:内存段 Diff + 聚合快照](#第二阶段内存段-diff--聚合快照)
|
||||
3. [第三阶段:SQLite 真实写入记录](#第三阶段sqlite-真实写入记录)
|
||||
4. [第四阶段:KV 持久化元数据](#第四阶段kv-持久化元数据)
|
||||
5. [第五阶段:KV 事务模式](#第五阶段kv-事务模式)
|
||||
6. [第六阶段:KV Prefix 策略层](#第六阶段kv-prefix-策略层)
|
||||
7. [第七阶段:基于 KV 的 MVCC 恢复](#第七阶段基于-kv-的-mvcc-恢复)
|
||||
2. [第二阶段:内存段 Diff](#第二阶段内存段-diff)
|
||||
3. [第三阶段:cur 快照与聚合版本](#第三阶段cur-快照与聚合版本)
|
||||
4. [第四阶段:SQLite 真实写入记录](#第四阶段sqlite-真实写入记录)
|
||||
5. [第五阶段:KV 持久化元数据](#第五阶段kv-持久化元数据)
|
||||
6. [第六阶段:KV 事务模式](#第六阶段kv-事务模式)
|
||||
7. [第七阶段:KV Prefix 策略层](#第七阶段kv-prefix-策略层)
|
||||
8. [第八阶段:基于 KV 的 MVCC 恢复](#第八阶段基于-kv-的-mvcc-恢复)
|
||||
构建为lib和单独可执行器
|
||||
8. [第八阶段:etcd 协议兼容](#第八阶段etcd-协议兼容)
|
||||
9. [第九阶段:QUIC mTLS Raft 算法](#第九阶段quic-mtls-raft-算法)
|
||||
10. [第十阶段:分布式租约](#第十阶段分布式租约)
|
||||
11. [后续分布式扩展蓝图](#后续分布式扩展蓝图)
|
||||
9. [第九阶段:etcd 协议兼容](#第九阶段etcd-协议兼容)
|
||||
10. [第十阶段:QUIC mTLS Raft 算法](#第十阶段quic-mtls-raft-算法)
|
||||
11. [第十一阶段:分布式租约与条件数据同步](#第十一阶段分布式租约与条件数据同步)
|
||||
12. [后续分布式扩展蓝图](#后续分布式扩展蓝图)
|
||||
|
||||
---
|
||||
|
||||
@@ -42,9 +43,9 @@
|
||||
|
||||
---
|
||||
|
||||
## 第二阶段:内存段 Diff + 聚合快照
|
||||
## 第二阶段:内存段 Diff
|
||||
|
||||
**目标**:在 FUSE 拦截通路打通的基础上,实现 COW 内存段 Diff 机制。任何写入都不原地覆盖物理文件,只在尾部追加新字节段,通过段链表拼接还原文件视图。
|
||||
**目标**:在 FUSE 拦截通路打通的基础上,实现 COW 内存段 Diff 机制。任何写入都不原地覆盖物理文件,只在尾部追加新字节段,通过段链表拼接还原文件视图。本阶段聚焦写入正确性:读取通过重放历史 VersionDiff 重建段链表,功能正确但不优化性能;cur 快照加速读与聚合版本留到第三阶段。
|
||||
|
||||
### 三层架构
|
||||
|
||||
@@ -139,6 +140,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 第三阶段:cur 快照与聚合版本
|
||||
|
||||
**目标**:在第二阶段 diff 机制跑通的基础上,解决「读取需重放全部历史 VersionDiff 导致延迟随写入次数线性爆炸」的问题。维护当前视图快照 cur 常驻内存,直接记录文件当前生效的完整段链表,读取无需重放历史;并将物理存储拆分为多 Block,引入聚合版本优化过长的小段链表。
|
||||
|
||||
---
|
||||
|
||||
### cur 快照与读取加速
|
||||
|
||||
### 为什么需要 cur 快照
|
||||
@@ -199,7 +206,7 @@ Truncate 场景:遍历原链表裁剪长度,生成短链表覆盖写入。
|
||||
|
||||
---
|
||||
|
||||
## 第三阶段:SQLite 真实写入记录
|
||||
## 第四阶段:SQLite 真实写入记录
|
||||
|
||||
**目标**:让 SQLite 在 /vfs 上正常运行,底层能精确记录每一次事务产生的字节段 Diff,证明 COW 机制对真实数据库工作负载有效。
|
||||
|
||||
@@ -227,7 +234,7 @@ Truncate 场景:遍历原链表裁剪长度,生成短链表覆盖写入。
|
||||
|
||||
---
|
||||
|
||||
## 第四阶段:KV 持久化元数据
|
||||
## 第五阶段:KV 持久化元数据
|
||||
|
||||
**目标**:把内存中的路径到段链表的映射,持久化到 KV 存储中。KV key 与 VFS 虚拟路径百分之百对应,元数据 value 中记录保存策略、实际位置与预期位置。
|
||||
|
||||
@@ -291,7 +298,7 @@ Truncate 场景:遍历原链表裁剪长度,生成短链表覆盖写入。
|
||||
|
||||
---
|
||||
|
||||
## 第五阶段:KV 事务模式
|
||||
## 第六阶段:KV 事务模式
|
||||
|
||||
**目标**:在 KV 持久化之上实现显式事务边界。业务层或管理员可手动调用 TxnBegin / TxnEnd / TxnRollback,将多次 VFS 写入聚合为单个 COW 版本,而不是每次 write 都产生独立 Diff。
|
||||
|
||||
@@ -331,7 +338,7 @@ TxnRollback
|
||||
|
||||
---
|
||||
|
||||
## 第六阶段:KV Prefix 策略层
|
||||
## 第七阶段:KV Prefix 策略层
|
||||
|
||||
**目标**:在 KV 存储之上实现前缀策略树,支持按路径前缀统一配置同步策略、MVCC 开关、共享字段等。路径匹配采用最长前缀优先。
|
||||
|
||||
@@ -357,7 +364,7 @@ xattr 动态覆盖
|
||||
|
||||
---
|
||||
|
||||
## 第七阶段:基于 KV 的 MVCC 恢复
|
||||
## 第八阶段:基于 KV 的 MVCC 恢复
|
||||
|
||||
**目标**:利用 KV 中保存的历史快照,实现对单个路径的任意版本回滚恢复,不是全系统恢复,而是精确到某个 path 的某个历史版本。
|
||||
|
||||
@@ -395,7 +402,7 @@ xattr 动态覆盖
|
||||
|
||||
---
|
||||
|
||||
## 第八阶段:etcd 协议兼容
|
||||
## 第九阶段:etcd 协议兼容
|
||||
|
||||
**目标**:对外暴露 etcd v3 API 语义,上层工具(etcdctl、Kubernetes 等)可无缝接入。内部读取不走传统 KV 查询,而是直接从 VFS 文件流中获取数据。
|
||||
|
||||
@@ -430,7 +437,7 @@ Watch 机制
|
||||
|
||||
---
|
||||
|
||||
## 第九阶段:QUIC mTLS Raft 算法
|
||||
## 第十阶段:QUIC mTLS Raft 算法
|
||||
|
||||
**目标**:实现基于 QUIC + mTLS 的 Raft 共识算法,替代 etcd 原生的 gRPC over TCP 传输层。节点间所有通信(Raft 日志、大文件字节、心跳探活)统一走 QUIC 连接,通过 mTLS 完成双向身份鉴权。
|
||||
|
||||
@@ -463,7 +470,7 @@ Raft 日志传输
|
||||
|
||||
---
|
||||
|
||||
## 第十阶段:分布式租约与条件数据同步
|
||||
## 第十一阶段:分布式租约与条件数据同步
|
||||
|
||||
**目标**:实现 FD 级别的分布式写租约,保证同一时刻只有一个节点能写入指定文件。同时实现条件同步机制:默认元数据全集群 Raft 同步,但实际的 VFS value 数据可按策略决定是否跨节点复制。
|
||||
|
||||
@@ -714,3 +721,4 @@ SQLite 不是独立的分布式模块,而是 VFS 的标准消费者之一,
|
||||
| 2026-07-06 | v0.4 | 增加第五阶段 KV 事务模式(TxnBegin / TxnEnd / TxnRollback),支持手动调用聚合多次 VFS 写入为单事务 |
|
||||
| 2026-07-06 | v0.5 | 重构为十阶段递进结构,新增第九阶段 QUIC mTLS Raft、第十阶段分布式租约与条件数据同步;KV key 与 VFS 路径一一对应;元数据 value 包含保存策略、预期位置、实际位置 |
|
||||
| 2026-07-06 | v0.6 | 第十阶段读取行为调整:默认本地无数据则读取失败,不自动网络拉取;增加 remote_read 开关区分公网/内网场景 |
|
||||
| 2026-07-07 | v0.7 | 拆分原第二阶段:内存段 Diff(写入 COW 机制)独立为第二阶段,cur 快照加速读 + 块增长 + 聚合版本独立为第三阶段;后续阶段顺延,整体由十阶段改为十一阶段 |
|
||||
|
||||
Reference in New Issue
Block a user