ZFS 手册

ZFS (Zettabyte file system) 是一个组合文件系统和逻辑卷管理器 由Jeff Bonwick和Matthew Ahrens领导的Sun Microsystems团队设计和实施,目前它可以存储多达256个ZiB(zebibytes)。

它开发始于2001年,并于2004年正式宣布。2005年,它被集成到Solaris的主干中,并作为OpenSolaris的一部分发布,目前,截至2015年1月,它原生于Solaris,OpenSolaris,OpenIndiana,illumos,Joyent SmartOS,OmniOS,FreeBSD。

Linux 受 GNU 公共许可证(General Public License,GPL)保护,而 ZFS 是遵循由 Sun 的通用开发和发布许可证(Common Development and Distribution License,CDDL)的。这些许可证协议的目标不同,各自的限制会有些冲突。这也就是为什么至今只有Ubuntu 16.04 + 引入了ZFS的原生内核模块。

术语 解释 备注
zpool ZFS Pool,由一个或多个VDEV构成,zpool之上再提供dataset和zvol。 zpool 不同于传统的FS特性,像LVM的VG,但是LVM最终做成LV之后还需要格式化才能使用,而zpool创建之后即使不创建dataset就可以直接使用了。
VDEV DISK,FILE VDEV 后端储存设备的类型,当然不建议FILE
Mirror 镜像VDEV,类似RAID-1
RAIDZ-1,RAIDZ-2,RAIDZ-3 RAIDZ 类型的VDEV,类似传统RAID,但是不存在写漏洞。
dataset * 数据集,比如在tank这个zpool上创建一个名为data的dataset,就表现为“tank/data”
* 可以针对不同dataset设置权限,限额,快照,挂载点等等高级特性;
zvol ZFS 提供的块设备方式,类似与dataset(文件系统),zvol为block设备,可以被格式化,可以被iSCSI分享 zvol_with_iscsi
Spare 热备盘
Slog / ZIL 单独额外的写日志设备,可以提高同步写的性能。
ARC / L2ARC 读缓存设备,一个基于RAM,一个基于外置高速SSD。
Deduplication 去重
Scrub ZFS 有scrub来替代fsck 来做一致性的检查。
在不正常的关闭之后并不需要做清洁动作,但建议每三个月至少执行一次。
snapshot 快照,可基于dataset,zvol做快照,还可以把快照克隆为dataset

Note: ZFS 是一个先进的文件系统,有了这个文件系统,大家再也不需要任何Volume Manager了。

特性 说明 备注
128文件系统 ZFS是128位,这意味着它具有很高的可扩展性:
* 最大单个文件大小为 16 EB(1 EB = 1024 PB);
* 最大 256 千万亿(256*1015 )的 ZB(1 ZB = 1024 EB)的存储;
储存池 ZFS作为一个全新的文件系统,全面抛弃传统File System + Volume Manager + Storage的架构,
所有的存储设备是通过ZFS Pool进行管理,只要把各种存储设备加 入同一个ZFS Pool,就可以轻松的在这个ZFS Pool管理配置文件系统。
不需要格式化就可以用了
丰富的VDEV架构 支持non-RAID(单盘),RAIDZ-1,RAIDZ-2,RAIDZ-3,Mirror,RAID-0,RAID-10等阵列级别,甚至一个zpool里可以包含多种VDEV以实现RAID-50,RAID-60等级别。
热备盘支持 支持Hot-spare,最大程度保证pool的数据安全。
缓存特性 不光支持基于内存的ARC缓存,还支持基于外部高速设备(SSD等)的ZiL(写)和cache(读)缓存,丰富了储存的层级。
COW
(写时拷贝)
ZFS 可以彻底抛弃fsck这种工具,因为ZFS是一个基于COW(Copy on Write)机制的文件系统。
COW是不会对硬盘上现有的文件进行重写,保证所有硬盘上的文件都是有效的。
所以不会有这种inconsistent的概念,自然就不需要这种工具了。
快照 非常简单高效的快照管理。
数据完整性验证,自动修复 在线检查(清理)和在线恢复故障,即scrub功能,实际使用中,比传统的阵列卡rebuild快得不是一点半点。 zpool scrub tank
安全 在安全上,ZFS支持类似NT风格NFSv4版的ACL(读取控制列表)。而且前面所提到的256位验证码,用户可选择多种验证方式,包括SHA-256验证算法,从而在物理存储单元级别上保证数据的安全性。
Quota
(配额)
一条命令搞定限制某个 dataset 的容量上限。
zfs set quota=10G tank/data
Reservation
(预留)
Compression
(压缩)
zlib等算法进行数据压缩
Clone
(克隆)
dataset,snapshot克隆
send / receive 在不同zpool和dataset之间自由的发送接收,甚至可以通过网络来传送至另外的主机,类似网络拷贝。

