Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SwiftFuse Phase-2 Roadmap(R1–R8)

日期:2026-08-10 · 上一阶段:v0.1.1(12-gate 检测 + BUG-6/BUG-7 修复,REPORT-2026-08-08) 定位:从“架构正确“走向“语义严格、故障可证明、性能稳定“。 总原则:R1 完成前不加复杂 feature;每个 R 有明确 gate 与可回滚 commit。


0. 阶段判断(2026-08-10)

  • 成立:chunk/slice/block + etcd + Swift 大架构;五条核心原则落地。
  • 不成立:production-ready 声称(inode identity、fencing、跨节点 handle 生命周期、 write request amplification、cache coherence、测试可信度 六个系统性问题未收敛)。
  • 三个 bug 同根:BUG-2/BUG-5/BUG-7 都是 PathFilesystem 把 path 当 identity。 R1 用 inode-centric FUSE boundary 根治,不再给 InodePathBridge 打补丁。

R1 — Identity & Correctness Foundation(最高优先级)

目标

  1. inode-centric FUSE boundary:FUSE nodeid → SwiftFuse inode_id → InodeMeta, path lookup 仅 (parent_inode, name) → inode;rename/unlink-open/FORGET/lookup/GC 全自然。
  2. open-unlinked fstat() 正确(现在 5/5 ENOENT,bridge 层)。
  3. rename/nodeid/FORGET 生命周期正确(BUG-7 类消除)。
  4. kernel_ttl 从 0 恢复非 0(先证明 inode 层不再依赖内核重查)。
  5. schema_version + CAS 改 revision(已部分完成 4f063f7:mod_revision CAS + schema_version 落地)。

Gate

pjdfstest unlink/14 PASS
rename torture 100k+(跨 rename/readdir/chmod 交错)
fsx / fsstress / fio verify 全绿
kernel_ttl = 1 后 G1/G6 重跑

状态(2026-08-18 据 HANDOFF-2026-08-15)

  • CAS mod_revision + schema_version:✅ 4f063f7
  • inode-centric 重写:✅ 已落地(InodeFs,nodeid == engine inode_id)
  • ttl=1 G1 + G4a×3 + G6:✅ 2026-08-15 关上(测完已回 ttl=0)
  • F2b ≥35 轮 × ttl × write_back:⏳ 合同未关。t0w1(ttl=0 wb=true)35/35 PASS(2026-08-18)。t0w0 / t1w1 / t1w0 未跑。

R2 — Distributed Ownership(fencing + 全局 handle 生命周期)

目标

  1. stable client_id + session_id + lease_id + fencing_epoch: holder 从 hostname-PID 改为稳定身份;每次写 acquire 携带 session/epoch。
  2. 所有 metadata commit 同时 CAS:
    inode_version == expected AND lease_epoch == N AND holder == client
    
    旧 writer 复活(epoch 过期)→ 100% 无法 commit。
  3. distributed open-handle registry:/handles/<inode>/<client>/<handle> 绑定 etcd lease; daemon 死亡自动消失;inode GC 条件 = nlink==0 AND handle_count==0 AND no writer lease。
  4. 解决:daemon 重启 30s EBUSY、stale writer、cross-node open-deleted、安全 block/inode GC。
  5. 安全 block GC 的前提:old reader 持有旧 metadata version 时不能删其引用的 blocks → open-handle generation / grace period / reader lease。

Gate

partition → lease expiry → new writer 获得 lease → old writer 恢复 → 尝试 commit
→ 必须 100% 失败
跨节点 open-deleted:A unlink 后 B 的 fd 读写正常,B close 后才 GC

R3 — Write Path 2.0

已定死的事实(M1 测量,2026-08-11)

  • 4K 写 + fsync → 1 × 4096B Swift object(字节放大 = 1×,不是 1024×)。 REPORT/BENCHMARK 的 “1024×” 声明已修正(下文 §M1)。
  • 100 × 4K 随机写 → ~96 个对象(非相邻不合并);真实问题是 object/request amplification。
  • flush 曾逐 slice 串行 PUT(96 块 = 33s)→ 已修复 4f063f7:批量并行上传,33s → 9.4s。
  • 剩余瓶颈:Swift 小对象 PUT 吞吐下限 + 对象数量爆炸。

路线

  1. dirty interval aggregation(已有合并,随机 4K 天然不合并)✅ 部分
  2. cross-slice bounded parallel PUT ✅ 4f063f7
  3. debounce / write aggregation(fsync 语义内的窗口合并)
  4. Immutable Delta Pack:多个小写打包进 1 个对象(index + payload), Swift PUT count ≈ dirty_bytes / pack_target;后台 compaction 合并回大 block。 完全符合宗旨:object immutable、不读旧数据、mutation 只在 metadata。
  5. background compaction(compact_interval=0 → 默认开启)

Gate

100 × 4K random write:
  PUT 次数 ≈ 1~2(delta pack)
  对象 size 分布记录
  fsync 完成时间可预测
容器对象数增长 = dirty_bytes / pack_target

R4 — Small-file Path

已定死的事实(M2 测量)

  • empty-file create 0 个 Swift 对象(纯 metadata,设计已正确)。
  • 114ms/create 的瓶颈 = 串行 etcd 往返(daemon 单 Mutex<Client> + create 路径 6-8 次等时操作),不是 Swift。
  • stat 9ms(路径缓存命中)。

路线

  1. create 路径 etcd 操作瘦身(合并 counter bump / parent touch;批量 inode 分配)。
  2. 多 etcd client / 连接池消除 Mutex<Client> 串行化。
  3. 目标:create ceiling 从 ~114ms 降到 etcd txn 延迟量级(目标 <20ms); mdtest create 从 9.5/s 到 >50/s。

