Linux-ZFS-入门指南-全-

Linux ZFS 入门指南(全)

原文:Introducing ZFS on Linux

协议:CC BY-NC-SA 4.0

一、ZFS 概述

要与 ZFS 合作,了解技术方面和实施方面的基础知识非常重要。我见过许多失败的案例,其原因是人们试图管理 ZFS 文件系统,甚至对其进行故障排除,但并不真正了解他们在做什么,为什么要这么做。ZFS 不遗余力地保护你的数据,但世界上没有什么是用户证明。如果你真的很努力,你会打破它。这就是为什么从基础开始是个好主意。

Note

在大多数 Linux 发行版中,默认情况下 ZFS 是不可用的。有关 ZFS 在 Linux 上实现的最新信息,包括当前状态和路线图,请访问该项目的主页: http://zfsonlinux.org/ 。自从 Ubuntu Xenial Xerus,16.04 LTS Ubuntu 发布以来,Canonical 已经使 ZFS 成为一个常规的、受支持的文件系统。虽然您还不能在安装阶段使用它,至少不容易使用,但它随时可供使用,并且是 LXD(下一代系统容器管理器)的默认文件系统。

在本章中,我们将了解什么是 ZFS,并涵盖一些关键术语。

什么是 ZFS?

ZFS 是一种写入时复制(COW)文件系统,它合并了文件系统、逻辑卷管理器和软件 RAID。使用 COW 文件系统意味着,每次对数据块进行更改时,数据都会被写入磁盘上一个全新的位置。要么完全写入,要么不记录为完成。这有助于在断电的情况下保持文件系统的整洁和完好。将逻辑卷管理器和文件系统与软件 RAID 合并在一起,意味着您可以轻松地创建一个具有所需设置并包含随时可用的文件系统的存储卷。

Note

ZFS 的强大功能无法替代备份。快照、克隆、镜像等。,将只在有足够的存储可用时保护您的数据。即使你有这些漂亮的能力,你仍然应该做备份,并定期测试它们。

奶牛原理讲解

写时拷贝(COW)设计保证了快速解释,因为它是实现一些基本 ZFS 特性的核心概念。图 1-1 显示了一个可能油藏的图示;四个磁盘由两个 vdev 组成(每个 vdev 中有两个磁盘)。vdev 是构建在磁盘、分区、文件或 LUN 之上的虚拟设备。在该池中,位于 vdevs 之上的是文件系统。数据在所有 vdevs 和所有磁盘之间自动平衡。

A449522_1_En_1_Fig1_HTML.jpg

图 1-1

Graphical representation of a possible pool

图 1-2 显示了一个新写入的数据块。

A449522_1_En_1_Fig2_HTML.jpg

图 1-2

Single data block

当该块稍后被修改时,它不会被重写。相反,ZFS 在磁盘上的一个新位置重新写它,如图 1-3 所示。旧块仍在磁盘上,但如果需要可用空间,可以重新使用。

A449522_1_En_1_Fig3_HTML.jpg

图 1-3

Rewritten data block

让我们假设在数据被修改之前,系统操作员创建了一个快照。DATA 1 SNAP块被标记为属于文件系统快照。当数据被修改并写入新位置时,旧的块位置被记录在快照 vnodes 表中。每当需要将文件系统恢复到快照时间时(回滚或挂载快照时),都会从当前文件系统中的虚拟节点重建数据,除非该数据块也记录在快照表中(DATA 1 SNAP),如图 1-4 所示。

A449522_1_En_1_Fig4_HTML.jpg

图 1-4

Snapshotted data block

重复数据删除是一个完全独立的场景。数据块将与文件系统中已经存在的数据块进行比较,如果发现重复数据,只会向重复数据消除表中添加一个新条目。实际数据不会写入池中。参见图 1-5 。

A449522_1_En_1_Fig5_HTML.jpg

图 1-5

Deduplicated data block

ZFS 优势

对于大型企业和 SoHo 环境,有许多存储解决方案可供选择。详细介绍它们超出了本指南的范围,但是我们可以看看 ZFS 的主要优点和缺点。

简化管理

由于将卷管理、RAID 和文件系统合二为一,您只需要使用两个命令来创建卷、冗余级别、文件系统、压缩、挂载点等。这也简化了监控,因为少了两层甚至三层需要关注。

经过验证的稳定性

ZFS 自 2005 年公开发布以来,基于它部署了无数存储解决方案。我在大型企业中见过数百个大型 ZFS 仓库,我相信这个数字如果不是数千个,也是数百个。我也见过小型的 SoHo ZFS 阵列。多亏了 ZFS,两个世界都见证了巨大的稳定性和可伸缩性。

数据完整性

ZFS 的设计考虑了数据完整性。它提供了数据完整性检查、元数据校验和检查、数据故障检测(以及在冗余设置的情况下,可能修复它)以及故障设备的自动替换。

可量测性

ZFS 扩展良好,能够添加新设备、控制缓存等。

ZFS 限制

与所有文件系统一样,ZFS 也有其弱点,您需要记住这些弱点才能成功操作存储。

80%或更多原则

与大多数文件系统一样,当达到其容量的 80%或更多时,ZFS 会遭受可怕的性能损失。这是文件系统的一个常见问题。请记住,当您的池开始填充到 80%的容量时,您需要考虑扩展池或迁移到更大的设置。

您不能缩小池,因此一旦添加了驱动器或 vdevs,您就不能从中删除它们。

有限冗余类型更改

除了将单个磁盘池转换为镜像池之外,您不能更改冗余类型。一旦决定了冗余类型,更改它的唯一方法就是销毁池并创建一个新池,从备份或其他位置恢复数据。

关键术语

下面几节列出了您将会遇到的一些关键术语。

贮水池

存储池是磁盘驱动器的组合容量。一个池可以有一个或多个文件系统。在池中创建的文件系统可以看到池的所有容量,并且可以增长到整个池的可用空间。任何一个文件系统都可能占用所有可用空间,使得同一个池中的其他文件系统无法增长和包含新数据。处理这种情况的方法之一是使用空间预留和配额。

虚拟设备

vdev 是一种虚拟设备,可以由一个或多个物理驱动器组成。vdev 可以是一个池,也可以是更大池的一部分。vdev 可以具有镜像、三重镜像、RAIDZ、RAIDZ-2 或 RAIDZ-3 的冗余级别。甚至更高级别的镜像冗余也是可能的,但是不切实际且成本高昂。

文件系统

文件系统是在池的边界创建的。一个 ZFS 文件系统只能属于一个池,但是一个池可以包含多个 ZFS 文件系统。ZFS 文件系统可以有预留(最低保证容量)、配额、压缩和许多其他属性。文件系统可以嵌套,这意味着您可以在另一个文件系统中创建一个文件系统。除非您另外指定,否则文件系统将自动装入其父文件系统中。除非另外指定,否则最上面的 ZFS 文件系统的名称与池的名称相同,并自动装载在根目录下。

快照

快照是文件系统状态的时间点快照。由于 COW 语义,它们在磁盘空间方面非常便宜。创建快照意味着记录文件系统虚拟节点并跟踪它们。一旦该索引节点上的数据被更新(写入新位置—记住,它是 COW),旧的数据块将被保留。您可以通过使用所述快照来访问旧的数据视图,并且仅使用在快照时间和当前时间之间已经改变的空间。

复制

快照是只读的。如果您想要装载快照并对其进行更改,您将需要一个读写快照或克隆。克隆有许多用途,其中最大的用途之一是引导环境克隆。使用能够从 ZFS 启动的操作系统(illumos 发行版,FreeBSD),您可以创建操作系统的克隆,然后在当前文件系统或克隆中运行操作,以升级系统或安装复杂的视频驱动程序。如果需要,您可以引导回原始的工作环境,它只占用与引入的更改一样多的磁盘空间。

资料组

数据集是 ZFS 池、文件系统、快照、卷和克隆。这是可以存储和检索数据的 ZFS 层。

卷是模拟块设备的文件系统。它不能用作典型的 ZFS 文件系统。实际上,它的行为就像一个磁盘设备。它的用途之一是通过 iSCSI 或 FCoE 协议将其导出,作为 LUN 装载到远程服务器上,然后用作磁盘。

Note

就我个人而言,体积是我最不喜欢使用的 ZFS。我最喜欢的 ZFS 的许多特征对卷来说用处有限或者没有用处。如果您使用卷并对其进行快照,则不能像使用简单的 ZFS 文件系统那样轻松地在本地装载它们以进行文件检索。

再镀银

重新同步是在更换磁盘后重建冗余组的过程。您可能出于多种原因需要更换磁盘—可能是驱动器出现故障,或者您出于任何其他原因决定更换磁盘—一旦新驱动器添加到池中,ZFS 就会开始将数据恢复到其中。这是 ZFS 相对于传统突袭的一个非常明显的优势。只有数据被重新同步,而不是整个磁盘。

Note

重新同步是一个低优先级操作系统进程。在非常繁忙的存储系统上,这将需要更多时间。

泳池布局说明

池布局是将磁盘分组到虚拟设备以及将虚拟设备一起分组到 ZFS 池的方式。

假设我们有一个由六个磁盘组成的池,所有磁盘都采用 RAIDZ-2 配置(大致相当于 RAID-6)。四个磁盘包含数据,两个包含奇偶校验数据。池的弹性允许最多丢失两个磁盘。超过这个数字将会不可逆转地破坏文件系统,导致需要备份。

图 1-6 呈现了该池。虽然从技术上来说,可以创建数量更少或更多、大小不同的新 vdev,但这几乎肯定会导致性能问题。

A449522_1_En_1_Fig6_HTML.jpg

图 1-6

Single vdev RAIDZ-2 pool

请记住,一旦添加了 vdevs,就不能从池中删除磁盘。如果您突然添加一个新的 vdev,比如说四个磁盘 RAIDZ,如图 1-7 所示,您会因为引入一个弹性较低的 vdev 而损害池完整性。您还将介绍性能问题。

A449522_1_En_1_Fig7_HTML.jpg

图 1-7

Wrongly enhanced pool

“不能改变冗余级别”规则的一个例外是单个磁盘被镜像和镜像到更多镜像。您可以将一个磁盘连接到单个磁盘 vdev,这将产生一个镜像 vdev(参见图 1-8 )。你也可以将一个圆盘连接到一个双向反射镜上,形成一个三向反射镜(见图 1-9 )。

A449522_1_En_1_Fig9_HTML.jpg

图 1-9

Two way mirror into a three-way mirror

A449522_1_En_1_Fig8_HTML.jpg

图 1-8

Single vdev turned into a mirror

常见调整选项

很多教程告诉你设置两个选项(一个池级别和一个文件系统级别)来提高速度。不幸的是,他们中的大多数都没有解释他们做什么以及为什么他们应该工作:ashift=12atime= off

虽然事实是,它们可以提供显著的性能提升,但是盲目地设置它们是一个很大的错误。如前所述,要正确管理您的存储服务器,您需要了解为什么要使用所提供的选项。

变化

ashift选项允许您在磁盘上设置物理块布局。随着磁盘容量的不断增长,在某种程度上保持 512 字节的原始块大小变得不切实际,磁盘供应商将其更改为 4096 字节。但是出于向后兼容的原因,磁盘有时仍然会公布 512 块大小。这可能会对池性能产生不利影响。ZFS 引入了ashift选项,允许 ZFS 手动更改块大小。因为它被指定为二进制移位,所以值是幂,因此:2¹² = 4096。省略ashift选项允许 ZFS 检测值(磁盘可以谎报);使用值 9 会将块大小设置为 512。新的磁盘块大小称为高级布局(AL)。

ashift选项只能在池设置期间或向 vdev 添加新设备时使用。这带来了另一个问题:如果您通过设置ashift创建了一个池,然后添加了一个磁盘但没有设置它,您的性能可能会由于不匹配的ashift参数而出错。如果您知道自己使用了该选项或不确定,请务必在添加新设备之前进行检查:

trochej@madchamber:~$ sudo zpool list

NAME SIZE  ALLOC FREE  EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
data 2,72T 133G  2,59T -        3%    4% 1.00x ONLINE -   
trochej@madchamber:~$ sudo zpool get all data

NAME  PROPERTY                    VALUE                SOURCE
data  size                        2,72T                -
data  capacity                    4%                   -
data  altroot                     -                    default
data  health                      ONLINE               -
data  guid                        7057182016879104894  default
data  version                     -                    default
data  bootfs                      -                    default
data  delegation                  on                   default
data  autoreplace                 off                  default
data  cachefile                    -                    default
data  failmode                    wait                 default
data  listsnapshots               off                  default
data  autoexpand                  off                  default
data  dedupditto                  0                    default
data  dedupratio                  1.00x                -
data  free                        2,59T                -
data  allocated                   133G                 -
data  readonly                    off                  -
data  ashift                      0                    default
data  comment                     -                    default
data  expandsize                  -                    -
data  freeing                     0                    default
data  fragmentation               3%                   -
data  leaked                      0                    default
data  feature@async_destroy       enabled              local
data  feature@empty_bpobj         active               local
data  feature@lz4_compress        active               local
data  feature@spacemap_histogram  active               local
data  feature@enabled_txg         active               local
data  feature@hole_birth          active               local
data  feature@extensible_dataset  enabled              local
data  feature@embedded_data       active               local
data  feature@bookmarks           enabled              local

你可能已经注意到了,我让 ZFS 自动检测值。

smartctl 系统变量

如果您不确定驱动器的AL状态,请使用smartctl命令:

[trochej@madtower sohozfs]$ sudo smartctl -a /dev/sda

smartctl 6.4 2015-06-04 r4109 [x86_64-linux-4.4.0] (local build)
Copyright (C) 2002-15, Bruce Allen, Christian Franke,
    www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     Seagate Laptop SSHD
Device Model:     ST500LM000-1EJ162
Serial Number:    W7622ZRQ
LU WWN Device Id: 5 000c50 07c920424
Firmware Version: DEM9
User Capacity:    500,107,862,016 bytes [500 GB]
Sector Sizes:     512 bytes logical, 4096 bytes physical
Rotation Rate:    5400 rpm
Form Factor:      2.5 inches
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   ACS-2, ACS-3 T13/2161-D revision 3b
SATA Version is:  SATA 3.1, 6.0 Gb/s (current: 6.0 Gb/s)
Local Time is:    Fri Feb 12 22:11:18 2016 CET
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

您会注意到我的驱动器有这样一行:

Sector Sizes:     512 bytes logical, 4096 bytes physical            

它告诉我们 drive 的物理布局是 4096 字节,但是为了向后兼容,驱动程序公布了 512 字节。

重复数据删除

根据经验,不要重复数据删除。就是不要。如果您确实需要注意磁盘空间,请使用其他增加容量的方法。我的几个老客户在使用重复数据删除时遇到了很大的麻烦。

ZFS 有一个有趣的选择,当它被介绍的时候激发了相当多的兴趣。打开重复数据删除会告诉 ZFS 跟踪数据块。每当数据写入磁盘时,ZFS 都会将其与文件系统中已有的数据块进行比较,如果发现任何相同的数据块,它将不会写入物理数据,而是会添加一些元信息,从而节省大量的磁盘空间。

虽然这个特性在理论上看起来很棒,但在实践中却很难巧妙使用。首先,重复数据消除是有成本的,而且是在 RAM 和 CPU 能力方面的成本。对于每个正在进行重复数据删除的数据块,您的系统将向内存中的 DDT(重复数据删除表)添加一个条目。具有讽刺意味的是,对于理想的重复数据消除,RAM 中 DDT 的结果是系统由于缺少内存和 CPU 能力来执行操作系统功能而陷入停顿。

