第零章:介绍

本书几乎所有内容都适用于OpenZFS。

前置条件

需要熟悉FreeBSD的存储管理层GEOM。在非FreeBSD平台上,可以使用ZFS的磁盘和分区设备。

始终在磁盘或分区设备上使用ZFS,而不是在RAID或其他软件设备上。

ZFS 最佳实践

最佳实践的好处是有很多可供选择。

此书中的一些示例可供参考。

空间管理

使用写时复制文件系统,删除文件会占用空间。

随着池接近容量,ZFS需要越来越多的时间来存储额外的数据块,性能下降。

虽然ZFS开发人员一直在减少碎片化(fragmentation)对性能的影响,但随着池的利用率接近100%,碎片化问题会变得越来越严重。

从完全满的池中恢复是非常困难的。为了防止所有空间被使用,或者至少提前发出警告,应创建reservation(预定)。

理想情况下,应该为池容量保留20%的预定。在添加更多容量或删除旧数据时,始终可以降低预定以争取时间。

最不希望的就是意外地用完空间。UFS可以提供软着陆,只有root可以使用最后百分之几的可用磁盘空间。

以下示例在一个1TB的池中,创建了一个新的数据集,其中保留了200GB的数据:

每当在ZFS数据集上探索空间问题时,请记住zfs get space命令:

虽然zfs get space不会腾出空间,但这是找出所有空间去向的最快方法。

选择VDEV类型

在创建池时选择正确的VDEV类型是最重要的决定。它会影响池的性能以及扩展的可能性。

有研究发现(参阅 http://arxiv.org/ftp/arxiv/papers/1501/1501.00513.pdf ),要构建一个可以在没有人为干预的情况下存活四年的磁盘阵列,需要三奇偶检验的RAID。即使有无限量的备份,双奇偶检验也无法在四年内保持99.999%的可靠性。

标签的重要性

给驱动器添加标签可以为未来的维护省去很多麻烦。

在将磁盘和分区添加到ZFS池之前,应为其设置标签。

如果使用原始设备名称创建池,当设备发生故障时,系统重启后池结构看起来会和预期的不同。

最初,池由两个镜像组成:da1和da15组成的mirror-0,以及da2和da14组成的mirror-1。

现在磁盘da1出现了故障。

FreeBSD在启动时动态分配磁盘节点,由于da1缺失,FreeBSD对剩余的磁盘重新进行编号,将数字降低了一个。磁盘da15变成了da14,da14变成了da13。最糟糕的是,da2变成da1。

因此,mirror-1包含da1,这与故障磁盘的da1不同。mirror-0正在使用其备用盘(da7)来替换以前称为da1的东西。

然而,当管理员为失效的da1放回一个磁盘时,da7变成了da8。

ZFS不使用FreeBSD磁盘名称来查找每个VDEV的成员,而是依靠其自己的磁盘标签和全局唯一标识(Globally Unique Identifier——GUID)。ZFS可以识别磁盘,无论操作系统将其设备节点放在哪里。操作系统也不在乎——它只会为你找到磁盘并挂载文件系统。

然而,这容易让人类操作员感到困惑。突然间,da1不再是故障设备,而是另一个VDEV中的完美设备。操作员更换设备并重新启动机器后,更换的驱动器几乎肯定会再次变为da1。所有设备节点将移回其原始值。在所有这些结束时,系统管理员不知道哪个磁盘是哪个磁盘。

为磁盘添加标签

FreeBSD提供了几种标记磁盘或分区的方法。有些是自动的,有些是由用户管理的。每种都有优缺点。一个设备可以有多个标签。

一旦访问了一个标签,指向同一设备的其他标签将会枯萎(wither)并变得无法访问。这可以防止通过多个名称访问同一设备。

默认情况下,所有自动生成的标签都会被激活。如果想使用手动标签,最好禁用手动方法(methods)。

GPT 标签(手动)

如果磁盘是用GUID分区表(GPT)分区的,则每个分区都可以包含你选择的文本标签。这是本书作者标记磁盘的首选方法。

使用gpart创建并标记一个新分区:

下面示例修改第二个分区的标签:

手动标签允许通过物理位置或序列号等特征来识别磁盘。

如果使用GPT标签,我们建议禁用GPTID和磁盘ID标签。

GPTID 标签(自动)

使用GPT分区方案,每个分区都有一个唯一的GUID。GPTID标签系统使用GUID来标识分区。

问题是GUID对人类来说意义不大。例如:

第一段的最后几个字符实际上是不同的,很容易搞混。

如果ZFS在另一个标签下看到同一个池之前,在GPTID标签下看到一个池的一部分,则使用GPTID。这隐藏了你精心制作的标签。

通过在/boot/loader.conf中添加以下行,在启动时禁用GPTID标签:

FreeBSD默认启用GPT ID标签。

磁盘ID 标签(自动)

GPT和GPTID标签定义分区,磁盘ID(diskid)标签则定义整个磁盘。

设备名称基于磁盘的序列号,这份方便。但不幸的是,序列号中的特殊字符——尤其是空格——会被编码。这会产生非常丑陋的设备名称。

此外,由于标签标识的是磁盘,而不是分区,因此附加了设备名称的分区部分,并且很难从设备名称中挑出来。

可以禁用这些自动生成的标签,以阻止ZFS使用它们而不是GPT标签。

在/boot/loader.conf中添加以下内容:

许多人强烈支持磁盘标签,但这确实看起来很恶心。

FreeBSD默认启用磁盘标签。

glabel(手动)

除了以上类型的标签,还以创建存储在磁盘或最后一份扇区中GEOM标签。这些标签采用GEOM特定的格式,称为glabel。

自定义glabel的优点是不需要使用GPT格式。因此它们可以与MBR格式的磁盘和没有分区的原始磁盘一起使用。glabel使用提供者的最后一个扇区。

使用glabel创建和查看glabel:

现在有了一个/dev/label/mylabel设备。

所有标签必须是唯一的。虽然可以将同一标签用于多个磁盘,但只会显示一个。

DTrace

一些ZFS功能的更高级别调优需要DTrace,这是一个用于跟踪软件行为和性能的程序。

将DTrace与ZFS结合使用需要了解内核内部。

DTrace使用内核模块进行软件探测,以观察软件的行为:DTrace.ko和dtraceall.ko。

可以在loader.conf中引导时自动加载这些模块。如果找不内核模块,dtrace程序会在你第一次运行时自动加载它们。

必须以root身份运行dtrace。

将脚本复制到文本中,然后运行dtrace -s,将脚本作为参数。

安CTRL-C中断脚本。

各章速览