ZFS简介

2020-11-21 12:13:30

近年来,ZFS变得越来越流行。 Linux(ZoL)上的ZFS推动了极限,并使许多新手接触到ZFS折叠。 iXsystems已将更新的代码库(现在称为OpenZFS)纳入TrueNAS CORE的代码库。本文的目的是帮助那些了解ZFS但尚未有机会对其进行研究的人们。

我们的希望是让您更好地了解它的工作方式以及工作方式。知识是决策过程的关键,我们认为ZFS对于大多数组织来说都是值得考虑的事情。

ZFS是一个文件系统,但与大多数其他文件系统不同,它也是逻辑卷管理器或LVM。这意味着ZFS不仅直接控制文件的位和块在硬盘上的存储方式,而且还控制为RAID和冗余目的在逻辑上排列硬盘的方式。 ZFS也被归类为写时复制或COW文件系统。这意味着ZFS可以做一些很酷的事情,例如快照,而NTFS这样的普通文件系统则做不到。快照可以听起来像是声音,是某个时间点的照片。但是,COW文件系统的工作方式具有一些重要的含义,我们需要讨论。

硬盘的工作方式是将数据片段存储在逻辑块地址或LBA中。 ZFS知道特定文件存储在哪些LBA中。假设我们需要编写一个足以容纳3个块的文件。我们将把该文件存储在LBA 1000、1001和1002中。这被视为顺序写入,因为所有这些块都直接相邻存储。对于旋转硬盘驱动器,这是理想的选择,因为写入头不必移出其所在的轨道。

现在,假设我们对文件进行了更改,并且需要修改LBA 1001中存储的零件。当我们写入更改时,ZFS不会覆盖存储在1001中的文件部分。相反,它将把该块写入LBA2001。LBA1001将保持原样,直到将其保留在快照上为止。这样,我们既可以存储文件的当前版本,也可以拥有前一个版本,同时仅存储差异。但是,下次我们回读该文件时,旋转硬盘驱动器的读取头需要读取LBA 1000,转到存储LBA 2001的轨道,然后再回到LBA 1002的轨道。被储存了。这种现象称为碎片。

为了使ZFS池更易于理解,我们将着重于使用小型存储容器,因为您可能在家中或商店附近都有。在继续之前,值得定义一些术语。 VDEV或虚拟设备是一个或多个存储设备的逻辑分组。因此,池是由1个或多个VDEV构建的逻辑定义的组。 ZFS是非常可定制的,因此,VDEV有许多不同类型的配置。您可以通过可视化以下图形来思考ZFS池的构造:

从最小的容器大小开始,我们有驱动器。我们可以看到,在此可视化中,每个较大的容器中都有两个驱动器。这两个较大的容器是我们的VDEV。那么,最大的容器就是我们的游泳池。在这种配置中,我们将每对驱动器放在一个镜像中。这意味着一个驱动器可能在一个(或两个!)VDEV中发生故障,并且该池将继续在降级状态下运行。

但是,如果单个VDEV中有2个驱动器,则整个池中的所有数据都会丢失。池本身没有冗余,ZFS中的所有冗余都在VDEV层中。如果一个VDEV发生故障,则没有足够的信息来重建丢失的数据。

接下来,我们需要定义什么是RAID-Z以及什么级别的RAID-Z。 RAID-Z是一种将多个驱动器放到VDEV中并存储奇偶校验或容错能力的方法。在ZFS中,没有像Unraid中一样的专用``奇偶校验驱动器'',而是在VDEV中的所有驱动器之间存储了奇偶校验。分布在驱动器上的奇偶校验量决定了RAID-Z的级别。这样更类似于传统的硬件RAID。

与镜像配置相比,可以使RAID-Z更好的方法是,RAID-Z中的哪个驱动器发生故障都没有关系。每个驱动器都是平等的伙伴,而在镜像配置中,每个镜像的VDEV是一个单独的实体。 RAID-Z的这一优势是以性能为代价的,但是镜像池几乎总是比RAID Z更快。

RAID-Z与传统RAID 5相似。在RAID-Z中,您有一个值得奇偶校验的驱动器。换句话说,如果丢失一个驱动器,则池将继续运行。对于RAID-Z,每个VDEV至少需要3个驱动器。 RAID-Z VDEV中可以有3、7甚至12个驱动器。但是,您添加的驱动器越多,重新进行银色或重建所需的时间就越长。