这并不是说重复数据删除没有用处。但是,在设置之前,您应该研究您的数据的重复数据删除效果如何。我可以想象通过使用重复数据消除来节省空间的备份存储。在这种情况下,必须观察 DDT 的大小、空闲 RAM 数量和 CPU 利用率,以避免出现问题。

问题是,滴滴涕是持久性的。您可以随时禁用重复数据删除,但一旦已删除的数据保持重复数据删除状态,如果您因此遇到系统稳定性问题,禁用并重新启动将无济于事。在下一次池导入(装载)时,DDT 将再次加载到 RAM 中。有两种方法可以消除这些数据:销毁池、重新创建池、恢复数据或禁用重复数据消除,或者移动池中的数据,以便在下次写入时消除重复数据。这两个选项都需要时间,具体取决于数据的大小。虽然重复数据删除可以节省磁盘空间,但请仔细研究。

默认情况下,使用zpool list命令显示重复数据删除率。比率 1.00 表示没有发生重复数据删除:

trochej@madchamber:~$ sudo zpool list

NAME SIZE  ALLOC FREE  EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
data 2,72T 133G  2,59T -        3%    4% 1.00x ONLINE -   

您可以通过查询文件系统的重复数据消除属性来检查重复数据消除设置:

trochej@madchamber:~$ sudo zfs get dedup data/datafs

NAME         PROPERTY  VALUE          SOURCE
data/datafs  dedup     off            default

重复数据消除是按文件系统设置的。

压缩

一种节省磁盘空间和提高速度的方法是压缩。有几种压缩算法可供 ZFS 使用。基本上,您可以告诉文件系统压缩它将写入磁盘的任何数据块。对于现代的 CPU,通常可以通过写入较小的物理数据来提高速度。您的处理器应该能够处理动态打包和解包数据。例外可以是压缩得很差的数据,如 MP3、jpg 或视频文件。文本数据(应用程序日志等。)通常很适合这个选项。个人用,我总是开着。ZFS 的默认压缩算法是 lzjb。

可以基于文件系统设置压缩:

trochej@madchamber:~$ sudo zfs get compression data/datafs

NAME         PROPERTY     VALUE     SOURCE
data/datafs  compression  on        local

trochej@madchamber:~$ sudo zfs set compression=on data/datafs

压缩比可以通过查询一个属性来确定:

trochej@madchamber:~$ sudo zfs get compressratio data/datafs

NAME         PROPERTY       VALUE  SOURCE
data/datafs  compressratio  1.26x  

有几种压缩算法可用。直到最近,如果您只是打开压缩,还会使用 lzjb 算法。它被认为是性能和压缩之间的一个很好的折衷。其他可用的压缩算法在zfs手册页中列出。最近增加的一个新算法是 lz4。它比 lzjb 具有更好的性能和更高的压缩比。它只能为具有feature@lz4_compress功能标记属性的池启用:

trochej@madchamber:~$ sudo zpool get feature@lz4_compress data

NAME  PROPERTY              VALUE                 SOURCE
data  feature@lz4_compress  active                local

如果启用了该功能,您可以为任何给定的数据集设置compression=lz4。您可以通过调用以下命令来启用它:

trochej@madchamber:~$ sudo zpool set feature@lz4_compress=enabled data

lz4 作为默认压缩算法已经有一段时间了。

ZFS 普尔州

如果您再次查看我的池列表:

trochej@madchamber:~$ sudo zpool list

NAME SIZE  ALLOC FREE  EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
data 2,72T 133G  2,59T -        3%   4%  1.00x ONLINE -

您会注意到一个名为HEALTH的列。这是 ZFS 游泳池的状态。您可以在这里看到其他几个指标:

  • ONLINE:池是健康的(没有检测到错误),它被导入(用传统的文件系统术语来说是挂载的)并准备好使用。这并不意味着完全没问题。即使出现少量 I/O 错误或可纠正的数据错误,ZFS 也会将池标记为在线。您还应该监控其他指标,例如磁盘健康状况(对于 LSI SAS 控制器,为hdparmsmartctllsiutil)。
  • DEGRADED:可能仅适用于冗余集,其中镜像或 RAIDZ 或 RAIDZ-2 池中的磁盘已丢失。该池可能已成为非冗余池。丢失更多磁盘可能会使其损坏。请记住,在三重镜像或 RAIDZ-2 中,丢失一个磁盘并不会使池变得不冗余。
  • FAULTED:磁盘或虚拟设备不可访问。这意味着 ZFS 不能读或写它。在冗余配置中,磁盘可能是FAULTED,但其 vdev 可能是DEGRADED,仍然可以访问。如果镜像集中有一个磁盘丢失,可能会发生这种情况。如果您丢失一个顶级 vdev,即镜像中的两个磁盘,您的整个池将无法访问并会损坏。由于没有办法恢复文件系统,您在此阶段的选择是使用健康的磁盘重新创建池,并从备份中恢复,或者寻求 ZFS 数据恢复专家的帮助。后者通常是一个昂贵的选择。
  • OFFLINE:设备已被管理员禁用(脱机)。原因可能各不相同,但这并不意味着磁盘有故障。
  • UNAVAIL:磁盘或 vdev 无法打开。实际上,ZFS 无法对其进行读写。你可能会注意到它听起来非常类似于FAULTED状态。区别主要是在FAULTED状态下,设备在被 ZFS 标记为FAULTED之前已经显示了错误次数。使用UNAVAIL,系统无法与设备对话;可能它完全没电了,或者电源太弱,无法为所有磁盘供电。最后一种情况需要记住,尤其是在商用硬件上。我不止一次碰到过消失的磁盘,只是为了弄清楚 PSU 太弱了。
  • REMOVED:如果你的硬件支持的话,当一个磁盘没有先使用zpool命令从池中移除就被物理移除时,它将被标记为REMOVED

您可以使用zpool statuszpool status -x命令明确检查池的运行状况:

trochej@madchamber:~$ sudo zpool status -x

all pools are healthy

trochej@madchamber:~$ sudo zpool status
  pool: data
 state: ONLINE
  scan: none requested

 config:

        NAME        STATE     READ WRITE CKSUM
        data        ONLINE       0     0     0
        sdb         ONLINE       0     0     0

errors: No known data errors

zpool status将打印所有池设备的详细运行状况和配置。当池包含数百个磁盘时,找出故障设备可能会很麻烦。为此,您可以使用zpool status -x,它将只打印遇到问题的池的状态。

trochej@madchamber:~$ sudo zpool status -x

  pool: data
 state: DEGRADED
status: One or more devices has been taken offline by the administrator.
        Sufficient replicas exist for the pool to continue functioning in a degraded state.
action: Online the device using 'zpool online' or replace the device with 'zpool replace'.
scrub:  resilver completed after 0h0m with 0 errors on Wed Feb 10 15:15:09 2016
config:

        NAME        STATE     READ WRITE CKSUM
        data        ONLINE       0     0     0
        mirror-0    DEGRADED     0     0     0
        sdb         ONLINE       0     0     0
        sdc         OFFLINE      0     0     0 48K resilvered

errors: No known data errors

ZFS 版本

ZFS 的设计是为了逐步引入新功能。作为这一机制的一部分,ZFS 版本是由一个单独的号码引入的。通过跟踪该数字,系统运营商可以确定他们的池是否使用最新的 ZFS 版本,包括新功能和错误修复。升级就地完成,不需要任何停机时间。

当 ZFS 仅由太阳微系统公司开发时,这一理念运行得相当好。随着 OpenZFS 社区的出现——聚集了来自 illumos、Linux、OSX 和 FreeBSD 世界的开发人员——很快就变得很明显,很难(如果不是不可能的话)在整个社区中就每一个磁盘格式变化达成一致。因此,版本号保持在甲骨文公司作为开源发布的最新版本:28。从那时起,引入了“特性标志”的可插拔架构。如果 ZFS 实现实现了相同的功能标志集,那么它们就是兼容的。

如果您再次查看我的主机的zpool命令输出:

trochej@madchamber:~$ sudo zpool get all data

NAME  PROPERTY                    VALUE                SOURCE
data  size                        2,72T                -
data  capacity                    4%                   -
data  altroot                     -                    default
data  health                      ONLINE               -
data  guid                        7057182016879104894  default
data  version                     -                    default
data  bootfs                      -                    default
data  delegation                  on                   default
data  autoreplace                 off                  default
data  cachefile                    -                    default
data  failmode                    wait                 default
data  listsnapshots               off                  default
data  autoexpand                  off                  default
data  dedupditto                  0                    default
data  dedupratio                  1.00x                -
data  free                        2,59T                -
data  allocated                   133G                 -
data  readonly                    off                  -
data  ashift                      0                    default
data  comment                     -                    default
data  expandsize                  -                    -
data  freeing                     0                    default
data  fragmentation               3%                   -
data  leaked                      0                    default
data  feature@async_destroy       enabled              local
data  feature@empty_bpobj         active               local
data  feature@lz4_compress        active               local
data  feature@spacemap_histogram  active               local
data  feature@enabled_txg         active               local
data  feature@hole_birth          active               local
data  feature@extensible_dataset  enabled              local
data  feature@embedded_data       active               local
data  feature@bookmarks           enabled              local

您会注意到最后几个属性以feature@字符串开始。这就是你需要寻找的特征标志。找出所有支持的版本和功能标志,运行sudo zfs upgrade -vsudo zpool upgrade -v命令,,如下例所示:

trochej@madchamber:~$ sudo zfs upgrade -v

The following file system versions are supported:

VER  DESCRIPTION
---  --------------------------------------------------------
 1   Initial ZFS file system version
 2   Enhanced directory entries
 3   Case insensitive and file system user identifier (FUID)
 4   userquota, groupquota properties
 5   System attributes

For more information on a particular version, including supported
releases, see the ZFS Administration Guide.

trochej@madchamber:~$ sudo zpool upgrade -v

This system supports ZFS pool feature flags.

The following features are supported:

FEAT DESCRIPTION
-------------------------------------------------------------
async_destroy                         (read-only compatible)
     Destroy file systems asynchronously.
empty_bpobj                           (read-only compatible)
     Snapshots use less space.
lz4_compress                         
     LZ4 compression algorithm support.
spacemap_histogram                    (read-only compatible)
     Spacemaps maintain space histograms.
enabled_txg                           (read-only compatible)
     Record txg at which a feature is enabled
hole_birth                           
     Retain hole birth txg for more precise zfs send
extensible_dataset                   
     Enhanced dataset functionality, used by other features.
embedded_data                        
     Blocks which compress very well use even less space.
bookmarks                             (read-only compatible)
     "zfs bookmark" command

The following legacy versions are also supported:

VER  DESCRIPTION
---  --------------------------------------------------------
 1   Initial ZFS version
 2   Ditto blocks (replicated metadata)
 3   Hot spares and double parity RAID-Z
 4   zpool history

 5   Compression using the gzip algorithm
 6   bootfs pool property
 7   Separate intent log devices
 8   Delegated administration
 9   refquota and refreservation properties
 10  Cache devices
 11  Improved scrub performance
 12  Snapshot properties
 13  snapused property
 14  passthrough-x aclinherit
 15  user/group space accounting
 16  stmf property support
 17  Triple-parity RAID-Z
 18  Snapshot user holds
 19  Log device removal
 20  Compression using zle (zero-length encoding)
 21  Deduplication
 22  Received properties
 23  Slim ZIL
 24  System attributes
 25  Improved scrub stats
 26  Improved snapshot deletion performance
 27  Improved snapshot creation performance
 28  Multiple vdev replacements

For more information on a particular version, including
supported releases, see the ZFS Administration Guide.

这两个命令都打印最高级别的 ZFS 池和文件系统版本的信息,并列出可用的功能标志。

您可以使用zpool upgradezfs upgrade命令检查您的池和文件系统的当前版本:

trochej@madchamber:~$ sudo zpool upgrade

This system supports ZFS pool feature flags.

All pools are formatted using feature flags.

Every feature flags pool has all supported features enabled.

trochej@madchamber:~$ sudo zfs upgrade

This system is currently running ZFS file system version 5.

All file systems are formatted with the current version.

Linux 是服务器领域的主流操作系统。在大多数情况下,ZFS 是一个非常好的存储文件系统。与传统的 RAID 和卷管理解决方案相比,它带来了几个优势—使用简单、数据修复功能、改进的操作系统间迁移能力等等。ZFS 处理虚拟设备。虚拟设备可以直接映射到物理磁盘,也可以映射到一组其他虚拟设备。用作文件系统空间的一组 vdevs 称为 ZFS 池。其中的文件系统称为文件系统。ZFS 文件系统可以嵌套。管理池是通过zpool命令完成的。文件系统的管理由zfs命令完成。

二、硬件

在为存储购买硬件之前,有几件事需要考虑。你需要多少磁盘空间?您的存储将服务多少个客户端连接(会话)?您将使用哪种协议?您计划提供什么样的数据?

不要着急

你应该永远记住的第一条建议是:不要操之过急。你将要投资你的金钱和时间。虽然您以后可以根据需要修改存储,但某些更改将要求您重新创建 ZFS 池,这意味着其上的所有数据都将丢失。如果您购买了错误的磁盘(例如,它们太小),您将需要添加更多磁盘,并且可能会耗尽可用插槽或电源。

考虑

在开始确定存储范围之前,您应该问自己几个问题。您在此给出的答案将在以后的部署中发挥关键作用。

多少数据?

您希望存储的数据量将决定您需要购买的磁盘数量和大小。它还会影响其他因素,如服务器大小。要确定您的空间需求,您需要评估您当前拥有的数据量及其增长速度。考虑您要运行您正在构建的存储多长时间。可能你计划在三年内完全替换它,因此不必非常小心。您可能不知道何时会实施新的存储,因此需要增加一些利润。看看你的组织发展计划。你打算在三年内将办公室人员的数量增加一倍吗?都是要出数据吗?这意味着三年后,数据的增长速度将至少是现在的三倍。

有多少并发客户端?

并发客户端连接数决定了您需要的 RAM 数量。如果你考虑使用固态硬盘,你可以购买固态硬盘作为存储的二级缓存,放弃使用 SATA 硬盘。即使您要存储数百 TB 的数据,但只有少数客户机会使用它,而且不是非常集中,您也可以使用少量的内存。这也将决定服务器中网络接口的类型以及它应该连接的交换机的类型。

数据有多重要?

您的数据有多重要?如果是任务关键型的,可以考虑经认证的、可能更贵的硬件,众所周知,这些硬件性能良好,使用时间更长。数据的重要性还会告诉您应该使用哪个冗余级别,这会影响最终成本。我从各种数据中心获得的个人经验表明,SATA 磁盘的故障速度比 SAS 磁盘快得多。

什么类型的数据?

您将提供的数据类型可能会影响您的存储池的体系结构。为大量客户端传输视频文件或为虚拟机和数据文件提供服务很可能意味着您需要使用镜像,这将直接影响阵列的最终容量和最终成本。

什么样的范围?

