ZFS文件系统运维笔记

ZFS 是Sun Microsystems开发的文件系统,该公司后来为Oracle收购,ZFS项目后来成为了开源项目,并移植到了Linux。虽然该项目依然处于Beta阶段,但大部分功能都运行良好,而且原来出现的一些问题也都得到了解决。该项目当前注重于添加新的功能。

ZFS是把磁盘管理、逻辑卷与文件系统整合起来的软件层。由于它提供压缩、ARC(Adaptive Replacement Cache,自适应的转换缓存)、去除重复(Deduplication)以及快照等功能,因此很适合与GlusterFS一起,用作Brick的后端。

周边不少运维同行因ZFS的原因而选择FreeBSD,一言蔽之就是ZFS是一种Niubility文件系统。

RHEL/CentOS-7

安装ZFS

安装epel仓库包

yum -y install epel-release

使用RPM安装

  • CentOS-7.9
sudo yum install http://download.zfsonlinux.org/epel/zfs-release.el7_9.noarch.rpm
  • CentOS-7.8

  • sudo yum install http://download.zfsonlinux.org/epel/zfs-release.el7_8.noarch.rpm
    

编辑/etc/yum.repos.d/zfs.repo文件,将 dkms repo 中设置为1

[zfs-kmod]
name=ZFS on Linux for EL7 - kmod
...
enabled=1
...

接下来执行

yum -y install zfs

执行以下命令,启动ZFS组件

systemctl enable zfs.target
systemctl enable --now zfs-import-scan.service

可以使用以下查看zfs模块

# lsmod |grep zfs
zfs                  4224878  0
zunicode              331170  1 zfs
zzstd                 460780  1 zfs
zlua                  151526  1 zfs
zcommon                94285  1 zfs
znvpair                94388  2 zfs,zcommon
zavl                   15698  1 zfs
icp                   301775  1 zfs
spl                    96750  6 icp,zfs,zavl,zzstd,zcommon,znvpair

如果没有加载模块使用以下:

modprobe zfs

配置ZFS

创建一个名为pool1的ZFS池,分配将sdb、sdc加入到池中

sudo lsblk
sudo zpool create brick1 /dev/sdb /dev/sdc     # 建议使用UUID

其它

#与RAID0类似
zpool create vol0 /dev/sd{b,c}
#与RAID1类似
zpool create vol0 mirror /dev/sd{b,c}
#与RAID5类似
zpool create vol0 raidz /dev/sd{b,c,d}
#与RAID6类似
zpool create vol0 raidz2 /dev/sd{b,c,d,e}

检查创建的池是否工作

zpool list  或者 zpool status
df -h

如果需要启用压缩功能,并把这个Pool的挂载点设置成/bricks/brick1,为此,需要先执行以下命令:

zfs set compression=lz4 brick1

lz4算法相对比较小的资源开销。

然后再执行

zfs set mountpoint=/bricks/brick1 brick1

提示:也可以在创建的时候加入挂载参数

zfs create -o mountpoint=/export/zfs tank/test2

文件测试

cd /bricks/brick1
touch test1.txt
echo "my test data" > test2.txt

优化项

在ZFS文件系统方面,我们主要调整ARC与L2ARC这两涉及性能的参数。

ARC

对于ZFS需要调整的主要是读缓存,也就是ARC。给ARC多分配一些内存,能够显著提升ZFS的读取效率。如虚拟机共有32GB内存,其中4G划分给GlusterFS,现在拿出26G给ZFS,余下2G给操作系统。

echo 27917287424  >/sys/module/zfs/parameters/zfs_arc_max

命令中数字是26GB所对应的字节数。这样修改可以令新的设置当场生效,但没有办法在重启后保留。要想让系统在每次重启时都采用这个值,需要创建/etc/modprobe.d/zfs.conf文件,添加如下内容:

options zfs zfs_arc_max=27917287424

这样就可以让新的值在重启后也得以保留。

L2ARC

L2ARC是二级读缓存,也就是刚才添加到zpool里的缓存盘。调整相关参数可以降低预热时间,让系统更迅速地将频繁用到的文件填充到缓存。该参数的单位是每秒钟的字节数,这可以通过下行命令修改:

echo 2621440000 >/sys/module/zfs/parameters/l2arc_write_max

重启生效时也需要添加如下配置:

options zfs l2arc_write_max=2621440000

这样改可以把L2ARC的最大填充速度,设为每秒256MB。如果改用更高级的虚拟机,那么至少将这个值翻倍。

禁用atime参数

需要更好的系统性能是可以理解的,您可能认为 raid 配置和备份就足够了,因此您将禁用校验和。不。尝试在使用不同类型的校验和算法时监控系统性能并选择合适的算法。

记录访问时间是一个属性,也可以关闭以提高池性能。

zfs set atime=off <pool_name>

或者

zfs set atime=on <pool_name>

zfs set relatime=on <pool_name>

FIO测试工具

要想用FIO工具测试性能,最简单的办法就是创建配置文件,告诉软件应该如何动作,配置文件如下:

# cat > /root/test.fio<<EOF
[global]
name=fw-nocache-random
rw=randrw
rwmixread=50
rwmixwrite=50
group_reporting=1
bs=1M
direct=1
numjobs=4
time_based=1
runtime=180
ioengine=libaio
iodepth=64

[file1]
size=10G
filename=rw-nocache-random.1
EOF

进入测试的路径进行测试

cd /zpool1
fio /root/test.fio

同时可以打开以下状态查看

zpool iostat -vLP 1

扩展

有两种方式进行扩容,一种是垂直扩展,也就是在每个节点上添加更多的brick ;别一种是水平扩展,也就是在集群中添加更多的节点。

在这两种方式中,垂直扩展要比水平扩展简单,因为它需要的资源比较少,例如,我们只需要给每个节点的ZFS pool添加一块128G的磁盘,就可以让整个方案的可用空间增加256GB。

下述命令能够向ZFS pool添加磁盘:

zpool add brick1 /dev/disk/by-id/<disk-id>

重复删除数据功能

使用以下命令查看

zfs get dedup zpool1

要在你的ZFS池上启用重复数据删除,请运行下面的命令。

$ sudo zfs set dedup=on pool1

运维指令

#查看当前存储池挂载状态
zfs list
#查看当前存储池状态
zpool status
#使用 sdb、sdc、sdd 这几块硬盘创建一个名为 vol0 的池
zpool create vol0 sdb sdc sdd
#可以使用-f启用强制模式,这个在正常的创建中没有必要,如果碰到你要创建raidz或者mirror类型的池,那么这个可以帮助你忽略由于添加的硬盘容量不相等导致的错误提示
#查看存储池 vol0 的一些信息
zpool get all vol0
#将硬盘 sde 添加到池 vol0 中
zpool add vol0 sde
#使用硬盘 sdf 替换 vol0 池中的 sde
zpool replace vol0 sde sdf
#检测池 vol0 是否存在问题
zpool scrub vol0
#查看池 vol0 的IO使用状况,可以加 -v 来详细到池所拥有的每块磁盘
zpool iostat vol0

故障模拟

模拟损坏修复
1、查看池情况

#zpool status vol0

2、损坏一个盘后

#清理并检查池情况
#zpool scrub vol0
#zpool status vol0
  pool: vol0
 state: DEGRADED
status: One or more devices could not be used because the label is missing or
        invalid.  Sufficient replicas exist for the pool to continue
        functioning in a degraded state.
action: Replace the device using 'zpool replace'.
   see: http://zfsonlinux.org/msg/ZFS-8000-4J
  scan: scrub repaired 0B in 0h0m with 0 errors on Wed Aug 21 16:41:03 2019
config:

        NAME                     STATE     READ WRITE CKSUM
        vol0                     DEGRADED     0     0     0
          raidz1-0               DEGRADED     0     0     0
            sdb                  ONLINE       0     0     0
            sdc                  ONLINE       0     0     0
            sdd  				 UNAVAIL      0     0     0  
errors: No known data errors

3、用新盘修复

zpool replace vol0 /dev/sdd /dev/sde

4、添加热备

zpool add vol0 spare /dev/sde

5、添加新raidz盘

zpool add vol0 raidz /dev/sd{e,f,g}