时间的增加会增加数据的风险,因为在此过程中第二次驱动器故障会破坏您的池。当数据仍在使用时,ZFS将重新同步,这是实时恢复。这意味着在此过程中,我们的磁盘工作得比平时更努力,这会增加第二个驱动器发生故障的机会。当您从VDEV的现有成员读取所有奇偶校验数据并将其写入新磁盘时,您的数据仍可访问并处于生产状态。

RAID-Z2 VDEV更类似于RAID6。在此配置中,所有设备上均存储了2个值得奇偶校验的驱动器。每个VDEV最多可能丢失两个驱动器,并且池仍将运行。添加更多的奇偶校验驱动器会增加所需的计算量,这意味着您需要更高的处理性能才能操作阵列。

最后,RAID-Z3 VDEV提供了三个值得奇偶校验的驱动器,因此每个VDEV最多可以丢失三个驱动器,并且池仍将运行。但是,添加的奇偶校验驱动器越多,最终性能就越慢。您至少需要四个驱动器,但至少应使用五个驱动器来构建RAID-Z3 VDEV。

我们可以通过两种方式来测量速度或牢固度:IOPS和吞吐量。在RAIDZ中,更多的驱动器将为您提供更大的吞吐量,或您在传输文件时看到的实际读写速度。但是,如果您曾经尝试在Windows中同时运行多个文件副本,则可能会注意到执行的次数越多,获取的速度就越慢。它并不总是以恒定的速度变慢,您尝试做的磁盘越多,速度将成指数地变慢。这是因为您的磁盘每秒只能执行这么多的输入/输出操作,即IOPS。

RAIDZ将随着您添加的更多磁盘来扩展吞吐量,但不会与IOPS一起扩展。通常,这意味着RAIDZ并不是传统上用于I / O密集型工作负载的最佳选择,因为如果我们排除所有ZFS缓存,IOPS的数量将大致限于VDEV中最慢的成员。正如我们在此处讨论的,虚拟化高度依赖于I / O。

之前,我们讨论了ZFS是COW文件系统,因此它遭受数据碎片的困扰。这个事实直接影响性能。您的池越“满”,它将最终变得越慢。 ZFS中的写入速度直接与要写入的相邻空闲块的数量有关。随着池的填充和数据片段的增加,彼此相邻的块越来越少。单个大文件可能会跨越硬盘表面散布的块。即使您希望该文件是顺序写入,但如果驱动器已满,它就不再可能。

在上图中,我们可以看到我在CrystalDiskMark中测试的Seagate 1TB移动驱动器。它可以执行大约130 MB / s的顺序读取和写入。我们还可以看到,当我们开始执行随机4k I / O时,速度下降了大约100倍。这旨在说明数据分段对性能的影响。此外,我们可以看到这些查找的延迟可能需要大约半秒,并且我们限制为大约350 IOPS。为了提高速度,传统硬盘驱动器上的虚拟化工作负载需要具有多个磁盘,以弥补这种缓慢性。看到一个由10个或更多镜像驱动器的VDEV构成的池的情况并不少见。

此外,我们可以从ZFS社区中借鉴一些智慧。随着您的池已满,并且由于碎片而导致连续写入变得越来越困难,它将以非线性方式减慢速度。根据一般经验,大约50%的容量将比10%的容量慢。在大约80%-96%的容量下,您的池开始变得非常缓慢,ZFS实际上将更改其写入算法以确保数据完整性,从而进一步降低速度。

这就是SSD的用武之地。它们从根本上改变了游戏,因为它们在物理层上的工作方式大不相同。他们没有读写磁头在旋转的磁盘上来回移动来查找数据。借助基于磁盘的驱动器的物理限制,SSD可以更快地读取和写入非顺序数据。他们没有遭受这些规则的惩罚那么严重,分散不会在相同程度上损害他们的表现。

在过去的几十年中,硬盘的容量得到了突飞猛进的增长。我们已经看到硬盘驱动器的容量已经从1 GB增长了,就在去年Western Digital宣布2020年将有18 TB和20 TB的驱动器出现。不变的是它们的I / O能力。新旧硬盘仍然受到物理限制。即使是那些新怪物,也只能真正执行约400次左右的随机IOPS,仅是这些年前的四倍。上图所示的Samsung 970 EVO plus可以完成超过14,000个操作。