首先,为本指南中的 SoHo 存储创建一个上限:

  • 考虑到您当前的磁盘大小,单个节点中最多 12 个插槽,以及最多 30 TB 的原始容量。
  • 内部 SAS 或 SATA 驱动器。
  • 一个或两个插槽用于最终的固态硬盘,以加快读取速度。
  • 可能是一个镜像 ZIL 设备,用于加速和连接对磁盘的写入。一个系统驱动器,可能是镜像的,尽管目前在 ZFS 上安装 Linux 系统并不容易,也不推荐从 ZFS 启动。
  • 高达 128 GB 的内存,可能是 64。
  • 具有四个或更多内核的 64 位 CPU。虽然在 32 位系统上运行 ZFS 是可能的,但肯定不推荐这样做。

如果您打算使用通过 SAS 或光纤通道连接的外部磁盘箱(JBODS ),这本书可能不适合您。可以手动设置和管理此类存储,许多人已经这样做了,但这可能涉及本指南中未涉及的其他步骤。如果您想运行几十或几百个磁盘,请帮自己一个忙,考虑免费 NAS 甚至付费支持的商业解决方案。跟踪系统性能、内存使用、磁盘、控制器和电缆健康状况可能最好由专业产品来管理。

硬件购买指南

硬件通常是一项长期投资。请记住以下几点。

同一供应商,不同批次

购买磁盘时,通常的做法是确保从相同的供应商和型号购买每个磁盘,以保持几何形状和固件相同,但来自不同的批次,这样可以最大限度地降低几个磁盘同时损坏的风险。我认为对于一个小买家(几个到 20 个磁盘),最简单的方法是从不同的商店购买磁盘。这可能很麻烦,但是存储操作员已经多次看到磁盘批次同时出现故障。

买几件备用的

存储系统的寿命通常以年为单位计算,并且通常比磁盘型号更长,尤其是当您决定使用消费级 SATA 磁盘时。当其中一款几年后出现故障时,你可能会惊讶地发现,你再也买不到这款产品了。在池中引入不同的池总是有性能风险。如果发生这种情况,不要绝望。ZFS 允许您交换一个池中的所有磁盘。过去,当池变得不足时,这种技巧被用来增加池的大小。请注意,在已满且繁忙的系统上,更换 10 个磁盘的池中的所有磁盘可能需要数周时间。

正确确定电源范围

如果您的电源不稳定或不足,您可能会遇到神秘的故障(磁盘消失、磁盘连接断开或池的随机 I/O 错误)或根本无法使用您的磁盘。

考虑性能,规划内存

就性能而言,磁盘越多越好。磁盘越小越好。ZFS 线程在 vdevs 之间读写。vdevs 越多,读/写线程就越多。计划更多内存。ZFS 需要至少 2 GB 的内存才能正常工作,但对于任何实际使用,不要低于 8 GB。对于 SoHo 的存储系统,我建议考虑 64 GB 或更多。ZFS 非常积极地缓存数据,所以它会尝试使用尽可能多的 RAM。但是,当系统需要 RAM 来进行正常操作(比如运行新程序)时,它就会让步。所以你的记忆中能容纳的越多越好。

规划固态硬盘(至少三个)

你不需要预先购买它们。ZFS 是一个混合存储文件系统,这意味着它可以将 SSD 磁盘用于二级缓存。它会比你的内存慢得多,但它更便宜,而且仍然比你的盘片快得多。只需花 RAM 价格的一小部分,你就可以得到一个 512 GB 的固态硬盘,这应该可以进一步提高速度。这是一块固态硬盘。两个固态硬盘用于外部 ZFS 意向日志。文件系统不会一直将所有数据刷新到物理存储中。它将写入绑定在事务中,并同时刷新多个事务,以最大限度地减少文件系统碎片和对磁盘的实际 I/O。

如果你给 ZFS ZIL 的外部设备,它可以通过在刷新之前分组更多的数据来加快速度。这个额外的池设备应该被镜像,因为它是您可能丢失数据的地方。在电源故障的情况下,外部 ZIL 上的数据必须是持久的。有模拟小型 SSD 磁盘(即 ZeusRAM)的电池备份 DRAM 设备。它们有 8gb 和 16 GB 两种尺寸,这对于 ZIL 来说已经足够了。它们和内存一样快,但是很贵。你也可以考虑镜像你的 L2ARC(二级缓存),但是丢失这个设备不会危及你的数据。

考虑 SATA

虽然 SAS 标准肯定会从您的磁盘获得更好的性能和预期寿命,但对于 SoHo solutions 来说,SATA 就足够了,尤其是当您考虑到有企业级 SATA 磁盘时。这种部署的价格差异应该不会很高。如果你不确定,在预算允许的情况下选择 SAS。

不要购买硬件和软件 RAID 控制器

虽然在过去,RAID 卡是卸载 CPU 单元和 RAM 所必需的,但这两种资源现在都很丰富而且便宜。你的 CPU 和内存对于工作负载来说是绰绰有余的,RAID 卡夺走了 ZFS 的一项重要功能。ZFS 通过直接与磁盘对话来确保数据安全:获取关于数据何时刷新到物理磁盘以及正在使用的块大小的可靠信息。

RAID 控制器介于两者之间,可以对 I/O 进行自己的“优化”,这可能会降低 ZFS 的可靠性。另一件事是,RAID 控制器在不同的供应商之间是不兼容的,甚至同一张卡,但不同的固件版本可能无法访问您的 RAID 磁盘阵列。这意味着在控制器出现故障的情况下,您会丢失整个设置,并且需要从备份中恢复数据。软突袭甚至更糟,因为它们需要特殊的软件(通常仅限于一个操作系统)才能实际工作。

ZFS 在所有这些方面都很优秀。它不仅可以使用您可以给它的所有处理能力和所有 RAM 来加速 I/O,而且池中的磁盘还可以在实现相同 OpenZFS 版本的所有软件平台之间迁移。此外,磁盘在磁盘插槽中的确切顺序并不重要,因为池会根据磁盘设备名称(即/dev/sdb)以及 ZFS 在创建池期间为其提供的磁盘 GUID 来记忆其配置。

至少 1 GB 速度的网卡

请记住,此服务器网卡的带宽将分布在所有同时使用存储的机器上。考虑 10 GB 是非常明智的,但是您还需要考虑其他网络设备—交换机、电缆等。请记住,网络在性能分析中起着重要作用,相当多的性能问题不是由存储本身引起的,而是由网络层引起的。对于办公室中的重要工作,我建议使用不低于 10GB 的网卡。在存储不会被广泛使用的非常小的环境中,1GB 是可以接受的。任何不足都会很快变得不方便。

冗余计划

一直都是。这意味着对于高速读取池,您需要考虑镜像存储,从而有效地将您购买的磁盘的总容量减半。RAIDZ 设置意味着您每创建一个 vdev,容量就会减少一个磁盘。对于 RAIDZ-2,它将是两个磁盘。

数据安全

您将使用 ZFS 存储来保存数据,并将其提供给公司中的不同人员。不管是两个人、十个人还是五十个人,都要花些心思来规划布局。各种存储不同种类、敏感度和可压缩性的数据的目录在将来会有所回报。设计良好的目录结构将简化组织方面的事情,如访问控制和技术方面,如启用或禁用压缩、时间选项等。

ZFS 文件系统的行为类似于目录。例如,为每个用户主目录创建一个单独的 ZFS 文件系统是很常见的,这样他们就可以拥有细粒度的备份策略、ACL 和压缩机制。

您需要考虑您的公司规模、访问存储的员工数量、增长前景、数据敏感性等。然而,无论你做什么,不要跳过这一点。我见过不少公司忽略了他们需要从自由发展的基础设施转变为工程化的基础设施的时刻。

中央情报局(Central Intelligence Agency)

有许多数据安全方法,其中之一,我认为是最经典的,使用缩写 CIA 来解释数据安全的各个方面。这代表机密性、完整性和可用性。虽然它更侧重于信息安全方面,但它也是存储管理的一个很好的视角。接下来的部分将从存储管理员的角度介绍这些概念。

机密

数据必须只对受托人开放。没有被明确允许查看数据的任何人都不能访问数据。许多基础设施工具涵盖了这方面的安全性,从允许查看数据的人员应该阅读和签名的策略和 NDA,到网络访问隔离(VPN、VLANs、通过凭据的访问控制)。还有一些方面与存储本身直接相关:访问控制列表(ACL)、通过安全协议和在安全网络中共享、使用存储防火墙等。

完整

必须保证数据是真实的,并且没有被不受信任的人更改。此外,如果不应该,改变不应该由软件或硬件有意或无意地引入。在整个数据生命周期中,只有拥有足够权限的人才能修改数据。无意的数据完整性破坏可能是破坏数据块的磁盘故障。虽然文本数据通常很容易被发现,但对于声音或视频等其他数据,就比较难了,因为与原始状态可能会有细微的差异。与安全性的所有方面一样,它也只是由存储部分管理。数据完整性由 ACL 覆盖,但也由 ZFS 校验和数据块来检测损坏。如果您的设置使用了任何冗余,ZFS 可以在很大程度上使用冗余集为您解决这些问题。

有效

数据应该在需要和保证的任何时候都可用。这可能是存储最明显的方面之一。任何时候,只要您认为您的数据应该是可用的,数据就应该是可用的。通常,存储冗余在这里起作用(mirror、RAIDZ 和 RAIDZ-2),但网卡中继、交换机堆叠和您使用的任何凭证检查解决方案的冗余也起作用(例如,Active Directory 服务器、主服务器和辅助服务器)。

工作量的类型

您将在存储上运行的工作负载将在您应如何规划池布局中发挥重要作用。

如果您将主要托管数据库,并且它们将成为该空间的主要消费者,L2ARC SSD 设备可能不会为您提供特殊的性能提升。数据库非常擅长缓存自己的数据,如果数据恰好适合数据库服务器 RAM,那么 ARC 就没有太多事情要做。另一方面,如果数据库中的数据经常变化,并且需要从磁盘中重新读取,那么无论如何,您都会有很高的未命中率,而且 L2ARC 设备也不会达到它的目的。

快照数据也将变得棘手。为了能够处理数据,数据库需要的不仅仅是文件系统的快照。这就是它们自带转储命令的原因——因为完整的工作备份通常包含比数据库文件中更多的内容。托管数据库通常意味着您在与 ZFS 相同的主机上运行引擎。同样,数据库将比文件系统本身更有效地使用 RAM。但是,请考虑一下,如果您将同一台服务器上的数据用于其他目的,比如 CIFS 或 NFS 共享。在这种情况下,数据库和文件系统缓存可能会争用 RAM。虽然这不会影响系统稳定性,但可能会对性能产生负面影响。

如果您为办公室工作人员存放文档和图片、程序之类的文件以及技术文档,L2ARC 设备是值得认真考虑的。因此,快照是在特定时间点捕获数据的可靠方式。如果您的数据不是一天 24 小时都被访问,并且您只有几秒钟的非工作时间,那么快照可以在指定的时间点可靠地承载您的数据。通常需要一秒钟来创建。您可以稍后装载此快照(记住它是只读的)并将其传输到备份位置,而不用担心数据完整性。

最重要的是,不要操之过急。如果性能测试不令人满意,您可以随时将 L2ARC 添加到您的池中。

要注意的其他组件

关注其他基础设施元素非常重要。该网络具有特殊的意义。在只有几个人的小公司中,将工作站改装成存储服务器的小型交换机可能不会有任何问题,但是一旦数据消费者的数量开始增长,这种网络可能很快就会成为瓶颈。开关可能不是唯一的限制因素。存储服务器中的网卡可能是另一个原因。此外,如果你从远程位置通过 VPN 提供你的数据,结果可能是链接太慢。在存储性能分析案例中,我们经常能够指出网络基础架构是故障元素。

硬件清单

不要着急。在购买硬件之前,坐下来用一张纸或你的笔记本电脑列一个清单。想想你需要多少空间,以及这种需求在几年后会如何增长。想想你的预算。能花多少钱?计算您将连接到存储的机器数量,并描述将要服务的流量类型。很多小文件?几千兆字节大小的大文件?计划一些测试,假设你需要几天时间来做。

三、设备

本章介绍了 ZFS 模块在您选择的 Linux 发行版中的基本安装。Ubuntu 允许快速安装和设置,所以我们将使用它作为一个例子。

系统包

在继续下一步之前,您需要从标准发行版本库中安装一些包。

虚拟计算机

在购买硬件并在裸机上运行测试之前,您可能希望在虚拟机中安装并测试 ZFS。这是一个好主意,我鼓励你这样做。您可能会以一种非常简单有效的方式习惯于管理 ZFS 池。您还可以检查哪个发行版更适合您。对虚拟化引擎没有要求。您可以使用 VirtualBox、VMware、KVM、Xen 或任何您觉得合适的虚拟机。请记住,您使用的工具应该能够为您的客户机提供虚拟磁盘来使用。虽然您可以在 VM 中创建的文件上创建一个池,但我不推荐这种测试方式。

Note

请记住,虚拟机不适合进行性能测试。太多的因素阻碍了可靠的结果。

Ubuntu 服务器

如果出于某种原因,您运行的是 15.10 之前的 Ubuntu,您将需要添加一个特殊的 PPA 库:

trochej@ubuntuzfs:~$ sudo add-apt-repository ppa:zfs-native/stable

[sudo] password for trochej:
 The native ZFS filesystem for Linux. Install the ubuntu-zfs package.

Please join this Launchpad user group if you want to show support for ZoL:

  https://launchpad.net/~zfs-native-users

Send feedback or requests for help to this email list:

  http://list.zfsonlinux.org/mailman/listinfo/zfs-discuss

Report bugs at:

  https://github.com/zfsonlinux/zfs/issues  (for the driver itself)
  https://github.com/zfsonlinux/pkg-zfs/issues (for the packaging)

The ZoL project home page is:

  http://zfsonlinux.org/
 More info: https://launchpad.net/~zfs-native/+archive/ubuntu/stable
Press [ENTER] to continue or ctrl-c to cancel adding it

gpg: keyring `/tmp/tmp4_wvpmaf/secring.gpg' created
gpg: keyring `/tmp/tmp4_wvpmaf/pubring.gpg' created
gpg: requesting key F6B0FC61 from hkp server keyserver.ubuntu.com
gpg: /tmp/tmp4_wvpmaf/trustdb.gpg: trustdb created
gpg: key F6B0FC61: public key "Launchpad PPA for Native ZFS for Linux" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
OK

在 Ubuntu 15.10 和更高版本中,ZFS 支持包已经包含在标准库中。您需要安装以下软件包:

trochej@ubuntuzfs:~$ sudo apt-get install zfsutils-linux

这将为您编译合适的内核模块。稍后,您可以通过运行lsmod来确认它们已经构建并实际加载:

trochej@ubuntuzfs:~$ sudo lsmod | grep zfs

zfs                  2252800  0
zunicode              331776  1 zfs
zcommon                53248  1 zfs
znvpair                90112  2 zfs,zcommon
spl                   102400  3 zfs,zcommon,znvpair
zavl                   16384  1 zfs

现在,您应该能够创建一个池了:

trochej@ubuntuzfs:~$ sudo zpool create -f datapool \
    mirror /dev/sdb /dev/sdc \
    mirror /dev/sdd /dev/sde \
    mirror /dev/sdf /dev/sdg

trochej@ubuntuzfs:~$ sudo zpool status
  pool: datapool
 state: ONLINE
  scan: none requested
 config:

    NAME        STATE     READ WRITE CKSUM
    datapool    ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
        sdb     ONLINE       0     0     0
        sdc     ONLINE       0     0     0
      mirror-1  ONLINE       0     0     0
        sdd     ONLINE       0     0     0
        sde     ONLINE       0     0     0
      mirror-2  ONLINE       0     0     0
        sdf     ONLINE       0     0     0
        sdg     ONLINE       0     0     0