要使用 ZFS 有很多种途径,大致如下:

Note: 对于一般用户,特别是对*BSD和UNIX没有使用经验的,使用ZFS的最简单最原生的方式为 ZFS on Ubuntu16.04 +,该方式提供了原生的内核模块。

  • ZFS support was added to Ubuntu Wily 15.10 as a technology preview and comes fully supported in Ubuntu Xenial 16.04. Note that ZFS is only supported on 64 bit architectures. Also note that currently only MAAS allows ZFS to be installed as a root filesystem.


# 查看zfs.ko
locate zfs.ko
modprobe zfs
lsmod | grep zfs
modinfo zfs
# 安装zfs用户工具
sudo apt install zfsutils-linux

ZFS 集文件系统和卷管理器为一体,所以会和普通文件系统(如xfs)有所不同,但是当你熟悉这些对象后,你一定会惊奇这样科学高效的设计!

总的来说,ZFS 中有以下几种管理对象:

  • pool/zpool
    • 由若干磁盘/块设备组成的一个pool,可以由几种架构组成,如stripe,mirror,RAIDZ-1,RAIDZ-2,RAIDZ-3等,也可以将这几种架构混合使用;
    • 通过 zpool create 命令创建;
    • 通过 zpool list 查看;
  • dataset
    • 就是zfs本身,标准的POSIX文件系统;
    • 通过 zfs create tank/data 创建,后就会有/tank/data这个挂载点,就和其他FS一样使用了;
    • 通过 zfs list 查看;
  • volume/zvol
  • snapshot
    • 顾名思义,快照,可以为dataset,zvol创建快照;
    • 快照不能被直接访问,通过克隆快照为dataset;
    • 可以配合windows的shadowcopy(卷影复制)和SAMBA来提供文件共享服务; shadow_cpoy

6.1. zpool 管理

创建zpool:

# 获取磁盘路径,强烈建议使用这种磁盘路径!!
ls /dev/disk/by-id/ | grep -v part
zpool create -f -o ashift=12 -O dedup=off -O atime=off -O compress=off tank raidz1 <disk_by_id>

参数:

  • create 创建zpool
  • -f: 强制创建,不显示相关警告
  • -m: 另设挂载点,默认为 /<pool_name>
  • raidz 阵列冗余级别,类似raid5,还有raidz2,raidz3
  • disk_by_ids 通过 ls /dev/disk/by-id查看
  • -o 针对zpool的属性设置,version=28兼容原生zfs和zol
  • -O 针对zfs文件系统的属性设置
  • -ashift=12 针对4K对齐
  • -atime=off 关闭访问时间更新
  • -dedup=off 关闭数据去重

查看ashift:

zdb | grep ashift

导入zpool:

# 导入名为tank的zpool
zpool import tank
# 将名为tank的zpool导入为tank2
zpool import -f tank [tank2]

删除zpool:

# destroy all datasets in the pool
zfs destroy -r tank
# destroy the pool itself
zpool destroy tank

重命名zpool:

# 还未导入zpool的情况下
zpool import -f oldname newname
# 已经导入zpool的情况下
zpool export oldname
zpool import oldname newname

查看zpool状态:

# 列出zpool列表
zpool list
# 查看zpool状态
zpool status -v
# 每秒刷新一次io状态
zpool iostat -v 1

更新zpool.cache文件:

zpool set cachefile=/etc/zfs/zpool.cache tank

6.2. dataset 管理

查看 dataset:

# 查看全部卷
zfs list
# 查看tank/data,类型为快照的卷
zfs list -r -t snapshot tank/data
# 查看tank/data,类型为volume的卷
zfs list -r -t volume tank/data

创建 dataset:

# 卷将被自动挂载在 /tank/volumes1/
zfs create tank/volume1

销毁 dataset:

# 销毁 dataset
zfs destroy tank/data
# 同时销毁子dataset
zfs destroy -r tank/data

挂载/卸载dataset:

zfs mount tank/dataset1
zfs unmount tank/dataset1

