19.8. ZFS 特性与术语

ZFS 是一个从本质上与众不同的文件系统,由于它并非只是一个文件系统,ZFS 结合了文件系统及磁盘区管理程序,让额外的储存设备可以即时的加入到系统并可让既有的文件系统立即使用这些在存储池中空间。透过结合传统区分为二的两个角色,ZFS 能够克服以往 RAID 磁盘群组无法扩充的限制。每个在存储池顶层的设备称作vdev,其可以是一个简单的磁盘或是一个RAID 如镜像或RAID-Z 阵列。 ZFS 的文件系统(称作数据集(Dataset))每一个数据集均可存取整个存池所共通的可用空间,随着使用存储池来配置空间区块,存储池能给每个文件系统使用的可用空间就会减少,这个方法可以避免扩大分割区会使的可用空间分散分割区之间的常见问题。

存储池(Pool)存储池(pool)是 ZFS 最基础的组成部分。存储池由一个或多个 vdev 组成,其下方设备负责存储数据。存储池上可创建一个或多个文件系统(数据集 datasets)或块设备(卷 volumes)。这些数据集和卷共享存储池用的剩余可用空间。存储池可用名字或GUID标记。存储池的功能由存储池自身的ZFS版本号决定。
vdev 类型(vdev Types)存储池是由一个或多个 vdev 所组成,vdev 可以是一个磁盘或是 RAID Transform 的磁盘群组。当使用多个 vdev,ZFS 可以分散资料到各个 vdev 来增加效能与最大的可用空间。
  • 磁盘(Disk) - 最基本的 vdev 型态便是一个标准的资料区块设备,这可以是一整个磁盘(例如/dev/ada0/dev/da0)或一个分割区(/dev/ada0p3)。在 FreeBSD 上,使用分割区来替代整个磁盘不会影响效能,这可能与 Solaris 说明文件所建议的有所不同。

    小心:

    强烈建议不要将整个磁盘用作可引导存储池的一部分,因为这可能会使存储池无法启动。同样,不应将整个磁盘用作镜像或RAID-Z vdev 的一部分。这是因为在引导时无法可靠地确定未分区磁盘的大小,并且无法放入引导代码。

  • 文件(File) - 除了磁盘外,ZFS 存储池可以使用一般文件为基础,这在测试与实验时特别有用。在 zpool create 时使用文件的完整路径作为设备路径。所有 vdev 必须至少有 128 MB 的大小。

  • 镜像(Mirror) - 要建立镜像,需使用 mirror 关键字,后面接着要做为该镜像成员设备的清单。一个镜像需要由两个或多个设备来组成,所有的资料都会被写入到所有的成员设备。镜像 vdev 可以对抗所有成员故障只剩其中一个而不损失任何资料。

    注意:

    正常单一磁盘的 vdev 可以使用 zpool attach 随时升级成为镜像 vdev。

  • RAID-Z - ZFS 实作了RAID-Z,以标准的RAID-5 修改而来,可提供奇偶校验(Parity)更佳的分散性并去除了RAID-5 write hole 导致在预期之外的重启后资料与奇偶校验资讯不一致的问题。ZFS 支持三个层级的RAID-Z,可提供不同程度的备援来换取减少不同程度的可用空间,类型的名称以阵列中奇偶校验设备的数量与存储池可以容许磁盘故障的数量来命名,从RAID-Z1RAID-Z3

    RAID-Z1 配置4 个磁盘,每个磁盘1 TB,可用的储存空间则为3 TB,且若其中一个磁盘故障仍可以降级(Degraded)的模式运作,若在故障磁盘尚未更换并修复(Resilver)之前又有磁盘故障,所有在存储池中的资料便会遗失。

    RAID-Z3 配置 8 个 1 TB 的磁盘,磁盘区将会可以提供 5 TB 的可用空间且在 3 个磁盘故障的情况下仍可运作. Sun™ 建议单一个 vdev 不要使用超过 9 个磁盘.若配置需要使用更多磁盘,建议分成两个 vdev,这样存储池的资料便会分散到这两个 vdev。

    A configuration of two RAID-Z2 vdevs consisting of 8 disks each would create something similar to a RAID-60 array. A RAID-Z group's storage capacity is approximately the size of the smallest disk multiplied by the number of non-parity disks. Four 1 TB disks in RAID-Z1 has an effective size of approximately 3 TB, and an array of eight 1 TB disks in RAID-Z3 will yield 5 TB of usable space.

  • 备援(Spare) - ZFS 有特殊的虚拟 vdev 型态可用来持续追踪可用的热备援设备(Hot spare)。注意,安装的热备援设备并不会自动布署,热备援设备需要手动使用 zfs replace 设定替换故障的设备。

  • 日志(Log) - ZFS 记录设备,也被称作ZFS 意图日志(ZFS Intent Log,ZIL)会从正常的存储池设备移动意图日志到独立的设备上,通常是一个 SSD。有了独立的日志设备,可以明显的增进有大量同步写入应用程序的效能,特别是资料库。日志设备可以做成镜像,但不支持 RAID-Z,若使用多个日志设备,写入动作会被负载平衡分散到这些设备。

  • 缓存(Cache) - 加入快取vdev 到存储池可以增加储存空间的L2ARC 快取。快取设备无法做镜像,因快取设备只会储存额外的现有资料的复本,并没有资料遗失的风险。