errors: No known data errors

您将需要安装另一个软件包:

trochej@ubuntuzfs:~$ sudo apt-get install zfs-zed

zed 是一个 ZFS 事件守护进程。这是一个守护程序服务,将监听任何 ZFS 生成的内核事件。下一节将对此进行更详细的解释。

CentOS

您将需要一个默认情况下不会安装的系统信息工具来对您的设置进行监控、故障排除和测试:

[root@localhost ~]# yum install sysstat

与 Ubuntu 相反,CentOS 的存储库中默认没有 ZFS 软件包,无论是 6.7 还是 7 版本都没有。因此你需要遵循这里的指示: http://zfsonlinux.org/epel.html

CentOS 7 的安装完全相同,除了软件包名称:

[root@CentosZFS ~]# yum localinstall --nogpgcheck https://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

[root@CentosZFS ~]# yum localinstall --nogpgcheck http://archive.zfsonlinux.org/epel/zfs-release.el6.noarch.rpm
[root@CentosZFS ~]# yum install -y kernel-devel zfs

一段时间后,您应该准备好探测和使用 ZFS 模块:

[root@CentosZFS ~]# modprobe zfs

[root@CentosZFS ~]# lsmod | grep zfs

zfs                  2735595  0
zcommon                48128  1 zfs
znvpair                80220  2 zfs,zcommon
spl                    90378  3 zfs,zcommon,znvpair
zavl                    7215  1 zfs
zunicode              323046  1 zfs

现在,您可以在连接的磁盘上创建池了:

[root@CentosZFS ~]# zpool create -f datapool mirror /dev/sdb /dev/sdc mirror /dev/sdd /dev/sde

[root@CentosZFS ~]# zpool status

  pool: datapool
 state: ONLINE
  scan: none requested
 config:

    NAME        STATE     READ WRITE CKSUM
    datapool    ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
        sdb     ONLINE       0     0     0
        sdc     ONLINE       0     0     0
      mirror-1  ONLINE       0     0     0
        sdd     ONLINE       0     0     0
        sde     ONLINE       0     0     0

errors: No known data errors

这段代码为您安装了前面提到的 ZED。

系统工具

你需要一些系统工具。习惯他们。

  • smartctl:smartmontools 包包含两个实用程序(smartctlsmartd),用于控制和监控存储系统。它使用内置于大多数现代 ATA/SATA、SCSI/SAS 和 NVMe 磁盘中的自我监控、分析和报告技术系统(SMART)。
  • 告诉你你有什么块设备。它将帮助您确定在设置 ZFS 池时将使用的驱动器名称。
  • blkid:帮助您识别已经被其他文件系统使用的驱动器。你可能也想用mountdf来达到这个目的。

z 字母

如前所述,zed 是一个守护进程,它将监听与 ZFS 相关的内核事件。一旦接收到事件,它将执行所谓的 ZEDLETs 中定义的任何操作,这是一个脚本或程序,将执行它应该做的任何操作。ZED 是一个 Linux 特有的守护进程。在 illumos 发行版中,FMA 是负责执行纠正措施的层。

编写 ZEDLETs 是超出本指南范围的主题,但是这个守护进程对于两个重要任务是必不可少的:监控和报告(通过邮件)池的健康状况,以及用热备盘替换故障驱动器。

即使负责将驱动器标记为故障的是 ZFS,更换操作也需要由单独的实体来执行。

要使这些操作生效,请在安装守护程序后,打开其配置文件。通常出现在/etc/zfs/zed.d/zed.rc:

# zed.rc

# Absolute path to the debug output file.

# ZED_DEBUG_LOG="/tmp/zed.debug.log"

# Email address of the zpool administrator.

#   Email will only be sent if ZED_EMAIL is defined.

ZED_EMAIL="admin@example.net"

# Email verbosity.

#   If set to 0, suppress email if the pool is healthy.

#   If set to 1, send email regardless of pool health.

#ZED_EMAIL_VERBOSE=0

# Minimum number of seconds between emails sent for a similar event.

#ZED_EMAIL_INTERVAL_SECS="3600"

# Default directory for zed lock files.

#ZED_LOCKDIR="/var/lock"

# Default directory for zed state files.

#ZED_RUNDIR="/var/run"

# The syslog priority (eg, specified as a "facility.level" pair).

ZED_SYSLOG_PRIORITY="daemon.notice"

# The syslog tag for marking zed events.

ZED_SYSLOG_TAG="zed"

# Replace a device with a hot spare after N I/O errors are detected.

#ZED_SPARE_ON_IO_ERRORS=1

# Replace a device with a hot spare after N checksum errors are detected.

#ZED_SPARE_ON_CHECKSUM_ERRORS=10

注意ZED_EMAILZED_SPARE_ON_IO_ERRORSZED_SPARE_ON_CHECKSUM_ERRORS。如果需要此功能,请取消对它们的注释。

您可以通过使用带有或不带有-v开关的zpool events来查看 zed 将监听的内核消息。如果没有开关,您将会收到一个类似于下面的列表:

trochej@ubuntuzfs:~$ sudo zpool events
TIME                           CLASS
Feb 15 2016 17:43:08.213103724 resource.fs.zfs.statechange
Feb 15 2016 17:43:08.221103592 resource.fs.zfs.statechange
Feb 15 2016 17:43:08.221103592 resource.fs.zfs.statechange
Feb 15 2016 17:43:08.661096327 ereport.fs.zfs.config.sync
Feb 15 2016 18:07:39.521832629 ereport.fs.zfs.zpool.destroy

这些应该是非常明显的,在这种情况下,它与池的创建、导入和销毁直接相关。

使用-v开关,输出更加详细:

trochej@ubuntuzfs:~$ sudo zpool events -v
TIME                           CLASS
Feb 15 2016 17:43:08.213103724 resource.fs.zfs.statechange
    version = 0x0
    class = "resource.fs.zfs.statechange"
    pool_guid = 0xa5c256340cb6bcbc
    pool_context = 0x0
    vdev_guid = 0xba85b9116783d317
    vdev_state = 0x7
    time = 0x56c2001c 0xcb3b46c
    eid = 0xa

Feb 15 2016 17:43:08.213103724 resource.fs.zfs.statechange
    version = 0x0
    class = "resource.fs.zfs.statechange"
    pool_guid = 0xa5c256340cb6bcbc
    pool_context = 0x0
    vdev_guid = 0xbcb660041118eb95
    vdev_state = 0x7
    time = 0x56c2001c 0xcb3b46c
    eid = 0xb

四、设置

我们已经介绍了各种池布局性能问题,现在是时候考虑给定冗余类型的经验法则了。

Note

我们不会报道条纹泳池。条带池是由两个或更多不提供冗余的磁盘组成的池。虽然总池容量等于池中所有磁盘容量的总和,但如果您丢失一个驱动器,文件系统将会损坏,并且会受到数据恢复的影响。存储的经验法则是:不要使用条带化池。

总则

对于镜像池,一个很好的经验法则是,只有当您确实需要令人难以置信的读取性能或者对您的存储有疑虑时,才使用它们。磁盘不会经常出现故障,镜像池会使您的总池容量减半。使用三重镜像,您的容量将是磁盘总容量除以三,依此类推。一条经验法则是谨慎小心地使用它们。

对于 RAIDZ(大致相当于 RAID-5 和 RAID-6),更适合 RAIDZ-2。它给你很好的弹性,同时节省了很多空间。还有另一个建议,根据我的个人经验,我会坚持它:对于 RAIDZ 池,每个 vdev 有 2n+1 个磁盘。那是三,五,七,等等。,但不超过 11 个。这是 2n 个数据磁盘加上 1 个奇偶校验数据磁盘。

对于每个 vdev 三个磁盘的最小集合,您基本上拥有读取性能较低的镜像集的容量。考虑从每个 vdev 五个磁盘开始。对于 RAIDZ-2,规则是使用 2x+2 个磁盘,即 4、6、8 个磁盘,等等。,并且一个 vdev 中不超过 12 个磁盘。根据本指南,池中的典型目标最大数量为 20 个磁盘(包括 ZIL 和 L2ARC)。池中最好有两个八磁盘的 RAIDZ-2 vdev,总共 16 个磁盘,池总容量为 12 个磁盘。

创建镜像池

因为我已经在前面的章节中向您展示了如何创建简单的池,所以现在没有必要演示这个。因此,我将直接跳到更复杂的配置。但是,请记住,对于单个节点,设置选项是有限的。

提醒一下,我们根本不打算介绍条带化池。在这样的设置中,您的池将完全没有弹性,并且您永远不应该考虑使用这样的配置来托管您所关心的数据。

在运行任何可能危及您的数据的命令之前,尤其是在生产中,即zpool createzpool destroy,请确认您要使用的磁盘是您打算由 ZFS 使用的磁盘。

我们已经介绍了一个简单的镜像池,现在让我们创建一个包含 10 个磁盘的更大的镜像池。我将使用zpool status来打印最终的池配置:

trochej@ubuntuzfs:~$ sudo zpool create -f datapool mirror /dev/sdb /dev/sdc \
mirror /dev/sdd /dev/sde \
mirror /dev/sdf /dev/sdg \
mirror /dev/sdh /dev/sdi \
mirror /dev/sdj /dev/sdk

trochej@ubuntuzfs:~$ sudo zpool status

  pool: datapool
 state: ONLINE
  scan: none requested
 config:

        NAME        STATE     READ WRITE CKSUM
        datapool    ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sdb     ONLINE       0     0     0
            sdc     ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            sdd     ONLINE       0     0     0
            sde     ONLINE       0     0     0
          mirror-2  ONLINE       0     0     0
            sdf     ONLINE       0     0     0
            sdg     ONLINE       0     0     0
          mirror-3  ONLINE       0     0     0
            sdh     ONLINE       0     0     0
            sdi     ONLINE       0     0     0
          mirror-4  ONLINE       0     0     0
            sdj     ONLINE       0     0     0
            sdk     ONLINE       0     0     0

errors: No known data errors

得到的池总容量等于池中所有磁盘容量的一半:

trochej@ubuntuzfs:~$ sudo zpool list

NAME       SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP DEDUP  HEALTH  ALTROOT
datapool  9.92G    64K  9.92G         -     0%     0%  1.00x  ONLINE  -

该池安装在/datapool处,包含一个名为datapool的文件系统,您可以在下面的输出中看到:

trochej@ubuntuzfs:~$ sudo zfs list

NAME       USED  AVAIL  REFER  MOUNTPOINT
datapool    58K  9.77G    19K  /datapool

创建 RAIDZ 池

我在所有示例中重用了相同的磁盘。在为它们创建新池之前,我将在池中运行zpool destroy。它就是这样做的:它将一个池标记为已销毁,并将磁盘标记为可供其他 ZFS 系统使用。当 ZFS 将磁盘添加到池中时,它会用自己的 GUID 和一些允许 ZFS 独立存在的信息对其进行标记。您可以四处移动池,从当前服务器导出,将服务器重新安装到 FreeBSD,然后导入同一个池,不会出现问题。因此,如果您决定不再需要该池并尝试将磁盘重新用于其他配置,zpool将拒绝在不使用-f开关的情况下将其添加到新的池中。

trochej@ubuntuzfs:~$ sudo zpool destroy datapool
[sudo] password for trochej:

我正在使用的虚拟机有 12 个磁盘用作存储:

trochej@ubuntuzfs:~$ ls -ahl /dev/sd[a-z]

brw-rw---- 1 root disk 8,   0 Feb 12 21:59 /dev/sda
brw-rw---- 1 root disk 8,  16 Feb 15 17:43 /dev/sdb
brw-rw---- 1 root disk 8,  32 Feb 15 17:43 /dev/sdc
brw-rw---- 1 root disk 8,  48 Feb 15 17:43 /dev/sdd
brw-rw---- 1 root disk 8,  64 Feb 15 17:43 /dev/sde
brw-rw---- 1 root disk 8,  80 Feb 15 17:43 /dev/sdf
brw-rw---- 1 root disk 8,  96 Feb 15 17:43 /dev/sdg
brw-rw---- 1 root disk 8, 112 Feb 15 17:43 /dev/sdh
brw-rw---- 1 root disk 8, 128 Feb 15 17:43 /dev/sdi
brw-rw---- 1 root disk 8, 144 Feb 15 17:43 /dev/sdj
brw-rw---- 1 root disk 8, 160 Feb 15 17:43 /dev/sdk
brw-rw---- 1 root disk 8, 176 Feb 12 21:59 /dev/sdl
brw-rw---- 1 root disk 8, 192 Feb 12 21:59 /dev/sdm

/dev/sda是系统盘,留给我们的是从/dev/sdb/dev/sdm的盘。这意味着 12 个磁盘用作存储。让我们按照之前提到的每个 vdev 五个磁盘的最佳做法来创建一个 RAIDZ 池:

trochej@ubuntuzfs:~$ sudo zpool create datapool \
        raidz /dev/sdb /dev/sdc \
        /dev/sdd /dev/sde /dev/sdf \
        raidz /dev/sdg /dev/sdh \
        /dev/sdi /dev/sdj /dev/sdk

trochej@ubuntuzfs:~$ sudo zpool status

  pool: datapool
 state: ONLINE
  scan: none requested
 config:

        NAME        STATE     READ WRITE CKSUM
        datapool    ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            sdb     ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0
            sde     ONLINE       0     0     0
            sdf     ONLINE       0     0     0
          raidz1-1  ONLINE       0     0     0
            sdg     ONLINE       0     0     0
            sdh     ONLINE       0     0     0
            sdi     ONLINE       0     0     0
            sdj     ONLINE       0     0     0
            sdk     ONLINE       0     0     0

errors: No known data errors

trochej@ubuntuzfs:~$ sudo zpool list

NAME       SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
datapool  19.8G   106K  19.7G         -     0%     0%  1.00x  ONLINE  -

此处显示的设置可以承受每个 vdev 同时丢失一个磁盘。如果两个磁盘未使用,您可以添加所谓的热备盘。热备盘是添加到池中的空闲磁盘,用于在池中的任何活动磁盘出现故障时进行替换。替换由 ZFS 自动完成。热备盘机制不是智能的,因此如果您关心池的物理布局,它可能会导致弹性问题—将池的磁盘分布在不同的 JBODs 中,以便您可以失去整个机箱,但仍然保留池和数据。

在简单的单一服务器设置中,这个问题并不重要。将备用磁盘添加到池中应该是安全的。我将在第五章演示这个过程。

创建 RAIDZ2 池

现在,我们来创建一个 RAIDZ2 池,该池将由 12 个磁盘组成,均匀分布在两个 vdevs 之间:

trochej@ubuntuzfs:~$ sudo zpool create -f datapool \
    raidz2 /dev/sdb /dev/sdc /dev/sdd \
    /dev/sde /dev/sdf /dev/sdg \
    raidz2 /dev/sdh /dev/sdi /dev/sdj \
    /dev/sdk /dev/sdl /dev/sdm

trochej@ubuntuzfs:~$ sudo zpool status

  pool: datapool
 state: ONLINE
  scan: none requested

 config