如果数据集存在快照,则不能销毁该数据集。

dataset 限额:

zfs set quota=20G tank/data

属性设置: 1)

# 查看tank的某个属性
zfs get <property> tank/data
# 查看tank的全部属性
zfs get all tank
# 设置属性
zfs set <property> tank/data

ZFS 由于是从 Solaris 引入而来,所以自身也具备完善的命令来共享ZFS,如通过NFS和Samaba。

但是不同的发行版本,特别是UNIX,Solaris,和Linux差别较大,所以需要区别对待。总体来说,Oracle ZFS就通过集成的命令,Solaris通过安装相关的包,并结合自身命令,Linux就通过NFS,samba包来分享。

比如oracle ZFS就这样:

zfs create -o sharenfs=on tank/volume2
exportfs
#默认对所有网络共享
zfs set sharenfs="-maproot=root -alldir -network 192.168.1.254 -mask 255.255.255.0" tank/volume2
exportfs
#停止NFS共享
zfs set sharenfs=off tank/volume2
exportfs

8.1. 创建快照

可以为dataset和volume创建快照,快照是使用 zfs snapshot 命令创建的,该命令将要创建的快照的名称用作其唯一参数,快照名称按如下方式指定:

  • 可以通过使用 -r 选项为所有子文件系统创建快照;
  • 快照没有可修改的属性,也不能将属性应用于快照;
# volume1@22082011 是快照的全名,@之后可为任意字符,一般建议是时间戳
zfs snapshot tank/volume1@now
zfs snapshot tank/dataset1@now

8.2. 列出快照

# 查看快照占用情况
zfs list -t snap -o space
# 列出tank这个pool的全部快照
zfs list -r -t snapshot tank
# 列出tank/dataset这个dataset的全部快照
zfs list -t snapshot -r tank/dataset
# 列出快照,但仅显示指定的输出
zfs list -t snapshot -o name,creation tank/dataset
# 列出快照,但仅显示指定的输出,不输出header,常用于脚本
zfs list -Hpo name,creation -t snapshot -r $dataset

8.3. 销毁快照

如果已从快照创建克隆,则必须先销毁克隆,才能销毁快照。

# 销毁指定快照
zfs destroy tank/data@now
# 销毁全部快照
zfs destroy tank/data@%
# 删除所有dataset的所有快照
zfs list -H -o name -t snapshot | xargs -n1 zfs destroy

8.4. 重命名快照

可以重命名快照,但是必须在从中创建它们的池和数据集中对它们进行重命名。例如:

zfs rename tank/home/cindys@083006 tank/home/cindys@today
# 快捷方式语法
zfs rename tank/home/cindys@083006 today
# -r 递归方式重命名快照
zfs rename -r users/home@yesterday @2daysago

不支持以下快照 rename 操作,因为目标池和文件系统名称与从中创建快照的池和文件系统不同:

zfs rename tank/home/cindys@today pool/home/cindys@saturday
 
cannot rename to 'pool/home/cindys@today': snapshots must be part of same dataset

8.5. 克隆快照

卷的快照无法直接访问,但可以克隆,备份和回滚卷。

克隆是可写入的卷或文件系统,其初始内容与从中创建它的数据集的内容相同。与快照一样,创建克隆几乎是即时的,而且最初不占用其他磁盘空间。此外,还可以创建克隆的快照。

克隆只能从快照创建。克隆快照时,会在克隆和快照之间建立隐式相关性。即使克隆是在数据集分层结构中的某个其他位置创建的,但只要克隆存在,就无法销毁原始快照。origin 属性显示此相关性,而 zfs destroy 命令会列出任何此类相关性(如果存在)。

克隆不继承从其中创建它的数据集的属性。使用 zfs get 和 zfs set 命令,可以查看和更改克隆数据集的属性。

zfs clone tank/volume1@21082011 tank/volume1_restore

8.6. 回滚快照

  • 快照回滚会丢弃指定快照之后的数据!!!
  • 可以使用 zfs rollback 命令放弃自特定快照创建以来对文件系统所做的全部更改;
  • 可以 rollback 到指定快照,如果一次回滚多个快照,需要使用 -r 选项;
  • 如果存在任何中间快照的克隆,则还必须指定-R选项以销毁克隆。
  • 如果要回滚的文件系统当前为挂载状态,则会取消挂载并重新挂载。如果无法取消挂载该文件系统,则回滚将失败。-f 选项可强制取消挂载文件系统;