交易群组(Transaction Group, TXG)交易群组是一种将更动的资料区块包装成一组的方式,最后再一次写入到存储池。交易群组是 ZFS 用来检验一致性的基本单位。每个交易群组会被分配一个独一无二的 64-bit 连续代号。最多一次可以有三个活动中的交易群组,这三个交易群组的每一个都有这三种状态:
  • 开放(Open) - 新的交易群组建立之后便处于开放的状态,可以接受新的写入动作。永远会有开放状态的交易群组,即始交易群组可能会因到达上限而拒绝新的写入动作。一但开放的交易群组到达上限或到达vfs.zfs.txg.timeout,交易群组便会继续进入下一个状态。

  • 静置中(Quiescing) - 一个短暂的状态,会等候任何未完成的操作完成,不会阻挡新开放的交易群组建立。一旦所有在群组中的交易完成,交易群组便会进入到最终状态。

  • 同步中(Syncing) - 所有在交易群组中的资料会被写任到稳定的储存空间,这个程序会依序修改其他也需同样写入到稳定储存空间的资料,如Metadata 与空间对应表。同步的程多会牵涉多个循环,首先是同步所有更改的资料区块,也是最大的部份,接着是 Metadata,这可能会需要多个循环来完成。由于要配置空间供资料区块使用会产生新的 Metadata,同步中状态在到达循环完成而不再需要分配任何额外空间的状态前无法结束。同步中状态也是完成 synctask 的地方,Synctask 是指管理操作,如:建立或摧毁快照与数据集,会修改 uberblock,也会在此时完成。同步状态完成后,其他处于状态中状态的交易群组便会进入同步中状态。