:

        NAME        STATE     READ WRITE CKSUM
        datapool    ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            sdb     ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0
            sde     ONLINE       0     0     0
            sdf     ONLINE       0     0     0
            sdg     ONLINE       0     0     0
          raidz2-1  ONLINE       0     0     0
            sdh     ONLINE       0     0     0
            sdi     ONLINE       0     0     0
            sdj     ONLINE       0     0     0
            sdk     ONLINE       0     0     0
            sdl     ONLINE       0     0     0
            sdm     ONLINE       0     0     0

errors: No known data errors

trochej@ubuntuzfs:~$ sudo zpool list

NAME       SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
datapool  23.8G   152K  23.7G         -     0%     0%  1.00x  ONLINE  -

强制操作

在某些情况下,您可能希望执行两个具有最终结果的操作,例如销毁池或强制对池执行操作,即创建操作。你可能会看到很多这样的例子,尤其是在最初阶段,当你学习 ZFS 政府的时候。

最佳实践是在重用其组件之前销毁一个池,但是有些情况下,您可能会得到一堆被其他人处理掉的健康磁盘。它们可能包含以前在 ZFS 池中的磁盘,但数量不足以正确导入和销毁它。

对于这样的场合,有-f开关,意为force

培训和测试

请记住,创建一个池在很大程度上是一条单行道。您不能从中删除驱动器,一旦决定了冗余级别,您必须在相同的配置中添加新磁盘。在虚拟机中使用 zpool 和 zfs 命令。这是一种熟悉 ZFS 的低成本方式。熟悉帮助您监控驱动器的工具:smartctl、ZED、sysstat。

五、高级设置

如前所述,您可以将热备盘分配给池。如果 ZFS 池丢失一个磁盘,将自动连接备用磁盘,并启动重新同步过程。

让我们考虑一个镜像池,每个池包含两个 vdevs 和两个驱动器。为了清楚起见,它将是四个硬盘。它们将被成对分组,并且每一对将在内部镜像内容。如果我们有驱动器 A、B、C 和 D,驱动器 A 和 B 将是一个镜像对,驱动器 C 和 D 将是第二个镜像对:

trochej@ubuntuzfs:~$ sudo zpool status

  pool: datapool
 state: ONLINE
  scan: none requested
 config:

    NAME        STATE     READ WRITE CKSUM
    datapool    ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
        sdb     ONLINE       0     0     0
        sdc     ONLINE       0     0     0
      mirror-1  ONLINE       0     0     0
        sdd     ONLINE       0     0     0
        sde     ONLINE       0     0     0

errors: No known data errors

您可以通过运行zpool add spare命令来添加热备盘设备:

trochej@ubuntuzfs:~$ sudo zpool add datapool -f spare /dev/sdf

接下来,通过查询池的状态来确认磁盘已添加:

trochej@ubuntuzfs:~$ sudo zpool status datapool

  pool: datapool
 state: ONLINE
  scan: none requested
 config:

    NAME        STATE     READ WRITE CKSUM
    datapool    ONLINE       0     0     0
      mirror-0  ONLINE       0     0     0
        sdb     ONLINE       0     0     0
        sdc     ONLINE       0     0     0
      mirror-1  ONLINE       0     0     0
        sdd     ONLINE       0     0     0
        sde     ONLINE       0     0     0
    spares
      sdf       AVAIL

errors: No known data errors

如果您想从池中移除备件,请使用zpool remove命令:

trochej@ubuntuzfs:~$ sudo zpool remove datapool /dev/sdf

您也可以在这里使用zpool status来确认更改。

您可以在多个池之间共享一个热备盘。您可以创建一个镜像池来托管非常重要的数据或需要快速传输的数据。然后,您可以创建第二个池 RAIDZ,它需要更多空间,但不是非常关键(仍然是冗余的,但只能丢失一个磁盘)。然后,您可以为这两个池分配一个热备盘。出现故障的设备将占用热备盘设备,然后该设备将无法用于第二个池,直到它被释放。

Note

使用热备盘有一个重要的注意事项。如果您以最大限度减少硬件故障影响的方式规划池中的驱动器,则热备盘的放置方式可能不是让您保持该质量的最佳方式。对于共享热备盘来说尤其如此。我见过的许多实际安装都使用了备用驱动器。它们被放置在机箱中,以确保在大多数情况下具有最佳的硬件故障恢复能力。当池中的驱动器出现故障时,系统管理员会从监控系统收到警报,然后手动更换驱动器。

ZIL 装置

ZIL 代表 ZFS 意向日志。它是数据块中永久存储写缓存的部分。通常,ZFS 会从存储池本身分配一些数据块。但是,由于池很忙并且位于旋转的磁盘上,性能可能不令人满意。

为了更好地适应性能要求,可以将 ZIL(也称为 SLOG)移到单独的设备上。该设备必须能够持续启动,这样,突然断电并不意味着事务数据丢失。对于基于 RAM 的设备,它们必须由电池或电容供电。也可以使用 SSD 设备。

《ZFS 管理指南》建议 ZIL 不低于 64 MB(这是对 ZFS 使用的任何设备的硬性要求),最多不超过可用 RAM 的一半。因此,对于 32 GB 的内存,应该使用 16 GB 的 ZIL 设备。实际上,我很少见过大于 32 GB 的,8 或 16 GB 是最常见的情况。原因是这是一个写缓冲区。将刷新到硬盘驱动器的写入将在 ZIL 中进行分组,以减少物理操作和碎片。一旦达到阈值,这些分组的更改将被写入物理驱动器。给它一个快速设备,最好是一个 RAM 设备,允许这些操作非常快,并大大加快写入速度。这还允许您转移通常会利用池带宽的 I/O(写入 ZIL ),为池本身提供一些额外的性能。

要添加 ZIL 设备,请先确认您的池运行状况良好。它还会提醒您哪些驱动器属于 ZFS 池:

root@xubuntu:~# zpool status
 pool: data
state: ONLINE
 scan: none requested
config:

       NAME        STATE     READ WRITE CKSUM
       data        ONLINE       0     0     0
         mirror-0  ONLINE       0     0     0
           sdb     ONLINE       0     0     0
           sdc     ONLINE       0     0     0
         mirror-1  ONLINE       0     0     0
           sdd     ONLINE       0     0     0
           sde     ONLINE       0     0     0
         mirror-2  ONLINE       0     0     0
           sdf     ONLINE       0     0     0
           sdg     ONLINE       0     0     0

errors: No known data errors

 pool: rpool
state: ONLINE
 scan: none requested
config:

       NAME          STATE     READ WRITE CKSUM
       rpool         ONLINE       0     0     0
         root_crypt  ONLINE       0     0     0

errors: No known data errors

添加/dev/sdh/dev/sdi驱动器作为镜像日志设备:

root@xubuntu:~# zpool add -f data log mirror /dev/sdh /dev/sdi

虽然 L2ARC 的内容(将在下一节中介绍)并不重要,但是 ZIL 保存了有关磁盘上的数据如何变化的信息。丢失 ZIL 不会使 ZFS 文件系统损坏,但可能会导致一些更改丢失。因此镜像。

通过运行zpool status确认更改生效:

root@xubuntu:~# zpool status data
 pool: data
state: ONLINE
 scan: none requested
config:

       NAME        STATE     READ WRITE CKSUM 

       data        ONLINE       0     0     0
         mirror-0  ONLINE       0     0     0
           sdb     ONLINE       0     0     0
           sdc     ONLINE       0     0     0
         mirror-1  ONLINE       0     0     0
           sdd     ONLINE       0     0     0
           sde     ONLINE       0     0     0
         mirror-2  ONLINE       0     0     0
           sdf     ONLINE       0     0     0
           sdg     ONLINE       0     0     0
       logs
         mirror-3  ONLINE       0     0     0
           sdh     ONLINE       0     0     0
           sdi     ONLINE       0     0     0

errors: No known data errors

您的新日志设备是 mirror-3。

L2ARC 设备(缓存)

ZFS 采用了一种叫做自适应替换缓存的缓存技术。简而言之,它基于最近最少使用(LRU)算法,该算法跟踪每个缓存页面的访问时间。然后从最近使用到最近最少使用对它们进行排序。当添加新的头部时,列表的尾部被驱逐。

ARC 通过跟踪两个列表中的页面——最近使用的和最频繁使用的——来改进这个算法。技术细节在这里并不重要,但是可以说,基于 ARC 的缓存的效率通常比 LRU 好得多。

导入池时,ARC 始终存在于操作系统的内存中。顺便提一下,如果您监控您的 RAM 并看到它的大部分正在被使用,不要惊慌。有这么一句话,“不用的内存就是浪费的内存”。你的操作系统试图在内存中尽可能多的存储空间,以减少磁盘操作。如你所知,磁盘是计算机中最慢的部分,即使是现代的固态硬盘。您应该注意的是,使用的 RAM 中有多少是缓存和缓冲区,有多少用于运行进程。

对于非常繁忙的服务器,将尽可能多的数据从驱动器加载到内存是很有意义的,因为这可以大大加快操作速度。

从 RAM 读取数据至少比从硬盘读取数据快 10 倍。但是,如果您的内存资源有限,但仍然希望尽可能多地缓存,会发生什么情况呢?

将一些 SSD 驱动器放入您的服务器,并将其用作 L2ARC 设备。L2 弧是二级弧。这些页面通常会被从缓存中逐出,因为 RAM 太小。但是,由于它们再次被请求的可能性仍然很高,因此它们可能被放置在中间区域,在快速 SSD 驱动器上。

因此,将 L2ARCs 放在镜像 SSD 上是非常有意义的。

要将/dev/sdi作为缓存设备放入池中,请运行以下命令:

root@xubuntu:~# zpool add -f data cache /dev/sdi

确认它有效:

root@xubuntu:~# zpool status data
 pool: data
state: ONLINE
 scan: none requested
config:

       NAME        STATE     READ WRITE CKSUM
       data        ONLINE       0     0     0
         mirror-0  ONLINE       0     0     0
           sdb     ONLINE       0     0     0
           sdc     ONLINE       0     0     0
         mirror-1  ONLINE       0     0     0
           sdd     ONLINE       0     0     0
           sde     ONLINE       0     0     0
         mirror-2  ONLINE       0     0     0
           sdf     ONLINE       0     0     0
           sdg     ONLINE       0     0     0
       logs
         sdh       ONLINE       0     0     0
       cache
         sdi       ONLINE       0     0     0

errors: No known data errors

配额和保留

在正常操作中,池中的每个文件系统都可以自由占用可用空间,直至达到整个池的容量,直到用完为止。唯一的限制是其他文件系统也占用空间。在这方面,对于 ZFS,您不应该考虑文件系统的容量,而应该考虑总的池空间。

然而,在某些情况下,当文件系统被限制在一定的空间内或者保证有足够的空间供自己使用时,您需要模拟传统的文件系统行为。

让我们考虑一个在普通磁盘分区上创建的传统文件系统。如果分区被创建为 3 GB,则文件系统自身的空间不会少于也不会多于 3 GB。如果您将它挂载为,比方说,/var/log,那么您系统中的日志将拥有全部 3 GB 的空间,不会再多了。它们也将与其他文件系统分开。因此,填充/var/log目录的日志不会使您的根分区变满,因为它们位于一个单独的空间中。

ZFS 就不是这样了!考虑安装在 ZFS 文件系统上的根目录。假设该池总共有 16 GB 的空间。这适用于/home/var/var/log的文件系统。安装完系统后,假设您还有 11 GB 的可用空间。每个文件系统都会消耗这个空间。如果由于某种原因,日志变得混乱——也许某个应用程序切换到了调试模式,而您忘记了它——它们可能会填满这 11 GB 的空间,使所有其他文件系统都处于饥饿状态。在最坏的情况下,您将无法以 root 用户身份登录。

根据您希望如何处理这个问题,您可以采取两种可能的措施:使用配额和使用保留。

配额类似于传统的 Linux 配额,只是它们是针对文件系统而不是系统用户设置的。通过设置配额,您可以防止给定的文件系统增长超过设置的限制。所以如果你想让/var/log永远不超过 3 GB,你就给它设置一个配额。

另一方面,保留是对文件系统的保证。通过设置 3 GB 预留空间,您可以保证该给定文件系统至少有 3 GB 的空间,并且池中的其他文件系统不会占用太多空间。

让事情变得稍微复杂一点的是,每种都有两个版本:配额和 refquotas,以及预留和重新预留。我的经验告诉我,这种差异非常重要。

配额和预留量说明了文件系统及其后代使用的存储。这意味着这 3 GB 的空间将是文件系统及其快照和克隆的极限。另一方面,Refquotas 只会跟踪文件系统本身使用的空间。它为一些有趣的场景开辟了道路,在这些场景中,您可以分别为文件系统及其快照设置限制。但是配额带来了一个重要的变化:快照会随着数据的变化而增长。您必须注意快照的大小和增长速度,否则您可能会在预期之前达到配额。

保留和再保留也有同样的风味区别。预留将为文件系统及其后代保证空间,而重新预留将仅为文件系统本身保留该空间。再次提醒,注意,因为你设置的最终结果可能不是你所希望的,也不是你所期望的。

让我们看一些基于真实场景的例子。

您正在运行的服务器有池数据。该池的总容量为 30 TB。该池将由财务、工程和营销部门共享。还将有共享空间,人们可以用来交换文件和愚蠢的猫图片。

这三个部门都向您提供了他们的目录在未来可以增长的规模。财务和营销部门表示,每个项目的容量大约为 5 TB,而工程部门表示,他们预计容量将增长到 10 TB。合起来就是 20 TB,留给你 10 TB 的空闲空间做其他事情。

现在,30 TB 的空间可能看起来是一个很大的数字,对于大多数小型组织来说,可能确实如此。另一方面,工程数据或原始图片和视频(例如,在图形工作室中)可能很快就无法满足需求。

快照是下一小节的主题,但是让我们在这里简单介绍一下。文件系统的快照可以与文件系统在给定时间(即拍摄快照时)的静态映像进行比较。在 ZFS,它可以像任何其他文件系统一样对待,除了它是只读的。这意味着,查看这个文件系统,您将会看到文件和目录在运行zfs snapshot命令时的状态。无论运行此命令后这些文件发生了什么情况,您都可以从快照中检索到它们以前的状态。

快照占用的空间量等于数据更改的大小。听起来很复杂,我们来揭开它的神秘面纱。工程有一个 5 GB 的大 CAD 文件。这是一个导入的项目,将继续工作。在它被复制到 ZFS 之后,为了以防万一,拍了一张快照。工程师打开文件,修改了一些东西。保存后,文件的大部分保持不变,但有些地方有所不同。这些差异加起来的大小是 300 MB。这是快照的大小。如果有人删除了文件,快照将增长到 5 GB,因为这是实际文件系统和拍摄快照时刻之间的差异。这背后的机制将在下一节中解释。现在,只要承认这是一个事实。

快照的这种空间消耗在设置预留和配额时起着重要作用。让我们回头看看工程部门的文件系统。该部门估计,他们将存储在文件系统中的数据量将达到 10 TB。但是他们只估计了“原始”数据。文件本身,而不是它们的快照。假设引入项目文件的每日变更量总计为 5 GB。这是一个快照每天占用的空间量,除非它被销毁。为简单起见,假设将只有一个快照,并且它将被永久保存。一年之内,这将相当于从池中占用近 2 TB 的空间!现在,假设您为工程文件系统创建了一个预留空间,并为其分配了 10 TB。你还要加一个配额,11 TB,让他们有喘息的机会,但这样他们就不会饿死其他用户。正如所假设的那样,他们的空间消耗在一年内开始接近 9 TB,突然,距离目标整整少了 2 TB,他们在尝试写入任何内容时都会出现空间不足错误。为了快速解决这种情况,他们删除了一些旧文件,已知这些文件是很久以前最后编辑的,并且存在于几个备份中。显然,他们已经释放了 3 TB 的空间,除了他们不断得到空间不足的错误。因为这个错误,在某些时候他们甚至不能删除文件!