Gate

touch 1000 空文件:0 Swift 对象(审计容器)
mdtest create/s 提升 ≥2×

R5 — Cache Coherence

现状

  • 本地 mutation 会 invalidate 进程内 cache;无跨节点通知(文档已标高风险未证明项)。
  • kernel_ttl=0 只保证内核重新问 userspace;userspace 的 path/attr/dir cache 若无跨节点失效,仍可回答 stale。

路线

  1. etcd watch revision stream:监听 {prefix} 变更 → invalidate inode/path/dir cache。
  2. 或 inode version validation(每次 cache 命中验证 version)。
  3. 恢复 kernel_ttl = 1~5s。

Gate

A rename/unlink/create/chmod → B 立即 stat/readdir/getattr,循环几十万次,0 stale
kernel_ttl=1 下 G6 重跑

R6 — Professional Correctness Suite

目标

  • G2 fstests:加 mount.swiftfuse/swiftfuse mount/unmount(可被 fstests 驱动 mount/remount)。
  • G3 LTP:16GB builder 编译 → artifact 拷到节点(不再 NOT SUPPORTED)。
  • Porcupine linearizability:Rust operation history recorder → JSON → Porcupine checker (多 client + 同 inode + 随机 history + partition/restart)。
  • failpoint crash testing:
    FAILPOINT_AFTER_BLOCK_PUT / BEFORE_METADATA_CAS / AFTER_METADATA_CAS
    FAILPOINT_BEFORE_REPLY / COMPACTION_AFTER_PUT / GC_BEFORE_DELETE
    
    seed 1..10000 反复 crash/restart → 只产生 orphan、绝不半可见。
  • G7 扩展:kill 真实 etcd leader / follower / lose quorum / asymmetric partition / Swift proxy & object-server kill / writer partition → lease expiry → new writer → old writer 复活。

Gate

Porcupine: 所有 history linearizable
failpoint: 10000 seeds 无 committed-data corruption
G7 fencing 考试通过

R7 — Benchmark 2.0

修正(M3 测量)

  • 单节点 benchmark 走 loopback(10.0.0.1 = lo,27.9 GB/s),352-406 MiB/s 物理自洽; “千兆内网 + Swift proxy ceiling” 表述已修正。
  • 真实跨节点上限需跨节点路径测量(G10 的 5-12 MiB/s 是部分证据)。

要求

  • 每个 workload 同时记录:FUSE op latency / etcd txn latency / Swift request latency+count / payload bytes / cache hit ratio / network bytes / CPU / memory / Swift auditor-replicator 活动。
  • Raw Swift → SwiftFuse → Raw Swift 交替跑,隔离环境噪声。
  • cold / warm / mixed 分开:cold = 新文件 + 清 cache + dataset > cache; warm = 100% 本地 cache。
  • 对比矩阵:Raw Swift / rclone / GeeseFS(S3API) / JuiceFS / SwiftFuse。
  • G8 判定改为 MEASURED / REGRESSION / TIMEOUT / SLO-VIOLATION(不再叫 PASS)。

R8 — NVMe sparse cache(最后)

  • 顺序:correctness → write amplification → consistency/fencing → benchmark credibility → NVMe。
  • 实现:RAM metadata/index + NVMe block cache + Swift backing(学 Mountpoint)。
  • 测:working set 10/50/100GB/1TB cache hit curve。

执行顺序与当前状态

R状态已落地 / 下一步
R1门禁已关✅ inode-centric + ttl=1 G1/G4a/G6(HANDOFF-2026-08-15);✅ F2b t0w1 35/35;⏳ 其余三格
R2门禁已关✅ fencing + persist-grant + GC hook(maybe_gc/peer_holds/sweep_unlinked);✅ live 100/100 081421;⏳ 四节点线上 bin 未换
R3部分✅ 并行 PUT + pack 单测绿(swift2,packed_100x4k PUT=1);⏳ pack 默认关,舰队 100×4K PUT≈1~2 未关
R4部分✅ create 纯 metadata + etcd 瘦身单测绿(live 4→2 RTT);⏳ mdtest ≥2× 未测
R5设计中etcd watch 失效(本会话设计;不碰 etcd.rs)
R6部分✅ Porcupine fixture;⏳ failpoint 10000 seeds + G7 fencing 考试
R7框架在Benchmark 2.0 脚本在;⏳ 实跑
R8未开始NVMe cache(最后)

测量附录(M1-M3,2026-08-11)

M1 — 4K 写放大真相(容器审计 + etcd)

场景对象增量对象大小结论
100×4K 写 + 每次 fsync+100全部 4096B字节放大 1×;491ms/写 = 1 PUT + commit
100×4K 写 + 单 fsync+96(94×4K + 2×8K)合并 2 对相邻flush 33s(串行)→ 9.4s(批量并行后)
  • REPORT/BENCHMARK 的 “4K→4MiB ≈1024× byte amplification” 为错误声明,已修正。

M2 — empty-file create

  • 100 个空文件 create:0 个 Swift 对象(纯 metadata);114ms/create 为 etcd 串行瓶颈。

M3 — 网络拓扑

  • 10.0.0.1 是 loopback(dev lo,27.9 GB/s);单节点 benchmark 未跨网卡。
  • eth1(10.0.0.x 内部网)为 Contabo virtio 网卡(ethtool 无法读速,物理 ≥10Gb 量级)。
  • “千兆内网” 描述不适用于单节点;跨节点真实上限需跨节点路径测量。