ZFS 不仅仅是一个文件系统,它在根本上是不同的。ZFS 结合了文件系统和卷管理器的角色,使新的存储设备能够添加到活动系统中,并立即在该池中的现有文件系统上提供新的空间。通过结合传统上分开的角色,ZFS 能够克服以往的限制,使 RAID 组能够扩展。vdev 是池中的顶级设备,可以是简单的磁盘,也可以是镜像或 RAID-Z 阵列等 RAID 转换。ZFS 文件系统(称为数据集)各自可以访问整个池的合并空闲空间。从池中使用的块会减少每个文件系统可用的空间。这种方法避免了广泛分区常见的问题,即空闲空间在分区之间变得分散。
池 | 存储池是 ZFS 的最基本构建块。池由一个或多个 vdev 组成,这些是存储数据的基础设备。然后使用池来创建一个或多个文件系统(数据集)或块设备(卷)。这些数据集和卷共享剩余空间的池。每个池通过名称和 GUID 唯一标识。池上的 ZFS 版本号确定可用的功能。 |
---|---|
vdev 类型
一个池由一个或多个 vdev 组成,它们本身是单个磁盘或一组磁盘,转换为 RAID。当使用大量的 vdev 时,ZFS 会在 vdev 之间分布数据,以提高性能并最大化可用空间。所有 vdev 的大小必须至少为 128 MB。 * 磁盘 - 最基本的 vdev 类型是标准块设备。这可以是整个磁盘(例如/dev/ada0 或/dev/da0)或分区(/dev/ada0p3)。在 FreeBSD 上,使用分区而不是整个磁盘不会导致性能损失。这与 Solaris 文档中的建议不同。
事务组(TXG)
事务组是 ZFS 将块更改组合在一起并将其写入池的方式。事务组是 ZFS 用来确保一致性的原子单元。ZFS 为每个事务组分配一个唯一的 64 位连续标识符。最多可以同时存在三个活动事务组,每个事务组处于以下三种状态之一: * 打开 - 新事务组以打开状态开始并接受新的写入。始终会有一个事务组处于打开状态,但是如果达到限制,该事务组可能会拒绝新的写入。如打开事务组达到限制,或达到 vfs.zfs.txg.timeout,事务组将进入下一个状态。* 静止 - 一个能让任何挂起操作完成而不阻塞创建新打开事务组的短暂状态。若组中的所有事务完成,事务组将进入最终状态。* 同步 - 将事务组中的所有数据写入稳定存储。此过程将反过来改变其他数据,例如元数据和空间映射,ZFS 也会将其写入稳定存储。同步过程包括几个步骤。在第一个和最重要的步骤中,写入所有更改的数据块;接下来是元数据,可能需要几个步骤才能完成。由于为数据块分配空间会生成新的元数据,因此在不使用任何新空间的步骤完成之前,同步状态无法完成。同步状态也是同步任务完成的地方。同步任务是创建或销毁快照和数据集等管理操作,完成 uberblock 更改。若同步状态完成,处于静止状态的事务组将进入同步状态。所有管理功能,例如 snapshot,都作为事务组的一部分写入。ZFS 将创建的同步任务添加到打开事务组中,并尽可能快地使此组进入同步状态以减少管理命令的延迟。
自适应替换缓存(ARC)
ZFS 使用自适应替换缓存(ARC),而不是更传统的最近最少使用(LRU)缓存。LRU 缓存是一个简单的列表,按照对象最近使用的顺序排序,将新项目添加到列表的头部。当缓存满时,从列表的尾部逐出项目,为更活跃的对象腾出空间。ARC 由四个列表组成;最近使用(MRU)和最常使用(MFU)的对象,以及每个的幻影列表。这些幻影列表跟踪被逐出的对象,以防止将它们再次添加到缓存中。这通过避免那些有时使用历史的对象来增加缓存命中率。同时使用 MRU 和 MFU 的另一个优点是,扫描整个文件系统将会优先考虑最近访问的内容,从而逐出所有数据从 MRU 或 LRU 缓存。有 ZFS,还有一个跟踪最常使用对象的 MFU,并保持最常访问块的缓存。
L2ARC
L2ARC 是 ZFS 缓存系统的第二级。RAM 存储主要的 ARC。由于可用 RAM 数量通常有限,ZFS 也可以使用缓存 vdevs。固态硬盘(SSD)通常被用作这些缓存设备,因为它们与传统旋转硬盘相比速度更快、延迟更低。L2ARC 完全可选,但有一个将会增加来自 SSD 的缓存文件的读取速度,而不必从常规硬盘中读取。L2ARC 还可以加速去重,因为一个不适合 RAM 但适合 L2ARC 的去重表(DDT)比必须从磁盘中读取的 DDT 要快得多。对加入缓存设备的数据率的限制可以防止因多余写操作而过早磨损 SSD。直到缓存满了(用来腾出空间的第一个块),写入 L2ARC 的速度将限制在写入限制和增加限制的总和上,之后将限制在写入限制上。一对 sysctl(8)值控制这些速度限制。vfs.zfs.l2arc_write_max 控制每秒写入缓存的字节数,而 vfs.zfs.l2arc_write_boost 在“Turbo 热身阶段”(写入增强)期间增加到此限制。
ZIL
ZIL 通过使用像 SSD 这样比主存储池中使用的设备更快的存储设备来加速同步事务。当应用程序请求同步写入(确保数据存储到磁盘而不仅仅是缓存以备后续写入),先将数据写入更快的 ZIL 存储,然后再将其刷新到常规硬盘上,极大地减少延迟并提高性能。像数据库这样的同步工作负载将单独受益于 ZIL。常规的异步写入(如复制文件)根本不会使用 ZIL。
写时复制
与传统文件系统不同,ZFS 会写入一个不同的块,而不是直接覆盖原来的数据。在完成这次写入时,元数据会更新,指向新的位置。当发生短写入(文件写入过程中系统崩溃或断电)时,文件的整个原始内容仍然可用,而 ZFS 会丢弃未完成的写入。这也意味着 ZFS 在意外关机后不需要运行 fsck(8)进行文件系统检查。
数据集
数据集是 ZFS 文件系统、卷、快照或克隆的通用术语。每个数据集都有一个格式为 poolname/path@snapshot 的唯一名称。池的根也是一个数据集。子数据集具有层次结构的名称,类似于目录。例如,mypool/home,也就是 home 数据集,是 mypool 的子数据集,并继承了它的属性。通过创建 mypool/home/user 进一步扩展。这个孙数据集将继承父数据集和祖父数据集的属性。在子数据集上设置属性以覆盖从父数据集和祖父数据集继承的默认值。可以将数据集及其子数据集的管理委托出去。
文件系统
ZFS 数据集通常用作文件系统。与大多数其他文件系统一样,ZFS 文件系统在系统目录层次结构中某个位置挂载,并包含具有自身权限、标志和其他元数据的文件和目录。
卷
ZFS 也可以创建卷,它们显示为磁盘设备。卷具有许多与数据集相同的功能,包括写时复制、快照、克隆和校验。卷可用于在 ZFS 之上运行其他文件系统格式,例如 UFS 虚拟化,或者导出 iSCSI 扩展。
快照
ZFS 的写时复制 (COW) 设计能让几乎瞬间生成一致的、具有任意名称的快照。在对数据集进行快照或对包含所有子数据集的父数据集进行递归快照后,新数据写入新块,但不会将旧块回收为自由空间。快照包含原始文件系统版本,活动文件系统包含自快照以来所做的任何更改,而不使用其他空间。写入活动文件系统的新数据使用新块来存储这些数据。随着块在活动文件系统中不再使用,在快照中会增长。将这些快照以只读方式挂载使得可以恢复先前的文件版本。可以将活动文件系统回滚到特定快照,从而撤消快照后发生的任何更改。池中的每个块都有一个引用计数器,用于跟踪使用该块的快照、克隆、数据集或卷。随着文件和快照被删除,引用计数减少,当不再引用块时,就回收自由空间。对快照标记保留会导致任何销毁尝试返回一个 EBUSY 错误。每个快照可以具有唯一名称的保留。释放命令将移除保留,以便可以删除快照。快照、克隆和回滚可用于卷,但独立挂载不可进行。
复刻
复刻快照也是可能的。克隆是快照的可写版本,能让文件系统分叉为新数据集。与快照一样,克隆最初不会消耗新空间。当新数据写入克隆时使用新块,克隆的大小会增长。当在克隆文件系统或卷中覆盖块时,先前块上的引用计数会减少。删除克隆依赖的快照是不可能的,因为克隆依赖于它。快照是父级,克隆是子级。克隆可以被提升,颠倒这种依赖关系,使克隆成为父级,先前的父级成为子级。此操作不需要新空间。由于父级和子级使用的空间量相反,可能会影响现有的配额和保留。
校验和
每个块也都经过了校验和。所使用的校验和算法是每个数据集的属性,请参阅 set。在读取时透明地验证每个块的校验和,使得 ZFS 能够检测到静默损坏。如果读取的数据与期望的校验和不匹配,ZFS 将尝试从任何可用的冗余数据(如镜像或 RAID-Z)中恢复数据。通过 scrub 触发所有校验和的验证。校验和算法包括: * fletcher2 * fletcher4 * sha256 fletcher 算法速度更快,但 sha256 是一种强大的加密哈希,具有更低的碰撞几率,但性能会有所降低。可以停用校验和,但强烈不建议这样做。
压缩
每个数据集都有一个压缩属性,默认值为关闭。将此属性设置为一个可用的压缩算法。这会导致对写入数据集的所有新数据进行压缩。除了减少使用的空间外,读取和写入吞吐量通常会增加,因为需要读取或写入的块更少。 * LZ4 - 添加在 ZFS 池版本 5000(特性标志)中,LZ4 现在是推荐的压缩算法。在处理可压缩数据时,LZ4 的速度大约比 LZJB 快 50%,在处理不可压缩数据时,速度是 LZJB 的三倍以上。LZ4 的解压速度也比 LZJB 快大约 80%。在现代 CPU 上,LZ4 通常可以以超过 500 MB/s 的速度压缩,并以超过 1.5 GB/s 的速度解压(每个单个 CPU 核心)。 * LZJB - 默认的压缩算法。由 Jeff Bonwick(ZFS 的原始创建者之一)创建。与 GZIP 相比,LZJB 提供了良好的压缩效果,CPU 开销较小。在未来,默认的压缩算法将更改为 LZ4。 * GZIP - ZFS 中提供的流压缩算法,非常流行。使用 GZIP 的主要优势之一是其可配置的压缩级别。在设置 compress 属性时,管理员可以选择压缩级别,从 gzip1 最低级别的压缩到 gzip9 最高级别的压缩。这使管理员可以控制要用多少 CPU 时间来换取节省的磁盘空间。 * ZLE - 零长度编码是一种特殊的压缩算法,仅压缩连续的零。当数据集包含大块零时,这种压缩算法非常有用。
复制
当设置为大于 1 的值时,copies 属性指示 ZFS 在文件系统或卷中维护每个块的副本。在重要数据集上设置此属性可以提供额外的冗余,用于恢复与其校验和不匹配的块。在没有冗余的池中,副本功能是唯一的冗余形式。副本功能可以从单个坏扇区或其他形式的轻微损坏中恢复,但它不能保护池免受整个磁盘的损失。
重复消除
校验和使在写入数据时检测重复块成为可能。使用重复消除时,现有相同块的引用计数会增加,节省存储空间。ZFS 在内存中保留一个重复消除表(DDT)来检测重复块。该表包含一组唯一的校验和、这些块的位置以及引用计数。在写入新数据时,ZFS 会计算校验和并将其与列表进行比较。当找到匹配时,它将使用现有块。使用 SHA256 校验和算法与重复消除提供安全的密码哈希。重复消除是可调的。如果 dedup 是 on,那么匹配校验和意味着数据相同。将 dedup 设置为 verify,ZFS 对数据执行逐字节检查,确保它们实际上是相同的。如果数据不相同,ZFS 会记录哈希冲突并将这两个块分开存储。由于 DDT 必须存储每个唯一块的哈希值,它会消耗大量内存。一个经验法则是每 1 TB 的重复消除数据需要 5-6 GB 的内存)。在实际情况下不可能有足够的 RAM 将整个 DDT 保存在内存中时,性能将大大受到影响,因为 DDT 必须在写入每个新块之前从磁盘中读取。重复消除可以使用 L2ARC 来存储 DDT,提供了快速系统内存和较慢磁盘之间的折衷方案。考虑使用压缩替代,通常可以提供几乎相同的空间节约,而不增加内存。
擦洗
与 fsck(8) 这样的一致性检查不同,ZFS 使用 scrub。scrub 读取存储在池中的所有数据块,并根据存储在元数据中的已知好校验和验证它们的校验和。对池中存储的所有数据进行定期检查可确保在需要时恢复任何已损坏的块。不需要在发生非正常关闭后进行擦洗,但至少每三个月最好练习一次。ZFS 在正常使用过程中验证每个块的校验和,但擦洗会确保甚至检查不经常使用的块是否存在静默损坏。ZFS 在档案存储情况下改善数据安全性。调整 scrub 的相对优先级以防止擦洗降低池中其他工作负载的性能。
数据集配额
ZFS 提供快速准确的数据集、用户和组空间账户以及配额和空间保留。这使得管理员可以对空间分配进行精细控制,并能让为关键文件系统保留空间。 ZFS 支持不同类型的配额:数据集配额、引用配额(refquota)、用户配额和组配额。 配额限制数据集及其后代的总大小,包括数据集的快照、子数据集以及这些数据集的快照。
--
-----------------------------------------------------------------------------------------
参考配额
参考配额限制数据集可以消耗的空间量,通过强制执行一个硬限制。该硬限制仅包括数据集本身引用的空间,不包括后代使用的空间,如文件系统或快照。
用户配额
用戶配額有助於限制指定用戶使用的空間量。
群組配額
群組配額限制了指定群組可以消耗的空間量。
数据集保留
reservation 属性使得可以为特定数据集及其后代保证一定量的空间。这意味着在 storage/home/bob 上设置一个 10 GB 的保留空间,阻止其他数据集使用完所有的可用空间,至少为这个数据集保留 10 GB 的空间。与常规的 refreservation 不同,快照和后代所使用的空间不计入保留空间。例如,如果在 storage/home/bob 上创建快照,则除了 refreservation 之外还必须具有足够的磁盘空间才能使操作成功。主数据集的后代不计入 refreservation 的空间,并且不会侵占所设置的空间。 任何类型的保留在诸如规划和测试新系统中磁盘空间分配的适用性,或确保文件系统中有足够的空间用于音频日志或系统恢复程序和文件等情况下都是有用的。
参考预留
refreservation 属性使得可以为特定数据集保证一定空间,而不包括其后代。这意味着在 storage/home/bob 上设置 10 GB 的保留空间,另一个数据集尝试使用空闲空间时,为该数据集保留至少 10 GB 的空间。与普通的保留不同,快照和后代数据集使用的空间不计入保留空间。例如,如果对 storage/home/bob 拍摄快照,必须存在其他大于 refreservation 的磁盘空间才能成功进行操作。主数据集的后代不计入 refreservation 的空间,因此不会侵占设置的空间。
重新同步
当替换了一个失效的磁盘后,ZFS 必须用丢失的数据填充新磁盘。重新同步是使用分布在其余驱动器上的奇偶校验信息来计算并写入缺失的数据到新驱动器的过程。
在线
池或者 Online 状态的虚拟设备拥有其成员设备连接并完全运作。Online 状态下的单个设备正在运行。
离线
如果存在足够的冗余以避免使池或 vdev 进入故障状态,管理员会将个别设备置于 Offline 状态。管理员可能选择离线磁盘以便替换,或者便于识别。
降级
在 Degraded 状态下的池或 vdev 中有一个或多个磁盘消失或故障。池仍然可用,但如果其他设备故障,池可能变得无法恢复。重新连接丢失的设备或更换故障磁盘将在重新连接或新设备完成重建过程后将池返回到在线状态。
故障
在 Faulted 状态下的池或 vdev 不再可操作。不再可能访问数据。当丢失或故障设备的数量超过 vdev 中冗余级别时,池或 vdev 进入 Faulted 状态。如果重新连接丢失的设备,池将返回在线状态。冗余不足以弥补故障磁盘数量将导致池内容丢失,并需要从备份中恢复。