在以下示例中,会将 tank/home/ahrens 文件系统回滚到 tuesday 快照:

zfs rollback tank/home/ahrens@tuesday
 
cannot rollback to 'tank/home/ahrens@tuesday': more recent snapshots exist
use '-r' to force deletion of the following snapshots:
tank/home/ahrens@wednesday
tank/home/ahrens@thursday
 
zfs rollback -r tank/home/ahrens@tuesday
在本示例中,因为已回滚到以前的 tuesday 快照,所以销毁了 wednesday 和 thursday 快照。
 
zfs list -r -t snapshot -o name,creation tank/home/ahrens
NAME                  CREATION
tank/home/ahrens@now  Wed Jun 30 16:16 2010
  • ZFS send 可以将ZFS的快照通过数据流的方式保存到文件或传输到另一台主机;
  • ZFS receive 可以接收并回写这些数据流到ZFS;(如果接收了完整的流,那么同时会创建一个新文件系统)
# 递归地创建快照(包括子dataset也创建快照)
zfs snapshot -r pool/projects@now
# option1:直接发送到另一个dataset,-R发送所有属性,快照等,-F覆盖现有数据
zfs send -R pool/projects@now | zfs receive -F pool2/projects[@now]
# option2:保存到文件 & 利用文件来恢复
zfs send -R pool/projects@snap2 > ~/projects-snap.zfs
zfs receive -F pool/projects-copy < ~/projects-snap.zfs
# option3:通过ssh传输
zfs send -R tank/home@backup | ssh root@myserver "zfs receive -F backup/home"

即“多副本”功能,作为一项可靠性功能,如果可能,ZFS 文件系统元数据会在不同的磁盘中自动存储多次。此功能称为重复块 (ditto blocks)。

通过 “zfs set copies” 命令存储用户数据的多个副本,这些副本也按文件系统进行存储。例如:

zfs set copies=2 tank/data
zfs get copies tank/data
 
NAME        PROPERTY  VALUE       SOURCE
users/home  copies    2           local

可用的值为 1、2 或 3。缺省值为 1。除了任何池级别的冗余以外,这些副本还用于诸如镜像或 RAID-Z 之类的配置中。

存储 ZFS 用户数据的多个副本的优点如下:

  • 通过支持所有 ZFS 配置从不可恢复的块读取故障(例如介质故障(一般称为位损坏))恢复来提高数据保留能力;
  • 提供数据保护,即使只有一个磁盘可用;
  • 允许您在存储池功能之外以每个文件系统为基础选择数据保护策略;
  • ZFS Deduplication 将丢弃与现有块相同的块,而是使用对现有块的引用。这节省了设备空间,但是将导致占用更多内存!
  • 大概每个block使用~320字节,数据删除表越大,写入性能就越慢!
  • 建议是不要开启;

例如,在 “tank/data” 上启用重复数据删除:

zfs set dedup=on tank/data

Note: Ubuntu 16.04 + 上安装ZFS的话,会自动生成scrub的定时任务。

要手动启动 zpool 的数据完整性检查,请使用 “zfs scrub”命令:

# 开启scrub
zpool scrub tank
# 停止scrub
zpool scrub -s tank
# 检查scrub的状态
zpool status -v tank
  • 用容量更大的硬盘去替换zpool中的硬盘时,zpool不会自动扩展,因为zpool的autoexpand属性默认关闭的,当然可以在扩展前打开,也可以手动扩展zpool;
# 创建zpool时指定
zpool create -f -o ashift=12 -o autoexpand=on -O dedup=off -O atime=off tank raidz /dev/sd{a,b,c}
# 手动指定
zpool set autoexpand=on tank
# 手动扩展zpool,sdb为新的硬盘
zpool online -e tank sdb

zpool 历史查看:

zpool history [tank]

zpool/zfs 版本查看:

sudo zfs upgrade -v
sudo zpool upgrade -v

ZFS/zpool 升级: 2)

zpool upgrade tank
zfs upgrade tank/data

zpool IO 负载查看:

zpool iostat tank [-v] 1


1)
卷属性由zpool继承而来,可通过设置全局zpool属性,也可设置单卷属性,或者二者组合。
2)
升级以使用更多新特性
  • storage/zfs/zfs手册.txt
  • 最后更改: 2019/08/19 17:55
  • 由 mrco