OpenZFS 是一个复杂的文件系统,在解释该功能的工作原理时,事情一定会变得有点棘手。因此,如果您是 ZFS 新手,您可能需要回顾我们全面的 ZFS 101介绍。
在 ZFS 中扩展存储
除了作为文件系统之外,ZFS 还是一个存储阵列和卷管理器,这意味着您可以为它提供一整堆磁盘设备,而不仅仅是一个。ZFS 存储系统的核心是 zpool——这是 ZFS 存储的最基本级别。在zpool 又包含vdevs,并vdevs 包含在其中,实际硬盘。写入被分成称为records 或 的单元blocks,然后在 之间半均匀地分布vdevs。
存储vdev 可以是五种类型-单个磁盘,镜子,一个 RAIDz1,RAIDz2或RAIDz3。您可以vdevs 向 a添加更多 磁盘zpool,也可以attach向单个磁盘或镜像添加更多磁盘vdev。但是以这种方式管理存储需要一些提前计划和预算——业余爱好者和家庭实验室通常不太热衷。
常规 RAID,它不与 ZFS 共享“池”概念,通常提供扩展和/或重构阵列的能力。例如,您可以将单个磁盘添加到六磁盘RAID6 阵列,从而将其变成七磁盘RAID6 阵列。进行实时重塑可能会非常痛苦,尤其是在几乎完整的阵列上;完全有可能这样的任务可能需要一周或更长时间,而阵列性能在整个时间内都被限制在正常情况的四分之一或更少。
从历史上看,ZFS 避免了这种扩展。ZFS 最初是为商业用途而开发的,实时阵列整形在商业世界中通常是行不通的。连续几天将存储性能降低到无法使用的水平通常比购买一套全新的硬件需要更多的工资和管理费用。实时扩展也可能非常危险,因为它涉及读取和重新写入所有数据,并将数组置于临时且远未经过充分测试的“一半这个,一半那个”条件中,直到它完成。
对于拥有许多磁盘的用户来说,新的RAIDz 扩展不太可能实质性地改变他们使用 ZFS 的方式。vdevs 作为一个完整的单元进行管理,而不是试图在它们内部乱搞,仍然会更容易也更实用。但是,使用单个运行 ZFS 的爱好者、家庭实验室和小用户vdev 可能会从新功能中获得很多好处。
它是如何工作的?
从实用的角度来看,Ahrens 的新vdev 扩展特性只是在现有命令上增加了新的功能,即 ,zpool attach通常用于将磁盘添加到单个磁盘vdev (将其变成mirror vdev)或向 a 中添加额外的磁盘mirror (用于例如,将两盘mirror 变成三盘mirror)。
使用新代码,您还可以将attach 新磁盘添加到现有RAIDz vdev。这样做会扩展 vdev 的宽度但不会更改vdev 类型,因此您可以将 6 个磁盘的RAIDz2 vdev 变成一个 7 个磁盘的RAIDz2 vdev,但不能将其变成一个 7 个磁盘的vdev RAIDz3。
发出您的zpool attach 命令后,扩展就开始了。在扩展期间,每个block orrecord 从vdev 被扩展的被读取然后被重写。重写的扇区block 分布在 中的所有磁盘中vdev,包括新磁盘,但条带本身的宽度不会改变。因此,RAIDz2 vdev 从六个磁盘扩展到十个磁盘在扩展完成后仍将充满六个宽的条带。
因此,虽然用户会看到新磁盘提供的额外空间,但扩展数据的存储效率不会因新磁盘而提高。在上面的示例中,我们从RAIDz2 标称存储效率为 67%(每六个扇区中有四个是数据)的六磁盘变为十磁盘RAIDz2。数据 新写入十盘RAIDZ2已经每10个行业的80%个标称存储效率是数据,但旧的扩展数据仍然写在六宽条纹,所以它仍然有旧67%的存储效率.
值得注意的是,对于 vdev 来说,这并不是一个意外或奇怪的状态——RAIDz 已经使用动态、可变的条带宽度来解决blocks 或records 太小而无法在单个vdev.
例如,如果您编写单个元数据块(包含文件名、权限和磁盘位置的数据),则它适合磁盘上的单个元数据块sector 。如果将该元数据块写入 10-wide RAIDz2,则不会写入完整的 10-wide 条带,而是写入一个block 仅三个磁盘宽的小块;单个数据sector加两个奇偶校验sectors。因此,blocks 新扩展的RAIDz vdev 中的“尺寸过小”不会让 ZFS 感到困惑。他们只是在办公室的另一天。
是否有任何持久的性能影响?
正如我们上面所讨论的,新扩展的RAIDz vdev看起来不太像从“出生”开始就以这种方式设计的——至少,一开始不是。虽然混合了更多的磁盘,但数据的内部结构并没有改变。
添加一个或多个新磁盘vdev 意味着它应该能够具有更高的吞吐量。即使遗留的blocks 不跨越整个宽度vdev,增加的磁盘意味着更多的心轴来分配工作。不过,这可能不会带来令人瞠目结舌的速度提升——七个磁盘上的六个宽条纹vdev 意味着您仍然无法blocks 同时读取或写入两个,因此任何速度提升都可能是微不足道的。
对性能的净影响可能难以预测。例如,如果您要从 6 个磁盘扩展RAIDz2 到 7 个磁盘RAIDz2,那么您原来的 6 个磁盘配置不需要任何填充。一个 128KiBblock 可以平均切割成四个 32KiB 的数据块,两个 32KiB 的奇偶校验块。分割在七个磁盘中的相同记录 需要填充,因为 128KiB/五个数据片段不会输出到偶数个扇区。
同样,在某些情况下(尤其是小 磁盘recordsize 或volblocksize磁盘组),在较旧、较窄的布局中,每个单独磁盘的工作负载可能比在较新、较宽的布局中更具挑战性。例如,block 将一个 128KiB分成 32KiB 块用于 6 宽的磁盘可以比分成 16KiB 块用于 10 宽的磁盘RAIDz2更有效地读取或写入 ,因此,如果更多的磁盘但更小的块将提供更多的磁盘,这有点废话比更少的磁盘更多的吞吐量,但更大的块确实如此。RAIDz2
您可以确定的一件事是,新扩展配置的性能通常应该与原始非扩展版本一样好——而且一旦大部分数据以新宽度(重新)写入,扩展配置vdev 将无法执行与从一开始就以这种方式设计的方式不同,或者不那么可靠。
为什么不在扩展期间重塑记录/块?
最初的扩展过程在运行时没有将所有现有的内容重写blocks 为新的宽度,这似乎很奇怪——毕竟,它无论如何都在读取和重写数据,对吧?我们问阿伦斯为什么保留原来的宽度,答案归结为“这样更容易、更安全”。
要认识到的一个关键因素是,从技术上讲,扩张 并没有移动blocks;它只是在移动sectors。按照它的编写方式,扩展代码不需要知道 ZFS 的逻辑block 边界在哪里——扩展例程不知道一个人sector 是奇偶校验还是数据,更不用说block 它属于哪个了。
扩展可以遍历所有block指针来定位block 边界, 然后 它会知道哪个sector 属于什么block 以及如何重新塑造block. 扩展需要不断更新spacemaps 的metaslabs ,以考虑在磁盘上的每个大小的变化block-和如果block 是的一部分dataset ,而不是一个zvol,更新每个数据集以及每个文件的空间占为好。
如果知道您在新的 5 宽 vdev 上有 4 宽条纹真的让您感到牙痒,那么您可以在扩展完成后自己读取和重写数据。要做到这一点,最简单的方法是使用zfs snapshot,zfs send和zfs receive 复制整个datasets和zvols。如果您不担心 ZFS 属性,一个简单的mv 操作就可以解决问题。
但是,我们建议在大多数情况下只是放松并让 ZFS 做它的事情。您blocks 从旧数据中获得的尺寸过小并没有真正伤害任何东西,并且当您在vdev.由于一次性读取和重写所有内容而导致的高存储负载。
RAIDz 扩展何时投入生产?
Ahrens 的新代码尚未包含在任何 OpenZFS 版本中,更不用说添加到其他任何人的存储库中了。我们询问了 Ahrens 我们什么时候可以看到生产中的代码,不幸的是,这需要一段时间。
RAIDz 扩展包含在即将发布的 OpenZFS 2.1 版本中为时已晚,预计很快(2.1 候选版本 7 现在可用)。它应该包含在下一个主要的 OpenZFS 版本中;现在确定具体日期还为时过早,但主要版本通常每年大约发布一次。
从广义上讲,我们预计 RAIDz 扩展将在 2022 年 8 月左右在 Ubuntu 和 FreeBSD 之类的产品中投入生产,但这只是猜测。TrueNAS 很可能会比这更早将其投入生产,因为 ixSystems 倾向于在 ZFS 功能正式达到发布状态之前从 master 中提取。