终极文件系统ZFS的使用与优化技巧

  ZFS一直都算是一个神器级别的东西,由于Z是字母表中的最后一个字母,所以很多人将其奉为“终极文件系统”,而我本人对ZFS也是情有独钟,从FreeBSD到Gentoo,都是使用ZFS作为根文件系统。作为文件系统的几个要素来说:ZFS的性能算是中规中矩,对内存要求比较高;稳定性来说,最初是Solaris的文件系统,所以经受过工业环境的考验;而最重要的是ZFS支持相当多的功能特性,告诉我们——文件系统居然可以这样玩。
  当然,由于许可证兼容性的问题,导致ZFS不能集成到Linux内核,所以在Linux下必须是模块的形似使用,这就导致每次更新内核,都需要重新编译安装这些模块。反正都是编译,这让Gentoo的用户感觉不到什么区别,哈哈!

一、ZFS的安装和迁移

  新系统安装,可以参照ZFS文件系统的Gentoo安装,安装和迁移操作系统涉及到的用法罗列在下文。需要注意的是,ZFS的设计颠覆了传统的文件系统,涉及到存储池的概念,具体的原理可以参考ZFS官方手册。

1.1 创建ZFS存储池和文件系统

  个人的使用经验,觉得为系统以及Gentoo的编译部分开辟两个单独的文件系统比较好:一方面可以根据两个不同的使用场景进行参数的设置和优化;同时编译部分的数据是没有意义的,那么在快照和备份的时候,可以不为这部分文件系统进行操作;在迁移和重装系统的时候,也可以忽略这部分数据。

1
2
3
4
5
6
zpool create -f -o ashift=12 -o cachefile=/tmp/zpool.cache -O normalization=formD -m none -R /mnt/gentoo zroot /dev/sda3
zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ zroot/ROOT/gentoo #根文件系统
zfs create -o mountpoint=none zroot/GENTOO
zfs create -o mountpoint=/usr/portage/distfiles -o atime=off zroot/GENTOO/portage
zfs create -o mountpoint=/var/tmp/portage -o sync=disabled zroot/GENTOO/build-dir

1.2 导出和导入ZFS存储池

  由于文件系统的信息都包含在了存储池中,所以导出和导入存储池和挂载卸载文件系统的效果是相同的。

1
2
zpool export -f zroot
zpool import -f -o cachefile= -R /mnt/gentoo zroot

1.3 系统迁移

  系统迁移我认为是zfs十分厉害的东西,既可以用作备份,也可以用于恢复系统。这里显示的是保存到固定的存储介质上,其实ZFS是可以在线迁移的,也就是两台电脑只要网络可通,可以在线将一个电脑上的存储池迁移到两外一台电脑上面。同时zfs send的对象是snapshot,就是你可以迁移任意一个之前备份的文件系统状态。

1
2
3
4
5
#备份:
zfs snapshot -r zroot@go_to_new
zfs send -Rv zroot@go_to_new | gzip > /mnt/zroot_go_to_new.gz
#迁移:
gzcat /mnt/zroot_go_to_new.gz | zfs receive -Fv zroot

二、ZFS的功能和特性

2.1 文件系统清理,检查数据的完整性

  建议一段时间对文件系统进行检查,使用scrub命令即可。该命令以低优先级执行,不会对正在运行的系统有明显的影响。

1
2
sudo zpool scrub zroot
sudo zpool status -v

然后status会不断的显示scan的进度。

scan: scrub in progress since Thu Feb 18 13:12:30 2016
47.7G scanned out of 50.2G at 317M/s, 0h0m to go
0 repaired, 95.09% done

当完成的时候,会显示下面的状态。

scan: scrub repaired 0 in 0h2m with 0 errors on Thu Feb 18 13:15:15 2016

2.2 坏掉的目录和文件修复

  ZFS 使用校验和、冗余和自我修复数据来最大限度地减少出现数据损坏的风险。如果status出现错误,可以尝试:scrub进行清理;导出然后重新导入存储池;删掉出错的文件。
这么看来,ZFS的最初设计已将容错设计到最大话了,如果运行的ZFS真的出错,基本是无能为力了。所以建议:规定时间进行文件系统快照;规定时间把文件系统备份到其他设备上。
个人在FreeBSD和Gentoo上用了两三年的ZFS,都没发生过什么大的问题。

三、文件系统的相关优化和设置

3.1 关闭atime

  这对任何的文件系统都是可用的,可以较为显著地优化系统的性能。
手册显示

除了配额和预留空间外,所有可设置的属性都从父文件系统继承各自的值。

所以不用递归地为每个文件系统都进行参数的设置。

1
2
3
4
5
sudo zfs set atime=off zroot/ROOT/gentoo
sudo zfs set atime=off zroot/GENTOO #可被子文件系统继承
sudo zfs get atime zroot/ROOT/gentoo
NAME PROPERTY VALUE SOURCE
zroot/ROOT/gentoo atime off local

3.2 对某些不常用的目录,可以设置压缩降低数据的写入量

  这样虽然消耗一些CPU和内存,但是不常用的话对系统性能没有太大影响,还可以延长SSD的寿命。该参数设置后,只对新数据有效,原有的数据没有影响。

1
2
3
4
sudo zfs set compression=lz4 zroot/GENTOO/build-dir
sudo zfs get compression zroot/GENTOO/build-dir
NAME PROPERTY VALUE SOURCE
zroot/GENTOO/build-dir compression lz4 local

3.3 交换分区

  目前ZFS上的交换分区还不太稳定,不建议使用。
单独交换分区不要使用discard挂载命令,因为每次在系统启动的时候,系统会自动TRIM它,而如果手动加上该参数,那么每次在删除文件时候都会进行TRIM,降低系统的性能。
修改/etc/sysctl.conf文件,添加

vm.swappiness = 1

减少交换分区的使用率。

参考