这是预定开始了。问题的第一部分是,随着配额的增长,快照会悄悄地从配额中占用空间。只有当您使用zpool -o space命令分析空间消耗时,这一点才显而易见(在其他地方解释)。但是问题的另一部分,即删除东西时违反直觉的空间不足错误,来自于快照本身的性质。当您从文件系统中删除文件时,这些文件会添加到快照中。释放该空间的唯一方法是使用以下命令销毁快照:

zfs destroy pool/engineering@snapshot

现在让我们考虑其他部门。如果您为它们设置了配额,并且它们对文件进行了足够多的编辑,那么由于文件系统快照,它们可能很快就会达到配额。此外,通常会有多个快照。这完全取决于政策制定者,但通常会有每月、每周和每天的快照。有时也有每小时的快照,这取决于一天中数据变化的程度。

现在回到配额和预留以及再配额和再预留之间的区别。第一种跟踪整个使用情况,包括快照。后者只是文件系统。对于工程部门,您可以将 refquota 设置为 11 TB,将配额设置为 13 TB。这将为随着文件删除而增长的快照打开空间,从而提供临时解决方案。然而,没有什么能打败空间利用监控。

配额、保留、引用配额和重新保留是文件系统属性。这意味着使用zfs setzfs get命令对它们进行设置和检查。

root@xubuntu:~# zfs list
NAME                USED  AVAIL  REFER  MOUNTPOINT
data                179K  2.86G    19K  /data
data/engineering     19K  2.86G    19K  /data/engineering

要检查数据/工程文件系统上配额、refquota、预留和重新预留的当前值,请运行以下命令:

root@xubuntu:~# zfs get quota,refquota,reservation,refreservation data/engineering
NAME              PROPERTY        VALUE      SOURCE
data/engineering  quota           none       default
data/engineering  refquota        none       default
data/engineering  reservation     none       default
data/engineering  refreservation  none       default

如您所见,它们不是默认设置的。由于我的测试池比考虑的场景小得多,我们将预留设置为 1 GB,配额设置为 1.5 GB,refquota 和 refreservation 稍低一些:

root@xubuntu:~# zfs set quota=1.5G data/engineering
root@xubuntu:~# zfs set refquota=1G data/engineering
root@xubuntu:~# zfs set reservation=800M data/engineering
root@xubuntu:~# zfs get quota,refquota,reservation data/engineering
NAME              PROPERTY     VALUE     SOURCE
data/engineering  quota        1.50G     local
data/engineering  refquota     1G        local
data/engineering  reservation  800M      local

快照和克隆

在这里,我们来讨论快照和克隆,ZFS 的两个强大的功能。前面已经讨论过了,所以现在是详细解释的时候了。

如前所述,快照是在给定时间“冻结”文件系统内容的一种方式。由于 ZFS 的“写入时拷贝”特性,创建快照的速度很快(通常只需几分之一秒),并且只需要很少的处理能力。因此,创建快照作为需要静态内容的长期运行作业的基础是很常见的,例如备份作业。从大型文件系统运行备份作业可能会在不同时间归档文件。通过快照运行它可以保证所有文件都在同一时间被捕获,即使备份运行了几个小时也是如此。此外,如果备份的文件包含需要在备份过程中关闭的应用程序的状态文件,则该应用程序的停机时间可以减少到几分之一秒。

快照的另一个特性是能够将当前文件系统回滚到快照。这意味着管理员可以将所有文件回滚到快照创建时。

ZFS 将更改的数据块写入池中的新位置。因此,除非池被填满,并且旧空间需要回收,否则旧数据块保持不变。因此,快照会自动装载到拍摄快照的文件系统的.zfs/snapshot子目录中。例如,对于data/documents ZFS 文件系统,如果有一个快照data/documents@initial,可以通过查看/data/documents/.zfs/snapshot/initial来访问该快照的内容。

可以通过查看上面的目录或运行回滚命令来访问快照内容,这可以有效地将文件系统回滚到快照创建的时刻。这个过程非常快。它只需要更新一些元数据的时间。但是,管理员需要小心谨慎—一旦回滚,文件系统就不能快速恢复到其当前状态。

在有些情况下,只读快照是不够的,将它用作普通文件系统可能会很有用。ZFS 有这样一个特点,它被称为克隆。克隆是快照的读写拷贝。最初,克隆和快照引用同一组字节,因此克隆不消耗任何磁盘空间。当对克隆的内容进行更改时,它开始占用空间。

克隆和从中创建克隆的快照以父子方式相关联。只要克隆在使用中,就不能销毁快照。

快照为什么有用?他们可以防止错误软件或意外删除造成的文件损坏。它们还可以提供在编辑前查看文件的方法。它们可以用作准备备份的文件系统的快照。

克隆为什么有用?克隆的一个有趣用途是在操作系统的重要更新之前创建一个克隆。illumos 和 FreeBSD 早就知道,引导环境是可以引导到的根文件系统克隆。这允许在升级中断后快速重启到已知的正常工作的操作系统。它们也被用作克隆容器和虚拟机的手段。用途受到想象力的限制。

现在,在这个介绍之后,回到用法本身。

zfs acls

Linux 是 Unix 传统的操作系统。Unix 操作系统是多用户系统,允许许多用户操作同一台计算机。这带来了文件和目录权限控制的标准模型。在这个模型中,有三种类型的动作和三种类型的参与者。动作是读、写和执行,参与者是所有者、组和所有其他人。这两者可以结合起来,提供一种简单而有效的方法来限制和授权对 Linux 中某些目录和文件的访问。这种模式被称为自主访问控制(DAC)。

DAC 允许灵活控制谁可以使用某些系统区域以及如何使用。但是,用户越多,组织结构越复杂,用 DAC 模型表达就越困难。到了某个时候,就变得不可能了。因此,一种新的表示访问控制方法的方式被发明出来。

Linux 采用了 POSIX ACLs。ACL 的意思是访问控制列表,确切地说是:一个访问控制条目的列表,它可以创建更细粒度的策略,关于谁可以读、写或执行给定的文件以及他们如何做。

默认操作系统 illumos 上的 ZFS 支持独立的 ACL 集合,符合 NTFS ACLs。它们由扩展的lschmod命令设置和列出。不幸的是,这些命令与它们在 Linux 上的对应命令不同,因此在 Linux 上,不支持标准的 ZFS ACL。这意味着,如果系统管理员想要超越 DAC 模型,他们必须利用 POSIX ACLs 和标准命令:setfacl用于指定列表,而getfacl用于列出列表。好处是其他主流 Linux 文件系统都使用这些命令,因此您只需要学习一次。缺点是,如果您从 illumos 或 FreeBSD 导入了一个池,ACL 可能会丢失。

DAC 模型

在解释 POSIX ACLs 之前,我首先需要使用一个简单的场景来解释 DAC 模型。

假设有一台服务器有三个用户:Alice、John 和 Mikey。爱丽丝是项目经理,约翰是程序员,米奇在会计部门工作。用户可以访问服务器上的三个目录:

  • 上面写着:爱丽丝管理的项目的源代码和约翰的代码。公司政策规定,爱丽丝和约翰都应该能够访问该目录的内容,但只有约翰可以添加新文件或编辑现有文件。Mikey 不应该看到这个目录的内容。
  • 这个目录包含典型的项目文档。架构分析、项目概述、里程碑、客户签署等。公司政策规定,Mikey 和 John 应该能够读取这些文件,但不能编辑它们,而 Alice 应该能够读取和编辑这些文件。
  • 该目录包含财务数据:John 和 Alice 的时间会计、客户发票以及与项目相关的承包商发票、预算等。米奇对这些文件有完全的控制权。Alice 应该可以阅读所有的内容,但只能编辑其中的一部分,John 应该也不能。

显然,这并没有反映真实的编程项目,但是对于我们的目的来说已经足够了。我们拥有的传统 DAC 模型工具有:

  • 系统用户和组
  • 目录和文件访问控制
  • 每个目录和文件都有一个所有者(系统用户)和一个组(也拥有目录或文件的系统组)

有了这三点,我们就可以在这个小场景中做很多关于管理的事情。

让我们从为每个目录创建 ZFS 文件系统开始。假设目录名为data。为了获得更好的数据可访问性,池被镜像。

$ sudo zpool create data mirror /dev/sdb1 /dev/sdc1

现在我们有了一个池,我们为三个目录创建文件系统:

$ sudo zfs create data/Code
$ sudo zfs create data/Documents
$ sudo zfs create data/Accounts

假设 alice、john 和 mickey 的系统用户已经存在,并且他们的登录名分别是 Alice、John 和 Mickey。此外,还定义了三个组:projmgmt代表项目经理,devel代表开发人员,accnt代表会计。在我们设置权限之前,让我们创建一个表来准确描述谁应该能够做什么。在建立文件服务器结构以准备这样一个矩阵时,这是一个很好的实践。它有助于整理和想象事物。

访问控制使用三个字母来表示分配给用户或组的权限:

  • r–阅读
  • w–写
  • x–执行。在目录上设置该位意味着用户或组可以看到其内容。你实际上不能执行一个目录。为了区分执行和访问,x用于前者,X用于后者。

表 1-1 很快让人们明白,组与属于它们的用户拥有相同的权利。这样一来,为两者复制访问权限似乎有些矫枉过正。在这个时间点上,它当然是,但是我们应该总是为未来做计划。管理组和用户权限并不需要做很多工作,而且每个目录都需要指定其所属的组。而且,如果将来这些组中的任何一个获得了另一个用户,那么授予他们权限就像将他们添加到他们应该属于的组中一样简单。

表 1-1

Project Directories, Users, Groups, and Access Rights

| 用户/组/目录 | 爱丽丝 | 约翰 | 精神 | 项目管理 | 重击 | 重点是 | | :-- | :-- | :-- | :-- | :-- | :-- | :-- | | 密码 | 处方药 | 读写执行 | - | 处方药 | 读写执行 | - | | 文档 | 读写执行 | 处方药 | 处方药 | 读写执行 | 处方药 | 处方药 | | 帐目 | 处方药 | - | 读写执行 | 处方药 | - | 读写执行 |

这还不包括将运行备份守护程序的单独用户,他们至少应该能够读取所有目录以备份其内容,如果需要,还可以写入并重新创建它们。在本例中,可以通过对目录拍摄快照并使用zfs send|zfs recv将它们存储在单独的池中来完成备份,特殊的守护程序可以将它们放在磁带上。

现在,如果我们只想应用用户和所有者的组权限,以下命令就足够了。

$ sudo chown -R alice:projmgmt data/Documents
$ sudo chown -R john:devel data/Code
$ sudo chown -R mickey:accnt data/Accounts
$ sudo chmod -R =0770 data/Documents
$ sudo chmod -R =0770 data/Code
$ sudo chmod -R =0770 data/Accounts

=0770是设置权限的八进制模式。等号表示我们希望设置与字符串中完全一样的权限,前导零在这一点上没有意义,第二、第三和第四个数字是所有者、所属组和所有其他人相应的权限。权限集由数字及其总和表示:4-读,2-写,1-执行。任何这些的总和将创建一个唯一的数字:5 表示读取和执行,6 表示读取和写入,7 表示以上所有。八进制模式是一种非常方便的一次性设置所有位的方式。如果我们想要使用命名模式、用户、组或其他模式,我们必须对每个模式运行一次该命令:

$ sudo chmod -R ug=rwX data/Documents
$ sudo chmod -R o-rwX data/Documents

该命令创建表 1-2 中反映的权限集。

表 1-2

Project Directories, Users, Groups, and Access Rights After First Commands

| 用户/组/目录 | 爱丽丝 | 约翰 | 精神 | 项目管理 | 重击 | 重点是 | | :-- | :-- | :-- | :-- | :-- | :-- | :-- | | 密码 | - | 读写执行 | - | - | 读写执行 | - | | 文档 | 读写执行 | - | - | 读写执行 | - | - | | 帐目 | - | - | 读写执行 | - | - | 读写执行 |

显然,这不是我们想要达到的目标。解决这个问题的一种方法是将所属组更改为需要读取权限的组:

$ sudo chown -R john:projmgmt data/Code
$ sudo chmod -R =0750 data/Code

这给了 Alice 读取Code目录的权限;但是,它没有解决另一个人加入项目管理或会计组的问题。让我们假设 Susan 加入了 PM 团队,并且需要拥有与 Alice 相同的权限集。以目前的模式,这是不可能实现的。这就是 ACL 发挥作用的地方。

ACL 解释

ZFS 不允许开箱即用地使用 Linux ACLs(或者更确切地说是 POSIX ACLs)。它需要被告知这样做。要运行的命令是:

$ sudo zfs set acltype=posixacl data

这个命令打开给定文件系统的 POSIX ACLs。默认情况下,该属性由所有子文件系统继承,因此如果它设置在 ZFS 的根目录下,它将一直向下传播。您可以通过运行zfs get命令来验证它:

$ sudo zfs get acltype data
NAME  PROPERTY  VALUE     SOURCE
lxd   acltype   posixacl  local

ACL 如何帮助解决上述问题?很简单。它们允许开发人员存储比之前使用的三个 DAC 条目更多的内容。可以为每个额外的用户或组设置单独的权限。有两个工具用于管理 ACL:setfactlgetfacl

$ setfacl -m g:projmgmt:r /data/Code
$ setfacl -m g:devel:r /data/Documents
$ setfacl -m g:accnt:r /data/Documents
$ setfacl -m g:projmgmt:r /data/Accounts

请记住,ACL 命令是在目录上操作的,而不是在 ZFS 文件系统上操作的!

正如所料,这些命令将给予其他组确切的权限,如表 1-1 所示。我们可以通过对每个目录运行getfacl来确认,如下所示:

$ getfacl /data/Documents
getfacl: Removing leading '/' from absolute path names
# file: data/Documents
# owner: alice
# group: projmgmt
user::rwx
group::rwx
group:devel:r--
group:accnt:r--
mask::r-x
other::r-x

setfacl模式的语法如下:

setfacl -mode:user|group:permissions directory[/file]

setfacl命令有两种工作模式:添加 ACL 条目或删除 ACL 条目。相应地使用-m-x开关。在前面的示例中,-m开关用于向特定组添加 ACL 列表条目。要删除一个条目,您需要使用-x开关运行命令:

$ setfacl -x g:devel /data/Documents

这将删除添加到/data/Documents目录中的devel组的所有 ACL 条目。

更换驱动器

在许多情况下,您可能需要更换驱动器。最常见的是驱动器故障。要么您的监控系统警告您驱动器即将出现故障,要么驱动器已经出现故障。无论哪种方式,您都需要向池中添加新的驱动器并删除旧的驱动器。

更换驱动器还有另一个原因。这是一种在不增加驱动器的情况下增加 ZFS 池的方法,缓慢而繁琐——用更大的磁盘一个接一个地替换旧的。

考虑第一种情况。在zpool状态输出中,您的池被报告为运行良好,但您知道其中一个驱动器很快会出现故障。假设在下面打印的池中,驱动失败的是sdb

