Java Solaris 加入Sun中国技术社区 我的社区 注册说明

BigAdmin 系统管理门户网站
Feature Article

ZFS-Sun 的最新文件系统(第 2 部分:易于管理且功能不断增强)

第 1 部分:存储完整性、安全性及可伸缩性Amy Rich,2006 年 9 月

ZFS 资源
培训资源


目录:


简介

ZFS-Sun 的最新文件系统(第 1 部分:存储完整性、安全性及可伸缩性)是这个由两部分组成的系列专题的第一篇文章,其中介绍了 Sun 首创新文件系统的一些基本情况,并讨论了其数据完整性和安全性模型及其强大的可伸缩性。本文将重点介绍易管理性,包括实际使用演示和即将发布的一些精彩新功能。

ZFS 的完整性和可靠性非常杰出,性能卓越,安全性也很出众,但是,怎么才能让管理也轻松起来呢?作为系统管理员,我们往往需要不断摆弄文件系统,力求最充分地利用其全部性能。也许您已经发现了一种方法,就是在设置 VxVM 时不让第二个镜像成为可引导镜像,但这种方法颇为繁琐。如果能把一切都交给文件系统/卷管理器处理,完全不必去烦恼到底该怎么办,这样多好啊!您是幸运的。ZFS 工程师们已经为您考虑到这一点了。


基于对象的存储

ZFS 全部采用基于对象的存储。卷管理器存储池的基础构件是 zpool。所有文件系统组件都构建在 zpool 上。如果要向池中添加存储,只需向 ZFS 提交文件、磁盘片或整个磁盘。需要运行 formatnewfs 来获得可用文件系统的日子已经一去不复返了。实际上,提交整个磁盘给 ZFS 能更好地优化其 I/O。下面我们来了解一下 zpool(1M) 手册页中的选项:

zpool - configures ZFS storage pools
zpool create [-fn] [-R root] [-M mountpoint] pool vdev...
zpool add [-fn] pool vdev...
zpool list [-H] [-o field[,fi] [pool] ...
zpool status [-xv] [pool] ...

zpool destroy [-f] pool
zpool iostat [-v] [pool] ... [interval [count]]

zpool attach [-f] pool device new_device
zpool detach pool device

zpool replace [-f] pool device [new_device]

zpool scrub [-s] pool ...

zpool offline pool device ...
zpool online pool device ...

zpool export [-f] pool
zpool import [-d dir]
zpool import [-d dir] [-f] [-o options] [-R root] pool |  id [newpool]
zpool import [-d dir] [-f] [-a]

下面我们将进行一些实际操作。首先,通过对两个磁盘片进行镜像创建名为 testpoolzpool

# zpool create testpool mirror c0t0d0s5 c0t1d0s5

# zpool list
NAME                    SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT
testpool               7.94G    164K   7.94G     0%  ONLINE     -

# zpool status
   pool: testpool
  state: ONLINE
  scrub: none requested
 config:

        NAME          STATE     READ WRITE CKSUM
        testpool      ONLINE       0     0     0
          mirror      ONLINE       0     0     0
            c0t0d0s5  ONLINE       0     0     0
            c0t1d0s5  ONLINE       0     0     0

我们无需使用 metainit 等命令来设置镜像的每一半,也并不真正需要 Solaris 卷管理器或 VxVM 中出现的抽象 GUI,因此十分简便。只需一个命令,即可大功告成!如果特别钟爱 GUI,也可以通过 Web 运行 /usr/sbin/smcwebserver 或使用 Solaris Express 中的 svcadm enable svc:/system/webconsole:console 来完成 ZFS 管理。

现在存储空间已经分配好了,可以开始建立文件系统。在 ZFS 中,文件系统是分层的,因此是很有用的管理控制点。可以对每个文件系统设置下列各项:大小、预留空间(为数据集及其后代保留的最小空间)、配额、压缩选项、备份及快照。例如,在起始目录服务器中,每人都有自己的文件系统,您可以将空间使用总量限制为 1 兆兆字节,并启用压缩。然后,便可确保特定 VIP 用户(或应用程序)始终有至少 1 千兆字节的可用空间,并每小时(通过 cron)进行快照。次要的用户可通过配额加以限制,每天才进行一次快照。

以下是 zfs(1M) 手册页中的选项:

zfs create filesystem
zfs create [-s] [-b blocksize] -V size volume
zfs destroy [-rRf] filesystem|volume|snapshot
zfs clone snapshot filesystem|volume
zfs rename  filesystem|volume|snapshot filesystem|volume|snapshot
zfs snapshot  filesystem@name|volume@name
zfs rollback [-rRf] snapshot
zfs list [-rH] [-o property[,property]...] [ -t type[,type]...][filesystem|volume|snapshot] ...
zfs set property=value filesystem|volume...
zfs get [-rHp] [-o field[,field]...] [-s source[,source]...]all | 
	property[,property]... filesystem|volume|snapshot...
zfs inherit [-r] property filesystem|volume...
zfs mount
zfs mount [-o options] [-O] -a
zfs mount [-o options] [-O] filesystem
zfs unmount [-f] -a
zfs unmount [-f] [filesystem|mountpoint]
zfs share -a
zfs share filesystem
zfs unshare [-f] -a
zfs unshare [-f] [filesystem|mountpoint]
zfs backup [-i snapshot] snapshot
zfs restore [-vn ] filesystem|volume|snapshot
zfs restore [-vn ] -d filesystem

下面我们在存储池 testpool 中创建两个文件系统 testfstestfs2

# zfs create testpool/testfs

# zfs list
NAME                   USED  AVAIL  REFER  MOUNTPOINT
testpool               268K  7.88G    99K  /testpool
testpool/testfs       98.5K  7.88G  98.5K  /testpool/testfs

# zfs create testpool/testfs2

# zfs list
NAME                   USED  AVAIL  REFER  MOUNTPOINT
testpool               376K  7.88G  99.5K  /testpool
testpool/testfs       98.5K  7.88G  98.5K  /testpool/testfs
testpool/testfs2      98.5K  7.88G  98.5K  /testpool/testfs2

# df -k
Filesystem           1k-blocks      Used Available Use% Mounted on
/dev/md/dsk/d0         8262869    751774   7428467  10% /
swap                  11800800       784  11800016   1% /etc/svc/volatile
/dev/md/dsk/d30        8262869     23616   8156625   1% /var
swap                  11800016         0  11800016   0% /tmp
swap                  11800040        24  11800016   1% /var/run
testpool               8257771       100   8257672   1% /testpool
testpool/testfs        8257770        99   8257672   1% /testpool/testfs
testpool/testfs2       8257770        99   8257672   1% /testpool/testfs2

同样地,这项操作也只需要一个简单的命令就可完成。我们不必运行 newfsmount,也不必编辑 vfstab。ZFS 包揽了一切。

可以看到,每个 ZFS 文件系统可以访问该存储池的所有资源。如果我们在 /testpool/testfs 下创建文件系统,它将继承 /testpool/testfs 的所有属性,除非我们特地将其覆盖。如果要将文件系统挂载到 / 以外的地方,并创建一些子文件系统, 可以按以下方式实现这些目标:

# zfs set mountpoint=/devel/testfs testpool/testfs
# zfs create testpool/testfs/dir1
# zfs create testpool/testfs/dir2
# zfs create testpool/testfs/dir3

# df -k
Filesystem           1k-blocks    Used Available Use% Mounted on
/dev/md/dsk/d0         8262869  751774   7428467  10% /
swap                  11800800     784  11800016   1% /etc/svc/volatile
/dev/md/dsk/d30        8262869   23616   8156625   1% /var
swap                  11800016       0  11800016   0% /tmp
swap                  11800040      24  11800016   1% /var/run
testpool               8257771     100   8257672   1% /testpool
testpool/testfs2       8257770      99   8257672   1% /testpool/testfs2
testpool/testfs       16515535      99  16515437   1% /devel/testfs
testpool/testfs/dir1  16515214      99  16515115   1% /devel/testfs/dir1
testpool/testfs/dir2  16515214      99  16515115   1% /devel/testfs/dir2
testpool/testfs/dir3  16515214      99  16515115   1% /devel/testfs/dir3

ZFS 会自动将 testpool/testfs/dir1 重新定位到正确的挂载点,这是因为它继承了其父文件系统 testpool/testfs 的属性。同样地,创建新文件系统与创建新目录或文件一样简单。

以下是设置文件系统某些属性的示例:

# zfs set sharenfs=rw testpool/testfs
# zfs compression=on testpool/testfs
# zfs set quota=10g testpool/testfs/dir1
   (在逻辑上限制空间)
# zfs set reservation=20g testpool/testfs/dir2
   (在逻辑上预先分配空间)

现在,如果用尽了存储池空间,需要增加容量,应该怎么办?只需通过 zpool add 添加更多设备即可:

# zpool add testpool c0t0d0s6 c0t1d0s6
invalid vdev specification
use '-f' to override the following errors:
mismatched replication level: pool uses 2-way mirror and 
new vdev uses 1-way disk

ZFS 非常聪明:它知道我之前的设备都是镜像,并发现我试图添加未经镜像的存储。如果我确实要这么做,可以像上面说的那样,通过 -f 强制执行该操作。这其实只是我犯的一个错误,因此,我可以返回并提供正确的信息:

# zpool add testpool mirror c0t0d0s6 c0t1d0s6

  # zfs list
  NAME                   USED  AVAIL  REFER  MOUNTPOINT
  testpool               396K  15.8G  99.5K  /testpool
  testpool/testfs       98.5K  15.8G  98.5K  /testpool/testfs
  testpool/testfs2      98.5K  15.8G  98.5K  /testpool/testfs2

同样地,由于元数据是动态的,因此无需等待存储池调整大小或等待镜像重新同步,即可使用新的空间。此时,如果运行 zpool status,可以看到新创建的镜像是由两个镜像经条带化处理构成的,每个镜像包含两个设备:

# zpool status
    pool: testpool
   state: ONLINE
   scrub: none requested
  config:

        NAME          STATE     READ WRITE CKSUM
        testpool      ONLINE       0     0     0
          mirror      ONLINE       0     0     0
            c0t0d0s5  ONLINE       0     0     0
            c0t1d0s5  ONLINE       0     0     0
          mirror      ONLINE       0     0     0
            c0t0d0s6  ONLINE       0     0     0
            c0t1d0s6  ONLINE       0     0     0

RAID-Z

到现在为止,我们只了解了镜像存储。ZFS 还实现了另一种类型的 RAID,称之为 RAID-Z,它与 RAID-5 类似,但采用了可变条带宽度来消除 RAID-5 中称为“RAID-5 写入漏洞”的问题。在 RAID-5 中,写入是针对两个或更多独立设备进行的,奇偶块则作为每个条带的组件进行写入。由于这些写入并不是原子操作,因此数据和奇偶校验事务之间的电源故障可能导致数据损坏。

有些供应商试图通过奇偶校验区域日志记录(如脏区域日志记录,仅限奇偶校验磁盘)或电池供电的 NVRAM 来解决这个问题。在 NVRAM 解决方案中,数据被写入 NVRAM,随后数据和奇偶校验信息被写入磁盘,最后 NVRAM 被释放。NVRAM 非常昂贵,有时可能形成瓶颈。此外,停机三天后存储在 NVRAM 中的所有数据将丢失。在扩展的灾难恢复情形下,这种数据损失可能是无法接受的。

与 RAID-5 不同,所有 RAID-Z 写操作都是完整条带化写操作,也就是说写入到所有磁盘。这样,既没有读取-修改-写入开销,也没有 RAID-5 写入漏洞,又无需 NVRAM 硬件。如果想试着确定何时使用直接镜像以及何时使用 RAID-Z,可以看看 Roch Bourbonnais 的博客文章 When to (and not to) use RAID-Z


文件系统快照和克隆

现在,有些文件系统中有很多数据,如果用户(或系统管理员)不慎修改或删除了一些数据且需要恢复数据,这时该怎么办?如果使用备份磁带或磁盘,速度比较慢,而且最终用户操作起来也不方便。幸好,ZFS 具备快照功能(与其他存储供应商提供的快照功能一样),更可喜的是由于采用写复制体系结构,几乎没有任何开销。实际上,捕获快照有时比释放包含旧数据的块更快!

在 ZFS 中,与 Network Appliance Inc. 的实现方式一样,只跟踪修改过的数据。可保留的快照数量仅受存储容量的限制。下面我们简单了解一下快照操作。在每个 ZFS 文件系统中都有一个 .zfs 目录,该目录中包含一个快照子目录:

# cd /testpool/testfs2
# ls -al .zfs/snapshot

total 0
dr-xr-xr-x    2 root     root            2 Jun 29 17:18 .
dr-xr-xr-x    3 root     root            3 Jun 29 17:18 ..

# cp /bin/sh /bin/tcsh /bin/ksh .
# zfs snapshot testpool/testfs2@snap1
# ls -al .zfs/snapshot/snap1/

total 786
drwxr-xr-x    2 root     sys             5 Jun 29 17:17 .
dr-xr-xr-x    3 root     root            3 Jun 29 17:19 ..
-r-xr-xr-x    1 root     other      238332 Jun 29 17:17 ksh
-r-xr-xr-x    1 root     other      113160 Jun 29 17:17 sh
-r-xr-xr-x    1 root     other      364176 Jun 29 17:17 tcsh

# zfs list testpool/testfs2@snap1

NAME                     USED  AVAIL  REFER  MOUNTPOINT
testpool/testfs2@snap1      0      -   882K  -

如果删除 ksh 后又决定将其恢复,可以从 .zfs/snapshot/snap1 目录中将其复制出来:

# rm ksh
# ls -al

total 514
drwxr-xr-x    2 root     sys             4 Jun 29 17:24 .
drwxr-xr-x    4 root     sys             4 May 22 10:48 ..
dr-xr-xr-x    3 root     root            3 Jun 29 17:25 .zfs
-r-xr-xr-x    1 root     other      113160 Jun 29 17:17 sh
-r-xr-xr-x    1 root     other      364176 Jun 29 17:17 tcsh

# cp .zfs/snapshot/snap1/ksh .
# ls -al
total 787
drwxr-xr-x    2 root     sys             5 Jun 29 17:26 .
drwxr-xr-x    4 root     sys             4 May 22 10:48 ..
dr-xr-xr-x    3 root     root            3 Jun 29 17:27 .zfs
-r-xr-xr-x    1 root     other      238332 Jun 29 17:26 ksh
-r-xr-xr-x    1 root     other      113160 Jun 29 17:17 sh
-r-xr-xr-x    1 root     other      364176 Jun 29 17:17 tcsh

另一种选择是对整个文件系统执行回滚,使其与特定快照匹配:

# rm ksh
# cp /bin/bash .
# ls -al
total 515
drwxr-xr-x    2 root     sys             5 Jun 29 17:28 .
drwxr-xr-x    4 root     sys             4 May 22 10:48 ..
dr-xr-xr-x    3 root     root            3 Jun 29 17:28 .zfs
-r-xr-xr-x    1 root     other      737148 Jun 29 17:28 bash
-r-xr-xr-x    1 root     other      113160 Jun 29 17:17 sh
-r-xr-xr-x    1 root     other      364176 Jun 29 17:17 tcsh

# ls -al .zfs/snapshot/snap1/
total 786
drwxr-xr-x    2 root     sys             5 Jun 29 17:19 .
dr-xr-xr-x    3 root     root            3 Jun 29 17:28 ..
-r-xr-xr-x    1 root     other      238332 Jun 29 17:19 ksh
-r-xr-xr-x    1 root     other      113160 Jun 29 17:17 sh
-r-xr-xr-x    1 root     other      364176 Jun 29 17:17 tcsh

# cd /
# zfs rollback testpool/testfs2@snap1
# ls -al /testpool/testfs2/
total 787
drwxr-xr-x    2 root     sys             5 Jun 29 17:19 .
drwxr-xr-x    4 root     sys             4 Jun 29 17:29 ..
dr-xr-xr-x    3 root     root            3 Jun 29 17:29 .zfs
-r-xr-xr-x    1 root     other      238332 Jun 29 17:19 ksh
-r-xr-xr-x    1 root     other      113160 Jun 29 17:17 sh
-r-xr-xr-x    1 root     other      364176 Jun 29 17:17 tcsh

如果不再需要某个快照,可以通过 zfs destroy 恢复该空间:

# zfs destroy testpool/testfs2@snap1
# ls -al testpool/testfs2/.zfs/snapshot/
total 0
dr-xr-xr-x    2 root     root            2 Jun 29 17:31 .
dr-xr-xr-x    3 root     root            3 Jun 29 17:31 ..

这里有一个小窍门,按日期命名快照以简化跟踪通常很有用。

还有一个与快照类似的有用功能是克隆。与快照不同的是,克隆的文件可以进行修改和写入。如果您的数据集几乎但不完全相同,这个功能通常很有用处。引导无盘客户机的服务器就是一个例子。在下面这个示例中,我将为第一个无盘客户机安装文件系统,捕获快照,对快照进行克隆,然后对克隆文件之一进行修改:

# zfs create testpool/diskless/nevada
   (在 testpool/diskless/nevada 中创建可引导的文件系统)
# zfs create testpool/diskless/sb2500
# zfs snapshot testpool/diskless/nevada@snap1
# zfs clone testpool/diskless/nevada@snap1 \
  testpool/diskless/sb2500/nevada
# vi /testpool/diskless/sb2500/nevada/etc/hosts
   (将主机名更改为 sb2500 并保存)

自动字节存储顺序自适应

与 UFS 相同,SPARC 和 x64 硬件均支持 ZFS。与 UFS 不同的是,可以将数据磁盘从一个体系结构中拆除,然后添加到另一个体系结构中,而无需考虑格式或字节存储顺序问题。从 SPARC 处理器上运行的系统中拆除一个数据磁盘,再安装到 x64 系统中,这个过程目前是完全透明的。Sun 将之称为自动字节存储顺序自适应。

从磁盘读取块时,ZFS 会检查字节存储顺序。如果其字节存储顺序与当前体系结构匹配,则不进行任何更改。如果不匹配,则 ZFS 在显示数据之前对文件进行字节交换,然后以自己的本机字节存储顺序写回该块。因此,虽然访问非本机块时会出现一些开销,但这很少发生,因为这些块会按新计算机本机字节存储顺序重写。请注意,字节存储顺序转换只适用于 ZFS 元数据块,而非用户数据。

如果要将数据磁盘从一台计算机迁移到另一台计算机,首先要将该物理介质上的所有存储池导出,将磁盘拆离,安装到新计算机,然后导入存储池:

# zpool export testpool
   (物理移动磁盘)
# zpool import

在导出过程中,大小、配额、预留空间、NFS 可导出性等所有文件系统元数据将得以保存,磁盘和存储池在逻辑上从系统中删除。在新计算机上导入数据时,可以指定特定存储池,也可以直接运行上面所述的 import 命令,扫描目前尚未加入系统的任何存储池并全部导入。


不断增强的 ZFS

如您所见,ZFS 中提供了大量可节省时间和资金的功能。但从任何方面而言,此项目并未就此完结。很多更加精彩的功能正呼之欲出。

ZFS 最热门的话题之一就是可引导的 ZFS,目前这个子项目正在 OpenSolaris 下进行。目前,富有冒险精神的用户可以根据 Tabriz Leman 有关 ZFS Mountroot 的博客文章中的指导,使用 UFS shim 引导至 x64 上的 ZFS 根文件系统。Sun 已讨论过通过让 SPARC OBP 使用 GRUB 作为引导装载程序,从而尽快为基于 SPARC 技术运行的计算机添加 ZFS 可引导性。

Jeff Bonwick 在 zfs-discuss 列表中的留言 "[zfs-discuss] Re: Re: Bootable ZFS and Live upgrade" 中对 ZFS 引导也进行了讨论。

很多人已经在使用 ZFS 快照来执行对其文件系统的快捷但粗劣的备份,但很有可能快照和实际商业备份软件之间将更紧密地集成。有关快照工作原理的代码级讨论,请参见 Matthew Ahrens 有关快照的博客文章

根据 Eric Schrock 在其 zfs-discuss 上有关可引导的 ZFS 和 Live Upgrade 的留言中透露的信息,已有计划通过 ZFS 克隆来支持 LiveUpgrade。为实现这一目标,必须首先修改安装和升级工具,并为 ZFS 添加 clone swap 支持。该功能已经添加到 Solaris Express 中。

ZFS 还致力于网络和物理介质上的安全性。OpenSolaris 中的 ZFS 磁盘加密支持项目目前正在进行,以便为 ZFS 提供盘上加密和解密以及密钥管理支持。Darren Moffat 为 opensolaris.org 撰写了一篇 zfs-crypto-project 文档草稿,对这项计划实现的各个方面进行了详细介绍。该项目的目的在于保护 SAN 通过不可信路径提供的数据,在物理存储器遭窃后保护数据,以及提供一个安全删除机制。

ZFS 加密文件系统密钥的破坏就是一种安全删除,一旦没有了密钥,就无法再检索数据。在即将出炉的其他安全功能中,符合 DOD 标准的安全删除也是其中之一。在这个方案中,一旦块被释放,就会被多次覆写。

要随时了解其他信息,请访问 opensolaris.org Web 站点订阅 zfs-discuss 或 zfs-code 邮件列表


资源

除非另行说明,否则此处所有技术手册(包括文章、常见问题解答和样例)中的代码都按此许可提供。