所有管理功能如快照(Snapshot)会作为交易群组的一部份写入。当 synctask 建立之后,便会加入到目前开放的交易群组中,然后该群组会尽快的进入同步中状态来减少管理指令的延迟。
自适应替换缓存(ARCZFS 使用了自适应替换快取(Adaptive Replacement Cache, ARC),而不是传统的最近最少使用(Least Recently Used, LRU )快取,LRU 快取在快取中是一个简单的项目清单,会依每个物件最近使用的时间来排序,新项会加入到清单的最上方,当快取额满了便会去除清单最下方的项目来空出空间给较常使用的物件。 ARC 结合了四种快取清单,最近最常使用(Most Recently Used, MRU)及最常使用(Most Frequently Used, MFU)物件加上两个清单各自的幽灵清单(Ghost list),这些幽灵清单会追踪最近被去除的物件来避免又被加回到快取,避免过去只有偶尔被使用的物件加入清单可以增加快取的命中率。同时使用MRUMFU 的另外一个优点是扫描一个完整文件系统可以去除在MRULRU 快取中的所有资料,有利于这些才刚存取的内容。使用 ZFS 也有 MFU 可只追踪最常使用的物件并保留最常被存取的资料区块快取。
L2ARCL2ARCZFS缓存系统的第二层,主要的ARC 会储存在RAM 当中,但因为RAM 可用的空间量通常有限,因此ZFS 也可以使用cache vdevs。固态磁盘(Solid State Disk, SSD)常被拿来此处作为快取设备,因为比起传统旋转碟片的磁盘,固态磁盘有较快的速度与较低的延迟。 L2ARC 是选用的,但使用可以明显增进那些已使用 SSD 快取的档案读取速度,无须从一般磁盘读取。 L2ARC 也同样可以加速去重复(Deduplication),因为DDT 并不适合放在 RAM,但适合放在L2ARC,比起要从磁盘读取,可以加快不少速度。为了避免SSD 因写入次速过多而过早耗损,加入到快取设备的资料速率会被限制,直到快取用尽(去除第一个资料区块来腾出空间)之前,写入到L2ARC 的资料速率会限制在写入限制(Write limit)与加速限制(Boost limit)的总合,之后则会限制为写入限制,可以控制这两个速度限制的sysctl(8) 数值分别为vfs.zfs.l2arc_write_max 控制每秒有多少数位元组可写入到快取,而vfs.zfs.l2arc_write_boost 可在涡轮预热阶段(即写入加速)时增加写入限制。
ZILZIL 會使用比主要儲存池還更快的儲存裝置來加速同步寫入動作(Synchronous transaction),如 SSD。當應用程序請求做一個同步的寫入時(保証資料會安全的儲存到磁盘,而不是先快取稍後再寫入),資料會先寫入到速度較快的 ZIL 儲存空間,之後再一併寫入到一般的磁盘。這可大量的減少延遲並增進效能。ZIL 只會有利於使用像資料庫這類的同步工作,一般非同步的寫入像複製檔案,則完全不會用到 ZIL
写入时复制(Copy-On-Write)不像传统的文件系统,在ZFS,当资料要被覆写时,不会直接覆写旧资料所在的位置,而是将新资料会写入到另一个资料区块,只在资料写入完成后才会更新Metadata 指向新的位置。因此,在发生写入中断(在写入档案的过程中系统当机或电源中断)时,原来档案的完整内容并不会遗失,只会放弃未写入完成的新资料,这也意谓着ZFS 在发生预期之外的关机后不需要做fsck(8)
数据集(Dataset)数据集(Dataset)ZFS 文件系统、磁盘区、快照或复本的通用术语。每个数据集都有独一无二的名称使用 poolname/path@snapshot 格式。存储池的根部技术上来说也算一个数据集,子数据集会采用像目录一样的层级来命名,例如mypool/home,home 数据集是mypool 的子数据集并且会继承其属性。这可以在往后继续扩展成 mypool/home/user,这个孙数据集会继承其父及祖父的属性。在子数据集的属性可以覆盖预设继承自父及祖父的属性。数据集及其子资料级的管理权限可以委托(Delegate)给他人。
文件系统(File system)ZFS 数据集最常被当做文件系统使用。如同大多数其他的文件系统,ZFS 文件系统会被挂载在系统目录层级的某一处且内含各自拥有权限、旗标及 Metadata 的档案与目录。
磁盘分区(Volume)除了一般的文件系统数据集之外,ZFS 也可以建立磁盘区(Volume),磁盘区是资料区块设备。磁盘区有许多与数据集相似的功能,包含复制时写入、快照、复本以及资料校验。要在ZFS 的顶层执行其他文件系统格式时使用磁盘区非常有用,例如UFS 虚拟化或汇出iSCSI 延伸磁区(Extent)。
快照(Snapshot)ZFS 的写入时复制(Copy-On-Write, COW)设计可以使用任意的名称做到几乎即时、一致的快照。在制做数据集的快照或父数据集递回快照(会包含其所有子数据集)之后,新的资料会写入到资的资料区块,但不会回收旧的资料区块为可用空间,快照中会使用原版本的文件系统,而快照之后所做的变更则会储存在目前的文件系统,因此不会重复使用额外的空间。当新的资料写入到目前的文件系统,便会配置新的资料区块来储存这些资料。快照表面大小(Apparent size)会随着在目前文件系统停止使用的资料区块而成长,但仅限于快照。可以用只读的方式挂载这些快照来复原先前版本的档案,也可以还原(Rollback)目前的文件系统到指定的快照,来还原任何在快照之后所做的变更。每个在存储池中的资料区块都会有一个参考记数器,可以用来持续追踪有多少快照、复本、数据集或是磁盘区使用这个资料区块,当删除档案与快照参照的计数变会灭少,直到没有任何东西参考这个资料区块才会被回收为可用空间。快照也可使用hold 来标记,档标记为hold 时,任何尝试要删除该快照的动作便会回传EBUSY的错误,每个快照可以标记多个不同唯一名称的hold,而release 指令则可以移除hold,这样才可删除快照。在磁盘区上快可以制作快照,但只能用来复制或还原,无法独立挂载。
复本(Clone)快照也可以做复本,复本是可写入版本的快照,让文件系统可分支成为新的数据集。如同快照,复本一开始不会消耗任何额外空间,随着新资料写入到复本会配置新的资料区块,复本的表面大小(Apparent size)才会成长,当在复本文件系统或磁盘区的资料区块被覆写时,在先前资料区块的参考计数则会减少。建立复本所使用的快照无法被删除,因为复本会相依该快照,快照为父,复本为子。复本可以被提升(promoted)、反转相依关系,来让复本成为父,之前的父变为子,这个操作不需要额外的空间。由于反转了父与子使用的空间量,所以可能会影响既有的配额(Quota)与保留空间(Reservation)。
校验码(Checksum)配置每个资料区块快的同时也会做资料校验,资料校验用的演算法是依数据集属性而有所不同的,请参考set。每个资料区块会在读取的过成便完成校验,让ZFS 可以侦测到隐藏的损坏,若资料不符合预期的校验码,ZFS 会尝试从任何可用的备援来还原资料,例如镜像(Mirror)或RAID-Z。要检验所有资料的校验码可以使用清洁(Scrub),资料校验的演算法有:
  • fletcher2

  • fletcher4

  • sha256

fletcher 演算法最快,而sha256 虽较消耗效能,但其有强大的密码杂凑与较低的冲突率。也可关闭资料校验,但并不建议。
压缩(Compression)每个数据集都有压缩(Compression)属性,预设是关闭的,这个属性可以设定使用以下几个压缩演算法的其中一个来压缩写入到数据集的新资料。压缩除了减少空间使用量外,常也会增加读取与写入的吞吐量,因为会减少读取与写入的资料区块。
  • LZ4 - ZFS 存储池版本5000(功能旗标)后所增加,LZ4 现在是建议的压缩演算法,在处理可压缩的资料时LZ4 压缩比LZJB 快将近50%,在处理不可压缩的资料时快将近三倍,LZ4 解压缩也比LZJB 将近80%。在现代的 CPU 上,LZ4 经常平均可用 500 MB/s 的速度压缩,而解压缩可到达 1。5 GB/s(每个 CPU 核心)。

  • LZJB - 预设的压缩演算法。由 Jeff Bonwick 所开发(ZFS 的创始人之一)。 LZJBGZIP 相比,可以较低的 CPU 提供较佳的压缩功能。在未来预设的压缩演算法将会更换为 LZ4

  • GZIP - 在 ZFS 可用的热门串流压缩演算法。使用 GZIP 主要的优点之一便是可设定压缩层级。当设定 compress 属性,管理者可以选择压缩层级范围从最低的压缩层级 gzip1 到最高的压缩层级 gzip9。这让管理者可以控制要使用多少 CPU 来节省磁盘空间。

  • ZLE - 零长度编号是一个特殊的压缩演算法,它只会压缩连续的零。这种压缩演算法只在数据集中含有大量为零的资料区块时有用。

副本(Copies)当设定大于1 的数值时,copies 属性会指示ZFS 备份每个在文件系统(File System)或磁盘区(Volume)的资料区块数份。在重要的数据集上设定这个属性可以做额外的备援以在资料校验码不相符时可做复原。在没有做备援的存储池上,备份功能提供只是一种资料的备援方式,备份功能可以复原单一坏轨或其他情况的次要损坏,但无法复原存储池中整个磁盘损坏所损失的资料。
去重复(Deduplication)校验码让在写入时可以侦测重复数据内存块,使用去重复,可以增加既有、完全相同的数据内存块参考数来节省储存空间。要侦测重复的数据内存块需要在內存中储存去重复数据表(Deduplication table,DDT),这个数据表中会有唯一的校验码清单、这些数据内存块的所在位置以及参考数。当写入新数据时,便会计算校验码然后比对清单中是否有符合的既有数据内存块已在清单。去重复使用了SHA256校验码算法来提供一个安全的加密哈希,去重复功能是可以调校的,若dedup设为on只要符合校验码便会认为数据完全相同,若dedup设为 verify则会一个一个位检查两个数据内存块的数据来确保数据真的完全相同,若数据不同便会注记与哈希冲突并会分别储存两个数据内存块。由于DDT须要储存每个唯一数据内存块的哈希,所以会消耗大量的內存,一般的经验法则是每1 TB的去重复数据需要使用5-6 GB的內存。由于要有足够的RAM来储存整个DDT在实务上并不实际,导致在每个新数据内存块写入前需要从磁盘来读取DDT会对性能有很大的影响,去重复功能可以使用L2ARC储存DDT以在快速的系统內存及较慢的磁盘之间取得一个平衡点。也可以考虑使用压缩功能来取代此功能,因为压缩也能节省相近的空间使用量而不需要大量额外的內存。
清洁(Scrub)ZFSscrub 来替代 fsck(8) 来做一致性的检查。 scrub 会读取所有储存在存储池中的资料区块并且根据储存在 Metadata 中已知良好的校验码来检验这些资料区块的校验码,定期检查存储池中储存的所有资料可以确保实际使用这些资料前已将所有损坏的资料区块复原。在不正常的关闭之后并不需要做清洁动作,但建议每三个月至少执行一次。在正常使用读取时便会检查每个资料区块的校验码,但清洁动作可以确保那些不常用的资料也会被检查以避免隐藏的损坏,如此便能增进资料的安全性,特别是对用来保存资料的储存设备。 scrub 可以使用vfs.zfs.scrub_delay 调整相对优先权来避免清洁动作降低存储池上其他工作的效率。
数据集配额(Dataset Quota)除了配额及空间保留外,ZFS 提供非常快速且准确的数据集、使用者及群组空间的计算功能,这可让管理者调整空间配置的方式且可为重要的文件系统保留空间。

ZFS supports different types of quotas: the dataset quota, the reference quota (refquota), the user quota, and the group quota.

配额会限制数据集及后裔包含数据集的快照、子数据集及子数据集的快照能使用的空间量。

注意:

磁盘区上无法设定配额,因为 volsize 属性已经被用来做内定的配额。

参考配额(Reference Quota)参考配额可以设定一个硬性限制(Hard limit)来限制数据集能使用的空间量,而这个硬性限制只包含了数据集参考的空间,并不含其后裔所使用的空间,如:文件系统或快照。
使用者配额(User Quota)使用者配额在用来限制特定使用者能使用的空间量时非常有用。
群组配额(Group Quota)群组配额可以限制特定群组能使用的空间量。
数据集保留空间(Dataset Reservation)reservation 属性可以确保对特定数据集及其后裔最小可用的空间量,若在storage/home/bob 设定10 GB 的保留空间且其他数据集尝试使用所有剩余的空间时,会保留至少10 GB 的空间供这个数据集使用。若要制作 storage/home/bob 的快照,该快照所使用的空间也会被列入保留空间计算。 refreservation 属性也以类似的方式运作,但是他 不包含 后裔,例如:快照。

不管那一种保留空间在许多情境皆很有用,例如:要规划与测试磁盘空间配置在新系统上的适应性,或是确保有足够的空间供稽查日志或系统还原程序及档案使用。

参考保留空间(Reference Reservation)refreservation 属性可以确保对特定数据集不包含 其后裔最小可用的空间,这代表若在storage/home/bob 设定10 GB的保留空间且其他数据集尝试使用所有剩余的空间时,会保留至少10 GB 的空间供这个数据集使用。于正常 reservation 不同的是,由快照及后裔数据集所使用的空间并不会列入保留空间计算。例如,若要制作一个storage/home/bob 的快照,在refreservation 空间之外必须要有足够的空间才能成功完成这项操作,主数据集的后裔并不会列入refreservation 空间额计算,所以也不会占用保留空间。
修复(Resilver)当有磁盘故障且被更换后,新的磁盘必须回存先前所遗失的资料,会使用分散在其他磁盘上的奇偶校验资讯来计算并写入遗失的资料到新的磁盘机的这个程序称作修复(Resilvering)
在线(Online)一个存储池或 vdev 处于在线(Online)状态时代表所有该设备的成员均已连结且正常运作。个别设备处于线上(Online)状态时代表功能正常。
离线(Offline)若有足够的备援可避免存储池或vdev 进入故障(Faulted)状态,个别设备若可由管理者设为离线(Offline)状态,管理者可以选择要设定那一个磁盘为离线来准备更换或是让其更容易辨识。
降级(Degraded)一个存储池或vdev 处于降级(Degraded)状态代表其有一个或多个磁盘已断线或故障,此时存储池仍可以使用,但只要再有其他的设备故障,存储池会无法复原。重新连线缺少的设备或更换故障的磁盘,并在新设备完成修复(Resilver)程序可让存储池返回线上(Online)状态。
故障(Faulted)一个存储池或 vdev 处于故障(Faulted)状态代表无法运作,会无法存取在该设备上的资料。当在 vdev 中缺少或故障的设备数超过备援的层级,存储池或 vdev 会进入故障(Faulted)状态。若缺少的设备可以重新连结上,存储池便会返回线上(Online)状态。若没有足够的备援可补偿故障的磁盘数量便会遗失存储池中的内容且只能从备份还原。

本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题,请先阅读 文档,如不能解决再联系 <questions@FreeBSD.org>.

关于本文档的问题请发信联系 <doc@FreeBSD.org>.