7.7 KiB
7.7 KiB
ZVFS 分阶段改造计划(可重入,用户验收版)
目标:把当前实现改造成可并发扩展、高性能且语义完整的架构。
约束:我无法使用 root,所有阶段验收由你执行。
通用约定(所有阶段)
- 建议先记录基线:
git rev-parse --short HEAD。 - 每阶段都保持“可编译 + 可回归”。
- 每阶段完成后打一个里程碑 tag(例如
phase1-done),中断后可从最近 tag 继续。 - 验收命令默认:
make -C zvfs -j4
make -C test -j4
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs
已落地变更(2026-03-03)
-
stale blob 自愈修复(已完成)
open(O_CREAT)遇到元数据引用失效 blob 时自动重建并回写元数据。unlink/close(rename 覆盖)删除失效 blob 时容忍ENOENT/EINVAL,避免误报EIO。
-
小块写合并(已完成)
- hook 层新增 per-fd writeback buffer(默认 128KB),连续小写先合并再
pwrite。 - 在
read/pread/lseek/fsync/fdatasync/close/ftruncate/fallocate/unlink/rename/sync_file_range前补齐 flush,保证可见性。
- hook 层新增 per-fd writeback buffer(默认 128KB),连续小写先合并再
-
当前观察
- 小块写已提升,但小块读仍偏低;读优化作为后续阶段重点。
Phase 0:基线与护栏
要做的事情
- 固化当前行为基线:功能、性能、CPU 占用。
- 在代码中加入轻量统计框架(计数器/延迟桶/开关),不改变行为。
- 增加最小并发回归入口(并行跑现有测试)。
用户验收
make -C zvfs -j4 && make -C test -j4
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_perf /zvfs
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_random_perf /zvfs
通过标准
- 功能测试通过。
- 有一份可复用的“基线性能记录”(IOPS/BW/延迟)。
可重入说明
- 仅增量加观测代码,可重复执行,不影响后续阶段。
Phase 1:全局运行时与并发安全
要做的事情
- 引入
zvfs_runtime_t,统一管理 mount/init 状态与全局资源。 - 用
pthread_once + mount mutex保护初始化/挂载过程。 - 给 inode/path/fd/dirs 操作补齐锁(rwlock + 细粒度 mutex)。
- 保持接口不变:
open/read/write/...行为兼容。
用户验收
make -C zvfs -j4 && make -C test -j4
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs
for i in $(seq 1 8); do
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_dual_open_same_file /zvfs &
done
wait
通过标准
- 无崩溃/死锁。
- 并发场景不出现随机 EBADF/ENOENT/元数据错乱。
可重入说明
- 锁与 runtime 框架可独立提交;若中断,重新进入本阶段不会破坏状态。
Phase 2:Worker 化 IO 通路(替换单 global_thread)
要做的事情
- 实现 worker 池(默认 N:M,支持配置 1:1)。
- 每 worker 持有独立
spdk_thread + io_channel。 - read/write/pread/pwrite 路径改为“提交到绑定 worker 执行”。
- 保留同步 POSIX 语义,但去掉全局单线程瓶颈。
用户验收
make -C zvfs -j4 && make -C test -j4
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs
for i in $(seq 1 4); do
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_random_perf /zvfs &
done
wait
通过标准
- 功能与 Phase 1 一致。
- 并发压测吞吐明显高于基线(目标 >= 1.5x,先达成趋势)。
可重入说明
- worker 与旧路径可通过编译开关共存,出现问题可快速切回旧路径继续调试。
Phase 3:完成等待机制与批处理
要做的事情
- 用“提交队列 + 完成通知”替换纯 busy-poll
waiter。 - 增加批量 poll 与背压(队列满、超时、错误传播)。
- 补齐延迟与队列深度指标,定位长尾。
- 引入读路径流水线(允许并发 in-flight read),把有效 QD 从 1 提升到可配置值。
用户验收
make -C zvfs -j4 && make -C test -j4
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_perf /zvfs
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_random_perf /zvfs
通过标准
- 在同等负载下 CPU 空转显著下降。
- P99 延迟较 Phase 2 收敛(无明显长尾恶化)。
可重入说明
- 队列与等待层可单独演进;可先只替换 read,再替换 write。
Phase 4:页缓存与写回合并
要做的事情
- 引入 per-inode 4KB 页缓存(dirty/clean 状态)。
- 小写走 cache + 延迟刷盘,大写/顺序写支持直写或批量写。
- 引入 flush 策略:阈值、定时、fsync 强制。
- 缩减
resize + sync_md频率(chunk 预分配)。 - 读性能专项:
- 增加顺序读 readahead(如 128KB~1MB 窗口自适应)。
- 对齐读支持“直接读到用户缓冲”快路径,减少一次 memcpy。
- 引入 clean page cache(读热点复用,避免重复 blob read)。
用户验收
make -C zvfs -j4 && make -C test -j4
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_random_noaligned_perf /zvfs
通过标准
- 功能语义不回退(truncate/sparse/rename/fstat 通过)。
- 小块随机写吞吐继续提升,写放大降低。
可重入说明
- cache 可先只支持 write-through,再切 write-back;两步都可单独验收。
Phase 5:元数据日志化与 fsync 语义闭环
要做的事情
meta_save/load从文本快照升级为 WAL + checkpoint(带 CRC/版本)。- 明确并实现
fdatasync/fsync语义:- fdatasync 保证数据持久化;
- fsync 额外保证必要元数据持久化。
- 补齐崩溃恢复流程(checkpoint + replay)。
用户验收
make -C zvfs -j4 && make -C test -j4
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_phase2_posix /zvfs
# 建议补充一次“异常退出后重启读取”的恢复验证(手工执行)
通过标准
- 重启后目录项与文件大小不丢失、不错乱。
- 数据库关键路径(fsync/fdatasync)语义满足预期。
可重入说明
- WAL 与 checkpoint 支持并存迁移;可先双写验证,再切主读路径。
Phase 6:性能收敛与上线门槛
要做的事情
- 清理临时开关,保留必要调优参数。
- 整理性能报告(与 Phase 0 基线对比)。
- 做最终回归矩阵(功能 + 并发 + 性能 + 恢复)。
用户验收
make -C zvfs -j4 && make -C test -j4
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so make -C test run-test
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_perf /zvfs
env LD_PRELOAD=/home/lian/share/10.1-spdk/zvfs/zvfs/libzvfs.so ./test/bin/test_single_file_random_perf /zvfs
通过标准
- 全量功能测试通过。
- 多线程性能达到
codexplan.md目标(或给出量化偏差与原因)。
可重入说明
- 本阶段仅收敛与验收,不引入架构性变更;可反复执行直到指标稳定。
附:root 权限与运行建议
- 若 NVMe/SPDK 环境需要 root,请在你本机按现有流程执行验收。
- 若希望无 root 回归,建议补一个
Mallocbdev 的 JSON 配置,并将 bdev 名改为可配置(环境变量优先)。