NAME         STATE    READ   WRITE   CKSUM
tank         ONLINE      0       0       0
  mirror-0   ONLINE      0       0       0
    sdb      ONLINE      0       0       0
    sdc      ONLINE      0       0       0

假设您已经将驱动器sdd添加到系统中。你可以运行zpool替换命令:

sudo zpool replace tank sdb sdd

这将在短时间内将sdd附着到sdb上,形成一面镜子,然后将sdb从水池中移除。或者你可以分两步做,首先手动将sdd连接到sdb,等到重新安装完成,然后自己拆下sdb:

sudo zpool attach tank sdb sdd

sudo zpool status
  pool: tank
state: ONLINE
  scan: resilvered 114K in 0h0m with 0 errors on Tue Nov 7 21:35:58 2017
config:

NAME         STATE    READ   WRITE   CKSUM
tank         ONLINE      0       0       0
  mirror-0   ONLINE      0       0       0
    sdb      ONLINE      0       0       0
    sdc      ONLINE      0       0       0
    sdd      ONLINE      0       0       0

你可以看到,这有效地将镜像 0 变成了三向镜像。监控 resilver 流程,并在完成后发布:

sudo zpool detach tank sdb

这将从您的池中删除sdb设备。

如果驱动器已经出现故障,步骤与上述类似,只是您将看到

NAME         STATE      READ   WRITE   CKSUM
tank         DEGRADED      0       0       0
  mirror-0   DEGRADED      0       0       0
    sdb      UNAVAIL       0       0       0
    sdc      ONLINE        0       0       0

遵循先前的步骤:

sudo zpool replace tank sdb sdd

这将用新驱动器替换故障驱动器。

在不添加新驱动器的情况下增加池意味着用新的更大的磁盘替换池中的每个磁盘。假设您想让池槽大于当前的 2 GB:

sudo zpool list
NAME SIZE  ALLOC FREE  EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 1.98G 152K  1.98G -        0%   0%  1.00x ONLINE -

这些步骤意味着:

  1. 将新驱动器添加到机箱中。它们必须有相同的几何形状和大小。
  2. 将更大的新驱动器连接到镜像,并等待它完成重新同步过程。
  3. 移除旧驱动器。
  4. 连接下一个更大的驱动器。等待 resilver,移除。

您可以运行 replace 命令,而不是附加和移除。它将为您完成上述所有步骤:

sudo zpool replace tank sdb sdd

如果您有由多个 vdev 构建的池,您可以为每个 vdev 运行 replace 命令。这将加快事情的进展。

六、共享

一旦您按照自己喜欢的方式设置和配置了储物件,就该开始使用它了。一种方法是使用在与 ZFS 池相同的服务器上运行的本地程序所使用的空间。如果您打算托管诸如邮件、网页或应用程序(也许是内部或外部 CRM)之类的应用程序,这将特别有用。另一方面,您可能需要为客户机提供公共磁盘空间,例如,将数据存储在服务器上或共享文档进行编辑的工作站。

您选择的连接方法,即共享协议,取决于您使用空间的方式。

共享协议

与任何存储阵列一样,共享磁盘空间有两种基本方式:作为字符设备或块设备。区别在于设备的使用方式,以及在 Linux 中如何中继到基本的两组设备——字符设备和块设备。对于我们的需求,差异可以这样总结:在我们的上下文中,字符设备将是一个文件系统,它可以被挂载并直接用于存储和检索文件。块设备是一种伪设备,是一种文件系统,只有将其视为硬盘驱动器本身才能使用。

鉴于 DYI 小型存储阵列,字符设备将成为两种流行的网络文件系统共享协议之一——NFS 或 CIFS。块设备很可能是 iSCSI 协议。虽然您可能决定使用 FC 或 FCoE 协议,但我不打算在这里讨论它们。

最初的 ZFS 实现允许通过 NFS 和 CIFS 协议快速共享。这些命令与 ZFS 本身紧密绑定,并在文件系统或zvol属性中表示。目前,在编写本指南时,本机 ZFS 共享命令不能在 Linux 平台上工作,或者工作不可靠。与 ACL 一样,您需要使用 Linux 本地工具——iSCSAadm、samba 和 NFS 服务器——来提供这一功能。

Note

请注意,描述复杂的 NFS、桑巴或 iSCSI 配置需要单独的书籍。这些超出了本简单指南的范围。如果你需要做一些更复杂的事情,网上有很多书和大量的教程。

NFS: Linux 服务器

NFS 是一种灵活且经过验证的网络存储共享协议。它是由太阳微系统公司在 1984 年构思的。它是分布式环境下的网络文件系统。在 Unix 世界中,一个非常常见的用途是在 NFS 服务器上托管用户的主目录,并在用户登录时自动将它们挂载到给定的机器上。因此,同一个主目录总是位于一个中心位置(便于备份和恢复),但在任何配置为使用 NFS 服务器的工作站上都可以访问。

NFS 在 Unix 和 Linux 世界中很常见,是服务器和客户机之间共享磁盘空间的标准方式。另一方面,如果您需要使用 Windows 系统中的磁盘空间,那么配置一个 SAMBA 服务器会很有好处。

NFS 协议有两个主要版本:第 3 版和第 4 版。如果可能的话,使用版本 4,因为它现在得到了主流 Linux 发行版的良好支持。版本 4 增加了许多性能和安全性改进,并强制实施了强安全性。我将介绍安装和配置 NFSv4 的步骤。包是相同的,但有些配置不同。在服务器和客户机上开始使用 NFS 之前,您需要采取一些步骤。首先,需要安装软件包。

在 Ubuntu 上安装软件包

要在 Ubuntu 上安装和配置 NFS 服务器,请运行以下命令:

trochej@ubuntu:~$ sudo apt-get install nfs-kernel-server
[sudo] password for trochej:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
 keyutils libnfsidmap2 libpython-stdlib libpython2.7-minimal libpython2.7-stdlib
 libtirpc1 nfs-common python python-minimal python2.7 python2.7-minimal rpcbind
Suggested packages:
 watchdog python-doc python-tk python2.7-doc binutils binfmt-support
The following NEW packages will be installed:
 keyutils libnfsidmap2 libpython-stdlib libpython2.7-minimal libpython2.7-stdlib
 libtirpc1 nfs-common nfs-kernel-server python python-minimal python2.7
 python2.7-minimal rpcbind
0 upgraded, 13 newly installed, 0 to remove and 96 not upgraded.
Need to get 4,383 kB of archives.
After this operation, 18.5 MB of additional disk space will be used.
Do you want to continue? [Y/n]

在您按 Y 并按 Enter 确认之后,系统将打印它安装的软件包列表。您的输出可能与这里显示的有所不同,这取决于您已经安装的内容。假设服务器上存在池槽和文件系统导出:

trochej@ubuntu:~$ sudo zfs list
NAME          USED  AVAIL  REFER  MOUNTPOINT
tank           80K  1.92G    19K  /tank
tank/export    19K  1.92G    19K  /tank/export

编辑/etc/exports文件(它是通过 NFS 协议导出的目录列表以及应用于它们的各种选项)并添加以下行:

/tank/export       192.168.0.0/24(rw,fsid=0,sync)

这将使 192.168.0.0 网络中的所有主机都可以使用/tank/export文件系统。

fsid=0选项告诉 NFS 服务器该目录是其他文件系统的根目录。rw选项将文件系统设置为读写。Sync告诉服务器只有当缓冲区被提交到物理介质时才确认写入。

要使此导出在网络上可用,需要重新启动内核服务器:

sudo systemctl restart nfs-kernel-server

最后要确保的是更改导出文件系统的权限,以便远程服务器可以写入:

trochej@ubuntu:~$ sudo chmod -R a+rwX /tank/

您可以通过运行exportfs命令来确认导出:

trochej@ubuntu:~$ sudo exportfs
/tank/export    192.168.0.0/24

在 Ubuntu 上安装 NFS 客户端

要在 Ubuntu 机器上安装和配置 NFS 客户端,请运行:

sudo apt-get install nfs-common

然后通过运行以下命令来测试装载:

sudo mount -t nfs4 -o proto=tcp,port=2049 192.168.0.9:/ /mnt

这将告诉mount命令在/mnt目录中挂载一个运行在 192.168.0.9 服务器上的远程文件系统。要使它在重启后保持不变,需要将这一行添加到/etc/fstab文件中:

192.168.0.9:/   /mnt   nfs4    _netdev,auto  0  0

从现在开始,您的 ZFS 池将被导出,并可由客户端计算机远程使用。

在 CentOS 上安装软件包

要在 CentOS 上实现相同的效果,请运行以下命令:

[root@centos ~]# yum install nfs-utils

更改目录的权限:

[root@centos ~]# chmod -R a+rwX /tank/export

接下来,将适当的条目添加到/etc/exports:

[root@centos ~]# cat /etc/exports
/tank/export 192.168.0.0/24(rw,fsid=0,sync)

最后,重新启动 NFS 服务器:

[root@centos ~]# systemctl restart nfs-server

在客户机上安装它是类似的。

[root@centos ~]# yum install nfs-utils
[root@centos ~]# mount -t nfs4 -o proto=tcp,port=2049 192.168.0.9:/ /mnt

和 Ubuntu 一样,为了让挂载在每次系统启动时自动进行,在您的/etc/fstab文件中添加下面一行:

192.168.0.9:/   /mnt   nfs4    _netdev,auto  0  0

这个装置非常简陋。没有应用任何安全性,也绝对没有使用任何外部用户身份验证方法。通常,在生产环境中,您会希望使用某种中央用户数据库,比如 LDAP 或 Active Directory。

桑巴舞

即使对于最简单的设置,配置 SAMBA 也更加复杂。它需要编辑适当的配置文件。在 Ubuntu 中是/etc/samba/smb.conf

下面我粘贴了我能想到的绝对最小的smb.conf文件:

[global]
  workgroup = WORKGROUP
  server string = %h server (Samba, Ubuntu)
  dns proxy = no
  server role = standalone server
  passdb backend = tdbsam

[shared]
  comment = Shared ZFS Pool
  path = /tank/
  browseable = yes
  read only = no
  guest ok = yes
  writeable = yes

上面的配置绝对不适合现实世界。它没有提供合理的登录方式,没有安全性,没有密码同步。只是匿名访问导出的池。但它起到了测试的作用。

在 Linux 机器上安装它很简单:

sudo mount -t cifs //CIFSSERVER/shared /mnt

其中,CIFSSERVER 是 SAMBA 服务器的 IP 地址或可解析的网络名称。请注意,一旦用户参与进来,上面的线将不得不改变。

在 Windows 计算机中装载此共享非常简单,只需打开资源管理器窗口,在网络中导航到 CIFSSERVER,然后打开共享。完成了。

与 NFS 一样,您很可能希望涉及一些额外的目录服务,即各种 LDAP。你绝对不能在现实世界中使用匿名共享。就是不要。

和 NFS 一样,学习的材料本身就是一本书,互联网上有丰富的资源。

其他共享协议

ZFS 允许更多的分享方式。特别感兴趣的可能是 iSCSI 或光纤通道。SCSI(小型计算机系统接口)是企业设置中将硬盘连接到服务器的事实标准。目前,串行连接 SCSI(通常称为 SAS)是要使用的技术。虽然该协议旨在将许多其他外围设备连接到计算机,但在服务器机房中,它主要用于连接驱动器。

如上所述,ZFS 可以创建像目录一样的文件系统。您可以创建称为 ZVOLs 的块设备。它们被视为可以分区和格式化的普通硬盘。它们也可以通过 iSCSI 协议作为物理驱动器导出。

iSCSI 是 SCSI 协议在 TCP/IP 网络上的实现。它允许您通过网络对存储设备执行 SCSI 命令,就像它们直接连接到系统一样。

两个重要的 SCSI(以及 iSCSI)术语是启动器和目标。目标是存储资源;在这种情况下,它可以通过网络获得。发起人是 iSCSI 客户。要利用存储启动器,您必须登录到目标并启动会话。如果这样配置,它可以强制客户端向服务器进行身份验证。

在 Linux 平台上使用 iSCSI 协议相当容易。首先,您需要创建 ZVOLs 并将每个 ZVOLs 导出为 LUN(逻辑单元)。

首先,让我们创建 ZVOLs 用作虚拟驱动器。那些将是生活在数据池中的vol01vol02vol03vol04

sudo zfs create -V 5gb data/vol01
sudo zfs create -V 5gb data/vol02
sudo zfs create -V 5gb data/vol03
sudo zfs create -V 5gb data/vol04

下一步是创建四个 LUN,它们将向客户端计算机呈现 ZVOLs:

sudo tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.2016.temp:storage.lun01
sudo tgtadm --lld iscsi --op new --mode target --tid 2 -T iqn.2016.temp:storage.lun02
sudo tgtadm --lld iscsi --op new --mode target --tid 3 -T iqn.2016.temp:storage.lun03
sudo tgtadm --lld iscsi --op new --mode target --tid 4 -T iqn.2016.temp:storage.lun04

完成后,必须通过之前配置的目标将 ZVOLs 导出为 LUN:

sudo tgtadm --lld iscsi --op new --mode logicalunit --tid 1 --lun 1 -b /dev/zvol/data/vol01
sudo tgtadm --lld iscsi --op new --mode logicalunit --tid 2 --lun 1 -b /dev/zvol/data/vol02
sudo tgtadm --lld iscsi --op new --mode logicalunit --tid 3 --lun 1 -b /dev/zvol/data/vol03
sudo tgtadm --lld iscsi --op new --mode logicalunit --tid 4 --lun 1 -b /dev/zvol/data/vol04
sudo tgtadm --lld iscsi --mode target --op bind --tid 1 -I ALL
sudo tgtadm --lld iscsi --mode target --op bind --tid 2 -I ALL
sudo tgtadm --lld iscsi --mode target --op bind --tid 3 -I ALL
sudo tgtadm --lld iscsi --mode target --op bind --tid 4 -I ALL
sudo tgt-admin --dump | sudo tee /etc/tgt/targets.conf

您可以通过运行tgadm命令来确认配置。为简洁起见,以下输出已被删减:

trochej@hypervizor:~$ sudo tgtadm --mode tgt --op show
Target 1: iqn.2016.temp:storage.lun01
        System information:
                Driver: iscsi
                State: ready
        I_T nexus information:
        LUN information:
                LUN: 0
                        Type: controller
                        SCSI ID: IET     00010000
                        SCSI SN: beaf10
                        Size: 0 MB, Block size: 1
                        Online: Yes
                        Removable media: No
                        Prevent removal: No
                        Readonly: No
                        SWP: No
                        Thin-provisioning: No
                        Backing store type: null
                        Backing store path: None
                        Backing store flags:
                LUN: 1
                        Type: disk
                        SCSI ID: IET     00010001
                        SCSI SN: beaf11
                        Size: 5369 MB, Block size: 512
                        Online: Yes
                        Removable media: No
                        Prevent removal: No
                        Readonly: No
                        SWP: No
                        Thin-provisioning: No
                        Backing store type: rdwr
                        Backing store path: /dev/zvol/data/vol01
                        Backing store flags:
        Account information:
        ACL information:
                ALL

使用iscsiadm命令将启动器连接到目标:

iscsiadm -m discovery -t sendtargets -p 192.168.0.9
192.168.0.9:3260,1 iqn.2016.temp:storage.lun01:target1

