开发者推出为Plan 9设计的新文件系统gefs,已开放测试
来源标题:Gefs: A new file system built for Plan 9
开发者发布了一款面向Plan 9的新文件系统gefs,目前尚不可完全信任但已可供测试。gefs旨在成为崩溃安全、能检测损坏、简单且支持快速快照的文件系统,基于写时复制Bε树构建传统9p接口。代码已发布在shithub.us上。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
最近我在开发一个名为 gefs 的新文件系统。它目前还不值得信赖,但已经可以用于测试。代码可以在这里找到: https://shithub.us/ori/gefs/HEAD/f.html Gefs 是为 Plan 9 构建的新文件系统。 它的目标是成为一个崩溃安全、能检测损坏、简单且支持快速快照的文件系统,优先级依次递减。 Gefs 通过在一组写时复制的 Bε 树之上构建传统的 9p 文件系统接口来实现这些目标。 它并不试图在各个方面都做到最优,但对日常使用来说足够好。 Gefs 提出了一个问题:如果我们停在一个简单、易于理解的写时复制文件系统上,然后说“这已经足够好了”,会发生什么? 在不做出重大牺牲的情况下,我们能走多远? 目前,Plan 9 有几个可用的通用磁盘文件系统。 它们都有一组共同的问题。 断电时,文件系统往往会损坏,需要手动恢复步骤。 静默的磁盘损坏不会被文件系统捕获,读取会静默返回错误的数据。 它们往往需要一块大且不可收缩的磁盘用于归档转储,并且当磁盘写满时表现很差。 此外,它们在进行文件查找时,都会在目录中进行 O(n) 扫描。 这在大型目录中会导致性能不佳。 Cwfs 是 9front 上的默认文件系统,已被证明性能良好且可靠,但不具备崩溃安全性。 虽然根文件系统可以从转储中恢复,但这很不方便,并且可能导致大量数据丢失。 它无法从转储中回收空间。 此外,由于年代久远,它背负了很多历史包袱和复杂性。 Hjfs 是 9front 中的一个新实验性系统,极其简单,代码行数比任何其他磁盘存储选项都少。 它有转储功能,但没有将转储存储与缓存存储分开,从而可以充分利用小磁盘。 然而,它极其缓慢,不具备崩溃安全性,并且缺乏一致性检查和恢复机制。 最后,fossil 是 9legacy 上的默认文件系统,庞大且复杂。 它使用软更新来实现崩溃安全性[7],这种方法在 BSD 文件系统的实践中效果不佳[8]。 Fossil 由于其固有的复杂性,一直存在(并且现在仍然存在)死锁和崩溃的历史。 经常有报告称在使用 clone 等工具时出现死锁和崩溃[9]。 虽然这些 bug 可以在发现时修复,但简单性要求重新思考磁盘上的数据结构。 而且即使在增加了所有这些复杂性之后,fossil+venti 系统在磁盘写满时也无法回收空间。 Gefs 旨在解决这些文件系统的问题。 数据和元数据采用写时复制,并具有原子提交。 如果文件服务器在超级块更新之前崩溃,那么下一次挂载将看到最后一次同步到磁盘的提交。 可能会丢失一些数据,默认最多 5 秒的数据,但不会发生损坏。 此外,由于使用了索引数据结构,目录不会遭受 O(n) 查找的问题,解决了大型目录长期存在的性能问题。 虽然快照有助于保持数据一致性,但磁盘往往会随着时间的推移而出现故障。 为了检测损坏并允许空间回收,块指针是 64 位值的三元组: 块地址、块哈希以及它们诞生时的代数。 如果底层存储介质返回了损坏的数据,这可以通过块哈希检测到。 损坏会被报告,然后可以通过备份、RAID 恢复或其他方式恢复损坏的数据。 最终目标是让 gefs 实现自愈。 归档转储被快照所取代。 快照可以随时删除,从而允许快照内的数据被回收再利用。 为了实现这一点,除了地址和哈希之外,每个块指针还包含一个诞生代数。 块的回收使用受 ZFS 启发的 deadlist 算法。 最后,整个文件系统基于一个相对新颖的数据结构。 这种数据结构被称为 Bε 树 [1]。 它是 B+ 树的一种写优化变体,与写时复制语义配合得特别好。 这使得 gefs 能够大大减少传统写时复制 B 树中出现的写放大。 额外的好处是,它用更少的复杂性解决了这些问题。 通过选择合适的数据结构,文件系统其他地方的大量复杂性就消失了。 核心数据结构的复杂性带来了回报。 能够在 Bε 树中原子地更新多个属性,使核心数据结构无需锁即可安全遍历,以及拥有一组简单、统一的操作,使其他一切变得更简单。 因此,gefs 的总源代码目前为 8737 行,而 CWFS 为 15634 行,fossil/venti 系统为 27762 行(fossil 为 20429 行,Venti 另有 7333 行)。 Gefs 使用的核心数据结构是 Bε 树。 Bε 树是 B+ 树的一种改进,通过在枢轴节点中添加写缓冲区来优化写入。 与 B 树一样,Bε 树由包含键和值的叶子节点以及枢轴节点组成。 与 B 树一样,枢轴节点包含指向其子节点的指针,子节点可以是枢轴节点或叶子节点。 与 B 树不同的是,枢轴节点还包含一个写缓冲区。 Bε 树实现了一个简单的键值 API,支持点查询和范围扫描。 它通过增加 upsert 操作,与传统的 B 树键值存储有所不同。 Upsert 操作是将修改消息插入树中的操作。 这些修改是针对某个键的。 要插入到树中,根节点被复制,新消息被插入到其写缓冲区中。 当写缓冲区满时,它会被检查,并统计指向每个子节点的消息数量。 待处理写入数量最多的子节点被选为牺牲者,然后
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。