转载:https://www.ibm.com/developerworks/cn/linux/l-zfs/index.html
https://www.cnblogs.com/pipci/p/10180366.html
ZFS 简介
将 ZFS 称为文件系统有点名不副实,因为它在传统意义上不仅仅是个文件系统。ZFS 将逻辑卷管理器的概念与功能丰富的和可大规模扩展的文件系统结合起来。让我们开始先探索一些 ZFS 所基于的原则。首先,ZFS 使用池存储模型,而不是传统的基于卷的模型。这意味着 ZFS 视存储为可根据需要动态分配(和缩减)的共享池。这优于传统模型,在传统模型中,文件系统位于卷上,使用独立卷管理器来管理这些资产。ZFS 内嵌入的是重要功能集(如快照、即写即拷克隆、连续完整性检查和通过 RAID-Z 的数据保护)的实现。更进一步,可以在 ZFS 卷的顶端使用您自己最喜爱的文件系统(如 ext4)。这意味着您可以获得那些 ZFS 的功能,如独立文件系统中的快照(该文件系统可能并不直接支持它们)。
但是 ZFS 不只是组成有用文件系统的功能集合。相反,它是构建出色文件系统的集成和补充功能的集合。让我们来看看其中的一些功能,然后再看看它们的一些实际应用。
存储池
正如前面所讨论的,ZFS 合并了卷管理功能来提取底层物理存储设备到文件系统。ZFS 对存储池(称为 zpools)进行操作,而不是直接查看物理块设备,存储池构建自虚拟驱动器,可由驱动器或驱动器的一部分物理地进行表示。此外,可以动态构造这些池,甚至这些池正在活跃地使用时也可以。
即写即拷
ZFS 使用即写即拷模型来管理存储中的数据。虽然这意味着数据永远不会写入到位(从来没有被覆盖),而是写入新块并更新元数据来引用数据。即写即拷有利的原因有多个(不仅仅是因为它可以启用的快照和克隆等一些功能)。由于从来不覆盖数据,这可以更简单地确保存储永远不会处于不一致的状态(因为在新的写入操作完成以后较早的数据仍保留)。这允许 ZFS 基于事务,且更容易实现类似原子操作等的功能。
即写即拷设计的一个有趣的副作用是文件系统的所有写入都成为顺序写入(因为始终进行重新映射)。此行为避免存储中的热点并利用顺序写入的性能(比随机写入更快)。
数据保护
可以使用 ZFS 的众多保护方案之一来保护由虚拟设备组成的存储池。您不但可以跨两个或多个设备(RAID 1)来对池进行镜像,通过奇偶校验来保护该池(类似于 RAID 5),而且还可以跨动态带区宽度(后面详细介绍)来镜像池。基于池中设备数量,ZFS 支持各种不同的的奇偶校验方案。例如,您可以通过 RAID-Z (RAID-Z 1) 来保护三个设备;对于四个设备,您可以使用 RAID-Z 2(双重奇偶校验,类似于 RAID6)。对于更大的保护来说,您可以将 RAID-Z 3 用于更大数量的磁盘进行三重奇偶校验。
为提高速度(不存在错误检测以外的数据保护),您可以跨设备进行条带化(RAID 0)。您还可以创建条带化镜像(来镜像条带化设备),类似于 RAID 10。
ZFS 的一个有趣属性随 RAID-Z、即写即拷事务和动态条带宽度的组合而来。在传统的 RAID 5 体系结构中,所有磁盘都必须在条带内具有其自己的数据,或者条带不一致。因为没有方法自动更新所有磁盘,所以这可能产生众所周知的 RAID 5 写入漏洞问题(其中在 RAID 集的驱动器中条带是不一致的)。假设 ZFS 处理事务且从不需要写入到位,则写入漏洞问题就消除了。此方法的另外一个便捷性体现在磁盘出现故障且需要重建时。传统的 RAID 5 系统使用来自该集中其他磁盘的数据来重建新驱动器的数据。RAID-Z 遍历可用的元数据以便只读取有关几何学的数据并避免读取磁盘上未使用的空间。随着磁盘变得更大以及重建次数的增加,此行为变得更加重要。
校验和
虽然数据保护提供了在故障时重新生成数据的能力,但是这并不涉及处于第一位的数据的有效性。ZFS 通过为写入的每个块的元数据生成 32 位校验和(或 256 位散列)解决了此问题。在读取块时,将验证此校验和以避免静默数据损坏问题。在有数据保护(镜像或 AID-Z)的卷中,可自动读取或重新生成备用数据。
用于完整性的标准方法
T10 为被称为数据完整性字段(Data Integrity Field,DIF)的端对端完整性提供相似的机制。此机制建议一个字段,包含块的循环冗余校验和存储在磁盘上的其他元数据以避免静默数据损坏。DIF 的一个有趣属性是,您将在许多存储控制器中发现对它的硬件支持,所以此进程完全从主机处理器卸载。
在 ZFS 上校验和与元数据存储在一起,所以可以检测并更正错位写入 — 如果提供数据保护(RAID-Z)—。
快照和克隆
由于 ZFS 的即写即拷性质,类似快照和克隆的功能变得易于提供。因为 ZFS 从不覆盖数据而是写入到新的位置,所以可以保护较早的数据(但是在不重要的情况下被标记为删除以逆转磁盘空间)。快照 就是旧块的保存以便及时维护给定实例中的文件系统状态。这种方法也是空间有效的,因为无需复制(除非重新写入文件系统中的所有数据)。克隆 是一种快照形式,在其中获取可写入的快照。在这种情况下,由每一个克隆共享初始的未写入块,且被写入的块仅可用于特定文件系统克隆。
可变块大小
传统的文件系统由匹配后端存储(512 字节)的静态大小的块组成。ZFS 为各种不同的使用实现了可变块大小(通常大小达到 128KB,但是您可以变更此值)。可变块大小的一个重要使用是压缩(因为压缩时的结果块大小理想情况下将小于初始大小)。除了提供更好的存储网络利用外,此功能也使存储系统中的浪费最小化(因为传输更好的数据到存储需要更少的时间)。
在压缩以外,支持可变块大小还意味着您可以针对所期望的特定工作量优化块大小,以便改进性能。
其他功能
ZFS 并入了许多其他功能,如重复数据删除(最小化数据重复)、可配置的复制、加密、缓存管理的自适应更换缓存以及在线磁盘清理(标识并修复在不使用保护时可以修复的潜在错误)。它通过巨大的可扩展性来实现该功能,支持 16 千兆兆个字节的可寻址存储(264 字节)。
在 Linux 上使用 ZFS
现在您已经了解了 ZFS 背后的一些抽象概念,让我们在实践中看看其中的一些概念。本演示使用了 ZFS-FUSE。FUSE 是一种机制,允许您在没有内核代码(除 FUSE 内核模块和现有的文件系统代码以外)情况下在用户空间中实现文件系统。该模块为用户和文件系统实现提供从内核文件系统接口到用户空间的桥梁。首先,安装 ZFS-FUSE 包(下面的演示针对 Ubuntu)。
安装 ZFS-FUSE
安装 ZFS-FUSE 很简单,尤其是在使用 apt
的 Ubuntu 上。下面的命令行安装了您开始使用 ZFS-FUSE 所需的一切:
1 |
|
此命令行安装 ZFS-FUSE 和所有其他依赖包( 我的也需要 libaiol
),为新的程序包执行必要的设置并启动 zfs-fuse
守护进程。
使用 ZFS-FUSE
在此演示中,您使用环回设备以便在主机操作系统内将磁盘仿真为文件。要开始此操作,请通过 dd
实用程序(参见清单 1)创建这些文件(使用 /dev/zero 作为源)。在创建了四个磁盘映像之后,使用 losetup
将磁盘映像与环路设备关联在一起。
清单 1. 使用 ZFS-FUSE 的设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
有了四台设备作为您的 ZFS 块设备(总大小 256MB),使用 zpool
命令来创建您的池。您可以使用 zpool
命令来管理 ZFS 存储池,不过您将看到,您可以将其用于各种其他目的。下面的命令要求通过四个设备创建 ZFS 存储池并通过 RAID-Z 提供数据保护。在此命令后为一个列表请求,以便提供您池中的数据(参见清单 2)。
清单 2. 创建 ZFS 池
1 2 3 4 5 |
|
您还可以研究池的一些属性,如清单 3 所示,其代表默认值。对于其他事项,您可以查看可用容量和已使用的部分。(为了简洁,此代码已经被压缩。)
清单 3. 查看存储池的属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
现在,让我们实际使用 ZFS 池。首先,在您的池中创建目录,然后在该目录中启用压缩(使用 zfs set
命令)。其次,将文件复制到其中。我已经选择了大小 120KB 左右的文件来查看 ZFS 压缩的效果。请注意您的池挂载在根目录上,因此就像您的根文件系统内的目录一样加以处理。一旦复制该文件,您就可以列出它来表示文件已存在(但与原来同样大小)。通过使用 dh
命令,您可以看到文件大小为原来的一半,这说明 ZFS 已经将其压缩。您还可以查看 compressratio
属性,了解您的池有多少已经被压缩(使用默认压缩程序,gzip)。清单 4 显示了该压缩。
清单 4. 演示 ZFS 压缩
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
最后,让我们看看 ZFS 的自修复功能。请回想在您创建池时,您要求四个设备具有 RAID-Z。通过使用 zpool status
命令您可以检查池的状态, 如清单 5 所示。如清单所示,您可以看到池的元素(RAID-Z 1 以及四个设备)。
清单 5. 检查池状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
现在,让我们强制执行一个错误到池中。对于此演示来说,转到后台并损坏组成设备的磁盘文件(disk4.img,通过 loop3
设备显示在 ZFS 中)。使用 dd
命令将整个设备清零(参见清单 6)。
清单 6. 损坏 ZFS 池
1 2 3 4 5 |
|
ZFS 目前未意识到损坏,但是您可以通过请求池的清理,强制池发现问题。如清单 7 所示,ZFS 现在认识到(loop3
设备的)损坏并建议操作以便替换该设备。还请注意在 ZFS 通过 RAID-Z 自我更正时,池仍然在线,您仍然可以访问您的数据。
清单 7. 清理并检查池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
根据建议,引入新的设备到您的 RAID-Z 集以便充当新的容器。首先创建新的磁盘映像并通过 losetup
将其表示为设备。请注意此过程类似于将新的物理磁盘添加到集。然后,您使用 zpool replace
用新的设备(loop4
)交换已损坏的设备(loop3
)。检查池状态,您可以看到新设备具有一条消息,指示其上重新构建了数据(称为 resilvering)以及移到那里的数据量。还请注意池仍保持在线,没有错误(对用户可见)。最后,再次清理池;在检查其状态以后,您将看不到存在问题,如清单 8 所示。
清单 8. 使用 zpool replace 修复池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
此简短演示探究了通过文件系统进行的卷管理的整合,并展示了管理 ZFS(即使是故障时)有多简单。
其他 Linux-ZFS 可能性
FUSE 中 ZFS 的优点是易于开始使用 ZFS,但是它的缺点是效率低。这种效率上的缺点是每个 I/O 都要求多个用户内核转换的结果。但是考虑到 ZFS 的流行,有另外一种提供更好性能的选项。
针对 Linux 内核的 ZFS 本地端口正在 Lawrence Livermore 国家实验室中处于顺利开发当中。虽然此端口仍然缺乏一些元素,如 ZFS 便携式操作系统接口(适用于 UNIX®) 层,但是这正在开发中。其端口提供大量有用的功能,尤其是当您有兴趣与 Lustre 一起使用 ZFS 时。(要了解更多细节,参阅 参考资料。)
ZFS 是什么,它有什么特性?
正如前面所说过的,ZFS 是一个先进的文件系统。因此,它有一些有趣的特性。比如:
- 存储池
- 写时拷贝
- 快照
- 数据完整性验证和自动修复
- RAID-Z
- 最大单个文件大小为 16 EB(1 EB = 1024 PB)
- 最大 256 千万亿(256*1015 )的 ZB(1 ZB = 1024 EB)的存储
让我们来深入了解一下其中一些特性。
存储池
与大多数文件系统不同,ZFS 结合了文件系统和卷管理器的特性。这意味着,它与其他文件系统不同,ZFS 可以创建跨越一系列硬盘或池的文件系统。不仅如此,你还可以通过添加硬盘来增大池的存储容量。ZFS 可以进行分区和格式化。
ZFS 存储池
写时拷贝
写时拷贝Copy-on-write是另一个有趣并且很酷的特性。在大多数文件系统上,当数据被重写时,它将永久丢失。而在 ZFS 中,新数据会写到不同的块。写完成之后,更新文件系统元数据信息,使之指向新的数据块(LCTT 译注:更新之后,原数据块成为磁盘上的垃圾,需要有对应的垃圾回收机制)。这确保了如果在写新数据的时候系统崩溃(或者发生其它事,比如突然断电),那么原数据将会保存下来。这也意味着,在系统发生崩溃之后,不需要运行 fsck 来检查和修复文件系统。
快照
写时拷贝使得 ZFS 有了另一个特性:快照snapshots。ZFS 使用快照来跟踪文件系统中的更改。快照包含文件系统的原始版本(文件系统的一个只读版本),实时文件系统则包含了自从快照创建之后的任何更改。没有使用额外的空间。因为新数据将会写到实时文件系统新分配的块上。如果一个文件被删除了,那么它在快照中的索引也会被删除。所以,快照主要是用来跟踪文件的更改,而不是文件的增加和创建。
快照可以挂载成只读的,以用来恢复一个文件的过去版本。实时文件系统也可以回滚到之前的快照。回滚之后,自从快照创建之后的所有更改将会丢失。
数据完整性验证和自动修复
当向 ZFS 写入新数据时,会创建该数据的校验和。在读取数据的时候,使用校验和进行验证。如果前后校验和不匹配,那么就说明检测到了错误,然后,ZFS 会尝试自动修正错误。
RAID-Z
ZFS 不需要任何额外软件或硬件就可以处理 RAID(磁盘阵列)。毫不奇怪,因为 ZFS 有自己的 RAID 实现:RAID-Z 。RAID-Z 是 RAID-5 的一个变种,不过它克服了 RAID-5 的写漏洞:意外重启之后,数据和校验信息会变得不同步(LCTT 译注:RAID-5 的条带在正写入数据时,如果这时候电源中断,那么奇偶校验数据将跟该部分数据不同步,因此前边的写无效;RAID-Z 用了 “可变宽的 RAID 条带” 技术,因此所有的写都是全条带写入)。为了使用基本级别的 RAID-Z(RAID-Z1),你需要至少三块磁盘,其中两块用来存储数据,另外一块用来存储奇偶校验信息。而 RAID-Z2 需要至少两块磁盘存储数据以及两块磁盘存储校验信息。RAID-Z3 需要至少两块磁盘存储数据以及三块磁盘存储校验信息。另外,只能向 RAID-Z 池中加入偶数倍的磁盘,而不能是奇数倍的。
巨大的存储潜力
创建 ZFS 的时候,它是作为最后一个文件系统而设计的 。那时候,大多数文件系统都是 64 位的,ZFS 的创建者决定直接跳到 128 位,等到将来再来证明这是对的。这意味着 ZFS 的容量大小是 32 位或 64 位文件系统的 1600 亿亿倍。事实上,Jeff Bonwick(其中一个创建者)说:“完全填满一个 128 位的存储池所需要的能量,从字面上讲,比煮沸海洋需要的还多。”
如何安装 ZFS?
如果你想立刻使用 ZFS(开箱即用),那么你需要安装 FreeBSD 或一个使用 illumos 内核的操作系统。illumos 是 OpenSolaris 内核的一个克隆版本。
事实上,支持 ZFS 是一些有经验的 Linux 用户选择 BSD 的主要原因。
如果你想在 Linux 上尝试 ZFS,那么只能在存储文件系统上使用。据我所知,没有任何 Linux 发行版可以在根目录上安装 ZFS,实现开箱即用。如果你对在 Linux 上尝试 ZFS 感兴趣,那么 ZFS on Linux 项目 上有大量的教程可以指导你怎么做。
附加说明
这篇文章论述了 ZFS 的优点。现在,让我来告诉你一个关于 ZFS 很现实的问题。使用 RAID-Z 会很贵,因为你需要购买大量的磁盘来增大存储空间。