开始学习ZFS并不难。安装最新的FreeBSD版本。告诉安装程序您需要ZFS。你已经开始了。如果您从未使用过ZFS,请花点时间在测试系统或虚拟机上安装一个带有ZFS的新FreeBSD。不要选择加密或任何花哨的自定义选项。这个简单的安装提供了一个机会,在深入了解更复杂的设置之前,先了解一些ZFS基础知识。
ZFS结合了传统文件系统和卷管理器的功能。因此,它希望处理从单个文件的权限、哪些文件在哪个目录中,到跟踪哪些存储设备用于什么目的以及如何安排存储的所有事情。系统管理员指示ZFS排列磁盘和文件,但ZFS管理它们下面的整个存储堆栈。本章使用安装了默认ZFS设置的FreeBSD 10.1主机,将ZFS堆栈分为三层:
为了确定您的方向,我们从存储堆栈最明显的部分开始,一路往下走。一旦你理解了这些层是如何组合在一起的,本书的其余部分就从基础开始,一步步向上。
ZFS文件系统与传统文件系统并不完全相似,因此被称为数据集(datasets)。经典的Unix文件系统(Unix File System,UFS)及其衍生和工作类似物,如现代BSD的UFS2和Linux的extfs,使用各种程序管理文件系统。您可能已经习惯了使用 df(1) 、newfs(8) 、mount(8)、umount(8) 和 dump(8) 以及类似的命令。ZFS在 zfs(8) 程序中吸收了所有这些功能,该程序允许您创建、销毁、查看和以其他方式操作(spindle)ZFS数据集。
首先使用 zfs list 查看现有的ZFS数据集。
xxxxxxxxxx# zfs listNAME USED AVAIL REFER MOUNTPOINTzroot 429M 13.0G 96K nonezroot/ROOT 428M 13.0G 96K nonezroot/ROOT/default 428M 13.0G 428M /zroot/tmp 104K 13.0G 104K /tmpzroot/usr 428K 13.0G 96K /usr...这结合了 mount(8) 和 df(1) 的输出,对于管理UFS或extfs的人来说应该很熟悉。
每个数据集都有一个名称。ZFS数据集名称以数据集所在的ZFS存储池(或称 zpool )开头。我们的第一个条目称为简单的 zroot 。此条目表示池的根数据集,其他所有内容都依赖于它。
接下来的两列显示了已使用(used)和可用(available)的空间量。zroot 池已使用429 MB,还有13 GB的空间。
REFER (引用)列是ZFS特有的。这是数据集上可访问的数据量,不一定与使用的空间量相同。一些ZFS功能(如快照)在它们之间共享数据。我们的zroot条目“使用”了429 MB,但只引用了96 KB的数据。整个池有13GB的可用空间,但通过这个特定的数据集可以访问96KB。那并不多。剩余的空间用于此数据集的子数据集。第6章详细讨论了ZFS磁盘的使用。数据集的子数据集包括快照、卷和子数据集,正如您将在本书中看到的那样。
最后,我们有了文件系统挂载点。zroot ZFS未挂载。
看看第二个条目,名为 zroot/ROOT 。这是为根文件系统创建的ZFS数据集。与 zroot 池一样,它没有挂载。它引用了96KB的数据。这显然没有被使用,这对于根文件系统来说似乎很奇怪。
第三个条目 zroot/ROOT/default 是当前的根文件系统。它使用428 MB的数据,并挂载在Unix根目录 / 上。它指的是428 MB,这意味着这个数据集中有这么多数据。
为什么ZFS要将其从根文件系统中分离出来?ZFS使在多个根文件系统之间进行选择变得容易。此主机运行FreeBSD 10.1,但假设您必须应用一些安全更新并重新启动?应用操作系统补丁总是让系统管理员感到恐惧和希望交织在一起。即使是经过充分测试的升级也可能出错,毁掉每个人的一天。但是ZFS允许您克隆和快照数据集。当你升级到FreeBSD 10.1-p1时,你可以创建一个新的数据集,如 zroot/ROOT/10.1-p1 ,并告诉FreeBSD将其用作根分区。您要么不挂载 zroot/ROOT/default ,要么我将其挂载到 /oldroot 等备用位置。如果升级进展不顺利,那么恢复就微不足道了。
下一个数据集 zroot/tmp 几乎为空。它被挂载在 /tmp。此数据集是传统的临时目录。
ZFS缺少传统分区。分区是磁盘的逻辑细分,填充存储设备上非常特定的逻辑块地址(Logical Block Addresses,LBA)。分区不知道分区上的数据。更改分区意味着销毁并(可能)重建其上的文件系统。
Lucas看到无分区文件系统的第一个想法是想知道他将如何管理他的存储。这大致相当于他在密歇根州度过漫长寒冷的冬天后,几个月来第一次走出户外感受到自然温暖的空气时所经历的困惑。困惑是解放的一部分。我们学会了通过分区管理存储,因为我们必须这样做,而不是因为分区是令人愉快的,也不是因为它们是最好的解决方案。运行没有分区的传统文件系统是一种糟糕的做法,但ZFS不是传统的文件系统。
ZFS紧密集成了文件系统和较低的存储层。这意味着它可以根据需要在各种文件系统之间动态划分存储空间。虽然您可以在ZFS文件系统上设置特定的大小限制,但数据集没有传统的大小。如果池中有足够的空间容纳一个文件,你就可以使用它。以前你为 /var/log 分配了有限的磁盘空间,从而防止疯狂的日志填满你的磁盘,现在你必须在ZFS级别设置这些限制。
数据集可能使用的空间量是ZFS属性的一个示例。ZFS支持数十个数据集属性,例如, quota 属性控制数据集可以增长到多大。使用 zfs(8) 设置ZFS属性。
xxxxxxxxxx# zfs set quota=2g zroot/var/log使用 zfs get 命令可以查看属性:
xxxxxxxxxx# zfs get quota zroot/var/logNAME PROPERTY VALUE SOURCEzroot/var/log quota 2G local使用 zfs get all [zfs-dataset-name] 命令可以查看数据集的所有属性。
第4章详细探讨了ZFS属性,而第6章讨论了限制数据集大小。
文件系统一直都有最大大小和限制。我们都知道并害怕的FAT文件系统需要多次修订,部分原因是为了克服其最大大小为32MB,然后是2GB,然后是4GB。如今,FAT32的2TB限制开始显得有点狭窄。UFS和ext2/3/4fs都有自己的、同样任意的限制。这些限制的存在是因为文件系统作者必须在某个地方设置一个限制,并选择他们预计在未来几年内都能使用的值。然而,在达到这些限制之前,一个流行的文件系统将继续使用,因此系统管理员需要反复应对这些限制。
ZFS的拥护者声称ZFS不受这些任意限制的影响,但事实并非如此。ZFS使用128位来存储其大部分值,这将限制设置得如此之高,以至于今天从事系统管理的任何人都不会遇到这些限制。一个目录可以有 248 个文件,每个文件最多16 EB。单个池最多可达256泽字节,即 278 字节。一个存储池最多可以包含 264 个设备,单个主机最多可以有 264 个存储池。
好消息是,我们活得不够长,无法达到这些极限。坏消息是,我们拥有在文件系统之间迁移的所有专业知识。当技术达到ZFS的极限时,那些可怜人将不习惯在文件系统之间迁移。幸运的是,他们将有一些挥之不去的FAT/UFS/extfs滚动练习。
ZFS使用存储池而不是磁盘。存储池是底层存储提供程序之上的抽象(abstraction),允许您将物理介质和其上的用户可见文件系统分开。
使用 zpool(8) 查看和管理系统的存储池。这是默认FreeBSD系统的池。
xxxxxxxxxx# zpool status pool: zroot state: ONLINE scan: none requestedconfig:NAME STATE READ WRITE CKSUMzroot ONLINE 0 0 0 gpt/zfs0 ONLINE 0 0 0 errors: No known data errors你首先要知道池的名称(name)和状态(state)。系统可以有多个ZFS池——具有数十个硬盘驱动器的大型系统通常有多个池。如果此主机有多个存储池,则每个存储池都会出现在单独的描述中,如上面的示例所示。
ZFS可以对存储池执行多种完整性检查。scan 语句显示是否正在执行任何完整性检查以及最近一次扫描的结果。
池列表的最后一部分显示了池中虚拟设备的布局。
存储池包含一个或多个虚拟设备或称 VDEVs 。VDEV类似于传统的RAID设备。一个大型RAID-5在文件系统层表现为一个巨大的设备,即使系统管理员知道它实际上是一堆较小的磁盘。虚拟设备允许您将特定设备分配给特定角色。使用VDEV,您可以根据需要安排物理存储。
虚拟设备是ZFS魔法发生的地方。可以为RAID式冗余安排一个池。您可以将提供者(providers)用作专用的读写缓存,从而提高虚拟设备的性能。第2章更深入地介绍了虚拟设备。
ZFS的数据冗余和自动纠错也发生在VDEV级别。ZFS中的所有内容都经过校验和,以进行完整性验证。如果你的池有足够的冗余,ZFS是自我修复的。如果您的池缺乏冗余,那么至少您知道数据已损坏,并且可以(希望)从备份中恢复。
显示池运行状况的 zpool status 命令还显示了该池中的虚拟设备。请看上一节中的示例。这个非常简单的池 zroot 包含一个存储提供者 /dev/gpt/zfs0 。此提供者是GPT分区,而不是磁盘。正如第2章所讨论的,ZFS可以使用各种底层存储。使用GPT分区非常常见,但其他选项包括整个磁盘、文件和任何其他GEOM提供者。FreeBSD使用GEOM提供者来支持加密等功能。
传统的文件系统几乎总是使用各种数据块(data block)来存储数据,并用索引节点(index node)映射这些块的内容。BSD的UFS和Linux的extfs调用这些块和索引节点。甚至微软的FAT文件系统也有数据存储块和索引节点。
与这些文件系统一样,ZFS使用索引块和数据块。然而,与旧的文件系统不同,ZFS根据需要生成索引节点。只要有可能,ZFS就会创建适合数据大小的存储块。可变大小的块并不总是适合您可能创建的每个文件,但它们肯定比传统的文件系统更灵活。
与UFS超级块不同,动态生成的索引块不能放置在磁盘上的已知位置。ZFS如何应对索引块损坏的可能性?ZFS在算法可预测的位置存储关键索引块的多个副本。这些同上的块(ditto blocks)被复制到磁盘上的多个位置。第3章讨论了ZFS块、uberblocks、ditto块、事务组等。
现在您已经了解了ZFS的基本知识,本书的其余部分只填充了几百个小细节。我们将从堆栈的最底层开始,从虚拟设备开始。