此命令将打印服务器上配置的目标。要开始使用它们,客户机需要登录并启动会话:

iscsiadm -m node -T iqn.2016.temp:storage.lun01:target1 --login

您可以通过查看以下信息来确认系统中出现的磁盘:

root@madtower:/home/trochej# dmesg | grep "Attached SCSI disk"
[...]
        [ 3772.041014] sd 5:0:0:1: [sdc] Attached SCSI disk
        [ 3772.041016] sd 4:0:0:1: [sdb] Attached SCSI disk
        [ 3772.047183] sd 6:0:0:1: [sde] Attached SCSI disk
        [ 3772.050148] sd 7:0:0:1: [sdd] Attached SCSI disk
[...]

系统中有四个 LUN 可用,剩下的唯一一步就是像使用任何其他物理驱动器一样使用它们。您可以在它们上面创建 LVM 池,甚至在另一个 ZFS 池上创建:

root@madtower:/home/trochej# zpool create -f datapool mirror /dev/sdb /dev/sdc mirror /dev/sdd /dev/sde
root@madtower:/home/trochej# zpool list
NAME       SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
datapool  9.94G  68.5K  9.94G         -     0%     0%  1.00x  ONLINE  -
rpool      444G   133G   311G         -    29%    29%  1.00x  ONLINE  -

root@madtower:/home/trochej# zpool status datapool
  pool: datapool
 state: ONLINE
  scan: none requested
 config:

                NAME         STATE     READ WRITE CKSUM
                datapool    ONLINE        0     0     0
                  mirror-0  ONLINE        0     0     0
                       sdb  ONLINE        0     0     0
                       sdc  ONLINE        0     0     0
                  mirror-1  ONLINE        0     0     0
                       sdd  ONLINE        0     0     0
                       sde  ONLINE        0     0     0

errors: No known data errors

当导出您的池供客户机使用时,您有很多选择。我只介绍了其中的三种,因为它们似乎最受欢迎。

七、空间监控

有了如此丰富的功能集,包括克隆、快照和压缩都依赖于文件系统组织,空间监控需要以不同于传统 Linux 文件系统的方式进行。每个 Linux 服务器管理员都熟悉的常用命令*df _-h_*\已经不够用了,甚至可能会产生误导。

使用新命令

使用 ZFS,您需要学习两个新命令,并理解它们的参数和输出,以跟踪您的空闲空间— *sudo zpool list** sudo zfs list *。在我的家庭工作站上,这些命令产生以下输出。

trochej@madchamber:~$ sudo zpool list

NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
data  2,72T   147G   2,58T        -     3%     5%  1.00x  ONLINE  -

trochej@madchamber:~$ sudo zfs list

NAME          USED  AVAIL  REFER  MOUNTPOINT
data          147G  2,53T    96K  /data
data/datafs   147G  2,53T   147G  /mnt/data

此列表不完整,因为默认情况下它忽略了快照。请记住,随着时间的推移,快照会消耗越来越多的空间,因为拍摄快照的系统上的数据会发生变化。根据我的经验,新 ZFS 存储运营商提出的一个常见问题是,由于空间不足,他们无法删除数据。他们通常感到困惑的是,删除数据不会增加可用空间,ZFS 列表中已消耗的空间不会加到池中的总可用空间中。

输出术语

让我们看看输出中的列,了解它们对操作员的意义:

  • AVAIL表示可用。文件系统中的总可用空间。
  • USED使用的意思。文件系统中的总已用空间。
  • USEDSNAP表示由快照使用。数据集快照使用的磁盘空间。一旦数据集的所有快照都被销毁,该空间就会被释放。由于多个快照可以引用相同的数据块,因此该数量可能不等于所有快照已用空间的总和。
  • USEDDS表示被数据集使用。数据集本身使用的磁盘空间。如果该数据集的所有快照和refreservation都被销毁,从而销毁数据集本身,则该磁盘空间将被释放。
  • USEDREFRESERV表示被refreservation使用。数据集上的refreservation集合使用的磁盘空间。一旦refreservation被移除,该空间被释放。
  • USEDCHILD指儿童使用的。数据集的子级使用的磁盘空间。销毁给定数据集的子数据集后,该空间将被释放。

要手动计算USED属性,请遵循以下等式:USED = USEDCHILD + USEDDS + USEDREFRESERV + USEDSNAP

什么在消耗我的池空间?

理解什么消耗了您的池空间有时有点困难。我将使用一些例子来演示解决这个问题的方法,但是没有什么比经验更好的了。创建池,用数据填充池,运行快照,以及删除和创建预留。同时,观察*zfs list_ -t all -o snapshot_**zfs list _-t all_*以更好地理解空间计算。

诊断问题

让我们考虑一种情况,您有一个 3 TB 的池。

sudo zpool create datapool mirror /dev/sdb /dev/sdc
sudo zfs create datapool/data

成功导入 2 TB 的备份数据后,您决定创建一个快照,以便用户误删除数据时不会要求您重新运行备份恢复。

sudo zfs snapshot datapool/data@after-backup-restore

请注意,运行此快照是即时的,最初不占用磁盘空间。

也许,正如有时可能发生的那样,就在您运行快照后,拥有非常广泛的访问权限的用户意外地删除了整整 2 TB 的数据。但是,删除作业在不到 1 TB 时停止,并报告由于空间不足而无法删除更多内容。这怎么可能?答案是:快照。让我们首先观察我的工作站上的文件系统:

trochej@madchamber:~$ sudo zfs list

NAME          USED  AVAIL  REFER  MOUNTPOINT
data          134G  2,55T    96K  /data
data/datafs   134G  2,55T   134G  /mnt/data

现在,我们在那里创建一个快照:

trochej@madchamber:~$ sudo zfs snapshot data/datafs@testsnapshot

trochej@madchamber:~$ sudo zfs list -t all

NAME                       USED  AVAIL  REFER  MOUNTPOINT
data                       134G  2,55T    96K  /data
data/datafs                134G  2,55T   134G  /mnt/data
data/datafs@testsnapshot      0      -   134G  -

现在我们上传一个 CentOS 7 GB 的 ISO 文件到_/mnt/data_:

trochej@madchamber:~$ sudo zfs list -t all

NAME                       USED  AVAIL  REFER  MOUNTPOINT
data                       141G  2,54T    96K  /data
data/datafs                141G  2,54T   134G  /mnt/data
data/datafs@testsnapshot  7,14G      -   134G  -

请注意,快照大小已经增加到新引入的数据。现在让我们删除包含存档 iso 的整个目录:

trochej@madchamber:~$ sudo zfs list -t all

NAME                       USED  AVAIL  REFER  MOUNTPOINT
data                       141G  2,54T    96K  /data
data/datafs                141G  2,54T   109G  /mnt/data
data/datafs@testsnapshot  32,0G      -   134G  -

您将会看到,虽然data/datafs ZFS 文件系统的REFER大小有所缩减,但总体的USED保持不变,快照大小增加到了 32 GB。为了比较,让我们看一下*df _-h_*命令(为了清楚起见,我从输出中删除了非 ZFS 文件系统):

trochej@madchamber:~$ df -h

Filesystem      Size  Used Avail Use% Mounted on
data            2,6T  128K  2,6T   1% /data
data/datafs     2,7T  109G  2,6T   5% /mnt/data

现在让我们从datafs中删除一些数据,只是为了增加快照的大小:

trochej@madchamber:~$ sudo zfs list -t all

NAME                       USED  AVAIL  REFER  MOUNTPOINT
data                       141G  2,54T    96K  /data
data/datafs                141G  2,54T  23,3G  /mnt/data
data/datafs@testsnapshot   117G      -   134G  -

trochej@madchamber:~$ df -h

Filesystem      Size  Used Avail Use% Mounted on

data            2,6T  128K  2,6T   1% /data
data/datafs     2,6T   24G  2,6T   1% /mnt/data

正如您可能注意到的,从du命令中没有收集到太多信息。它或多或少地跟踪了空间使用情况,但是它没有告诉我们任何关于模式的信息。另一方面,zfs列表告诉了我们很多。仅通过这个输出,您就可以看到,虽然您的文件系统已用空间减少了,但总的已用空间保持不变;它刚刚移动到另一个数据集的位置。

*zfs*命令可以让您更深入地了解空间在数据中是如何分布的。虽然它在我目前为止运行的小实验中不是很有趣,但是我马上会给你们提供更复杂的例子。然而,首先让我们看看*zfs list*的另一个选项:

trochej@madchamber:~$ sudo zfs list -t all -o space

NAME                      AVAIL   USED  USEDSNAP  USEDDS  USEDREFRESERV  USEDCHILD
data                      2,54T   141G         0     96K   0              141G
data/datafs               2,54T   141G      117G   23,3G  0              0
data/datafs@testsnapshot      -   117G         -       -  -              -

Note

下一节将对-o space进行更详细的解释。

现在应该很清楚数据删除的问题来自哪里了。由于 3 TB 池能够保存或多或少相同数量的数据(模数数据压缩),在已经保存 2 TB 数据的文件系统上引入 2 TB 数据的删除会导致池空间耗尽,因为随着用户不断删除数据,池需要向快照添加数据。

更多高级示例

前面的例子非常简单。这个池上没有发生太多事情,也没有使用太多附加功能。让我们使用文件存储(模拟真实块设备的文件)创建一个示例 ZFS 池,我们将尝试几个场景,看看设置各种 ZFS 属性如何影响可用空间和zfs -o space输出。

在前面的例子中,*zfs _-o space_*输出信息不多,也不有趣,所以让我们考虑以下配置:

  • 具有 RAIDZ2 冗余的名为datapool的池。
  • 五个文件系统,其中两个每小时拍摄定期快照,并保留两周。每周六拍摄一次快照,并保留一个月。
  • 其中两个文件系统设置了配额。
  • 一个文件系统设置了保留。
  • 创建一个 zvol。

让我们把这个配置打印出来:

trochej@ubuntuzfs:~$ sudo zpool list
NAME       SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
datapool  23.8G  5.37G  18.4G         -    14%    22%  1.00x  ONLINE  -

因此,池显示池中有超过 18 GB 的可用空间。让我们仔细看看:

trochej@ubuntuzfs:~$ sudo zfs list
NAME              USED  AVAIL  REFER  MOUNTPOINT
datapool         13.2G  2.41G  34.0K  /datapool
datapool/first   3.58G  6.83G  3.58G  /datapool/first
datapool/five     50.0K  2.41G  32.0K  /datapool/five
datapool/fourth  50.0K  2.41G  32.0K  /datapool/fourth
datapool/second  50.0K  2.41G  32.0K  /datapool/second
datapool/third   50.0K  2.41G  32.0K  /datapool/third
datapool/vol01   5.16G  7.57G  16.0K  -

但也不尽然。AVAIL号不应该和*zpool list*输出中的FREE一样吗?ZFS 文件系统可以增长到池的容量。让我们列出所有数据集:

trochej@ubuntuzfs:~$ sudo zfs list -t all
NAME                 USED    AVAIL   REFER   MOUNTPOINT
datapool             13.2G   2.41G   34.0K   /datapool
datapool/first        3.58G   6.84G   3.58G   /datapool/first
datapool/first@2016-02-17-14:55    18.0K   -       32.0K   -
datapool/first@2016-02-17-15:04    0       -       3.58G   -
datapool/five         50.0K   2.41G   32.0K   /datapool/five
datapool/five@2016-02-17-14:55    18.0K   -       32.0K   -
datapool/fourth      50.0K   2.41G   32.0K   /datapool/fourth
datapool/fourth@2016-02-17-14:55    18.0K   -       32.0K   -
datapool/second      50.0K   2.41G   32.0K   /datapool/second
datapool/second@2016-02-17-14:55    18.0K   -       32.0K   -
datapool/third       50.0K   2.41G   32.0K   /datapool/third
datapool/third@2016-02-17-14:55    18.0K   -       32.0K   -
datapool/vol01       5.16G   7.57G   16.0K   -

好吧。有快照在起作用,所以它可能占用了一些容量,但为什么数据集之间的数字不同呢?我们先来看一下*zfs list*输出中的_REFER_列。它说明数据集保留引用的空间有多大。在输出中可以看到:

datapool/first@2016-02-17-15:04       0      -  3.58G  -

_USED_列为零,但_REFER_在 3.5 GB 以上。这是典型的快照。自创建快照以来,文件系统datapool/first没有发生任何变化,因此快照目前不使用任何空间。但是,它保留了对拍摄快照时datapool/first包含的 3.5 GB 数据的引用。让我们通过删除我复制到数据池的一段数据来使用一些空间:

trochej@ubuntuzfs:~$ rm /datapool/first/Fedora-Live-KDE-x86_64-23-10.iso

这为我们提供了以下输出:

trochej@ubuntuzfs:~$ sudo zfs list
NAME                       USED   AVAIL  REFER  MOUNTPOINT
datapool                   14.7G   930M  34.0K  /datapool
datapool/first              9.50G  4.91G  741M   /datapool/first

所以,文件系统datapool/first消耗了 9.5 GB 的空间,但引用的只有 741 MB?其余声称的空间消耗在哪里?首先,运行zfs list -t all不仅可以看到文件系统,还可以看到快照:

trochej@ubuntuzfs:~$ sudo zfs list -t all
NAME                       USED   AVAIL  REFER  MOUNTPOINT
datapool                   14.7G   930M  34.0K  /datapool
datapool/first               9.50G  4.91G  741M   /datapool/first
datapool/first@2016-02-17-14:55  18.0K    -  32.0K -
datapool/first@2016-02-17-15:04  18.0K    -  3.58G -
datapool/first@2016-02-17-15:22  1.20G    -  5.50G -
datapool/first@2016-02-17-15:27  0        -  741M  -

trochej@ubuntuzfs:~$ ls -ahl /datapool/first/
total 741M
drwxr-xr-x 2 trochej trochej    3 Feb 17 15:25 .
drwxr-xr-x 7 trochej trochej    7 Feb 17 14:51 ..
-rw-r----- 1 trochej trochej 741M Feb 17 15:21 FreeBSD-11.0-CURRENT-amd64-20151130-r291495-disc1.iso

好吧。因此,文件系统保存 741 MB 的数据,但其快照消耗 1.20 GB 的空间。这还差不多。但是,剩下的空间在哪里?

trochej@ubuntuzfs:~$ sudo zfs list -t all -o space
NAME                              AVAIL   USED  USEDSNAP  USEDDS  USEDREFRESERV  USEDCHILD
datapool/first                    4.91G  9.50G     4.78G    741M           4G         0
datapool/first@2016-02-17-14:55       -  18.0K         -       -              -          -
datapool/first@2016-02-17-15:04       -  18.0K         -       -              -          -
datapool/first@2016-02-17-15:22       -  1.20G         -       -              -          -

为了简洁起见,输出被删除了,但是您可以看到datapool/first文件系统在快照中消耗了 4.78 GB。4 GB 由文件系统上设置的refreservation属性使用,以其他文件系统为代价为其提供 4 GB 的空闲空间。

让自己熟悉-o 空间。这将为你以后省去很多麻烦。虽然几乎为空的未拍摄快照的池可能不是很有挑战性,但随着时间的推移,每个添加的快照或保留可能会增加混乱。空间是你的朋友,但前提是你要和它成为朋友。

posted @ 2024-08-02 19:34  绝不原创的飞龙  阅读(0)  评论(0编辑  收藏  举报