如果我们收到足够的反馈,则可以在另一篇文章中讨论ZFS的进一步调优性能。

最后,我们需要简要探讨一些有关基础存储配置的主题。在Windows计算机中,如果插入新的硬盘驱动器或闪存驱动器,则需要对其进行格式化并为其分配驱动器号,然后才能使用它。同样,在ZFS中完成创建Pool时,需要创建一个数据集才能真正开始使用它。格式化闪存驱动器时,Windows要求您指定分配单位大小。

在ZFS中,此术语称为“记录大小”。该值表示块的最大大小。块将数据片段组装成逻辑分组。在TrueNAS Core中,您可以在池级别上定义记录大小。其子数据集将继承您在“池”中设置的记录大小,或者在创建它时也可以指定其他记录大小。此外,您可以随时修改记录大小。但是,这样做只会影响新数据,因为它会写入池中,而不会影响任何现有数据。

TrueNAS Core默认创建记录大小为128k的数据集。这是一个全面的决定。根据您的工作流程,您可能希望增加或减少此值。例如,如果您正在运行数据库服务器,则将值设置为较小的数字会更有意义。在该示例中,记录大小为4k,可以将数据库中的每个事务直接写入磁盘,而不必等待以默认配置填充整个128k记录。一般而言,较小的记录提供较低的延迟,而较大的记录提供较高的总体吞吐量。

一个128k的记录大小跨越4k本地硬盘驱动器上的32个扇区。扇区是存储难题中最底层的部分。这是我们要遍历的存储介质内部数据的物理实施方式中最接近的内容。

ZFS需要了解此信息,以便就如何向磁盘读取和写入数据做出明智的决定。您可以通过提供偏移值来告诉它扇区大小是多少。 TrueNAS Core在为您自动执行此操作方面做得很好。大多数现代磁盘的扇区大小为4k。对于这些驱动器,ZFS的偏移值为12。对于较旧的512b驱动器,偏移值为9。

对于某些固态硬盘,故事变得混乱。他们向操作系统报告它们是4k驱动器时,实际上,它们在内部用作8k驱动器。这些设备将要求您手动分配ashift值,并且应使用13。如果不确定,最好将其设置为过高而不是过低。偏差值太小会削弱性能。

ZFS自适应替换缓存或ARC是一种将文件缓存在系统内存中的算法。这种类型的缓存是读缓存,对写性能没有直接影响。在传统的文件系统中,使用LRU或最近最少使用的缓存。缓存的工作方式是,如果您在计算机上打开文件,它将把该文件放入缓存中。如果然后关闭然后重新打开,文件将从缓存而不是硬盘驱动器加载。

LRU缓存将首先从缓存中逐出最近最少使用的项目。我们说的文件是一个Excel电子表格。假设您已打开该文件并将其保存在缓存中。这个Excel文件是您在整个工作日中经常访问的文件。您进行更改,然后将其关闭以在PowerPoint上工作并写一些电子邮件,LRU缓存可能会用完空间并从缓存中逐出Excel文件。因此,当您在当天晚些时候再次打开它时,必须从磁盘加载它,而不是从缓存中读取它。缓存通常比Office文档大得多,但是我们将其用作概念性示例。

ARC与此不同之处在于,它考虑了最近的迁离历史。每次从ARC撤出文件时,都会记录该事件。该算法将权衡这些日志以及之前已撤出但又在缓存中的文件,但优先级较低,因此可以再次撤出它们。

级别2 ARC或L2ARC是ZFS ARC的扩展。如果将文件从ARC逐出,则将其移到L2ARC而不是被删除。 L2ARC驻留在一个或多个磁盘上,而不是系统内存中。由于RAM昂贵,因此此功能是扩展缓存功能的有用方法。随着NVMe和Optane的出现,可以实现相对较高的速度和较大的缓存。但是,这是有代价的。由于ARC需要知道这些文件存储在L2ARC中,因此它必须将该信息存储在RAM中。

根据Oracle员工在Reddit上的帖子,计算ARC标头映射的公式为:

(L2ARC大小以字节为单位)/(ZFS记录大小以字节为单位)* 70字节= ARC标头大小以字节为单位

因此,让我们对这一点有所了解。我们将使用TrueNAS默认的128Kb块和256GB NVME SSD作为L2ARC。

对于低端VM存储盒来说,这将是一个非常常见的配置选择。如果您的系统中只有16GB或RAM,则所有L2ARC映射都将浪费ARC空间,而整个系统其余部分将只有2GB。对于256GB的L2ARC,您至少需要32GB的内存。建议使用64GB。

我们希望将数据缓存在ARC和L2ARC中,这是一种分层方法。以上比较试图说明这一事实。即使使用软件RAMDisk驱动程序,我的PC相对较慢的DDR4 2400也比1TB三星PM981快3倍。过去的经验是,L2ARC的内存通常不超过RAM的5倍。

这里的最终目标是防止我们的池必须尽我们所能进行多次读取。尽管ARC不直接缓存写入,但它可以使驱动器不必从磁盘中不断读取数据,从而可以提高写入性能。

在解释ZIL是什么或SLOG做什么之前,我们必须首先解释什么以及如何将数据写入ZFS池。写入磁盘时,它必须首先通过创建事务组或TXG的系统内存。然后,ZFS会将这些数据异步提交到池中,这意味着没有检查/余额来确保数据成功到达池中。如果发生崩溃或电源故障,将发生损坏,并且您将丢失正在写入的数据。

ZFS还可以同步写入数据块。您可以通过在池中设置“ sync = always”标志来强制ZFS执行此操作。除上述内容外,同步写入还会将写入与系统内存并行地提交到ZIL或ZFS Intent Log。如果正常的TXG成功写入您的池,则ZIL中的数据将被删除。如果系统崩溃或电源中断,数据将保留在ZIL中。由于系统内存是易失性的,而我们的ZIL则不是,因此可以将其视为写提交的保险政策。但是,您的写入速度现在与ZIL的速度有关。

默认情况下,ZIL位于您的池中,但位于逻辑上分开的位置。它只能在一种情况下读取。如果发生崩溃或电源故障。每次重新启动系统时,都必须先重新导入ZFS池,然后再继续。重新导入池后,ZFS将查看是否有任何剩余数据写入ZIL。如果存在,那意味着存在尚未提交到磁盘的写操作。然后它将读取该数据并将其作为新的TXG提交到您的池中。

这意味着通过同步写入,您的数据将两次写入池中的磁盘。这称为写放大,它将减慢对池的所有写提交到爬网的速度。同步写入的成本很高,将写入性能降低一半或更多。

这是SLOG的来源,SLOG是一个单独的硬件,充当ZIL的专用场所。具有单独的硬件可防止对池的写放大作用。它还允许您将ZIL放在速度更快的设备上。这很重要,因为您的写入仍将受到SLOG速度的限制。这些事务对磁盘延迟特别敏感,磁盘延迟比SLOG设备的吞吐量或IOPS更重要。出于这个原因,当需要同步写入时,我们建议使用Intel Optane。

值得注意的是ZIL不是ZFS写缓存!即使使用同步写入时,即使使用SLOG,异步写入也会使池的写入速度始终更快。如果您认为自己的数据足够敏感,需要进行同步写入,请购买SLOG。

在本文中,我们花了一些时间讨论有关ZFS的关键概念。我们希望我们已经帮助提供了必要的知识和参考,以帮助您入门ZFS。当您去建立一个实验室,或者当您去竞购一个新的存储解决方案时,开源是一个巨大的资源,应该考虑。

我们没有涵盖所有内容。特殊分配类是OpenZFS的功能,它们使您可以使用闪存在旋转驱动器上加速元数据。此外,您可以使用它们来获得性能更好的重复数据删除。这仍然是OpenZFS的一项新功能,我们尚未对其可行性或价值进行过测试或审查。

此外,ZFS可以进行即时压缩,具有本机加密支持,并且正在积极开发大量新功能。我们希望随着对ZFS的介绍,随着新事物的到来,在将来围绕ZFS提供更多的内容。

如果您想在实验室中付诸实践,请查看我们的系列文章,从构建实验室第1部分,使用TrueNAS和VMWare ESXi计划开始。