Ubuntu上使用ZFS(Zettabyte File System)

限于喜欢 提交于 2020-02-28 22:57:13

ZFS-基于Ubuntu使用Zettabyte File System

ZFS 的支持从 Ubuntu Wily 15.10 开始作为技术预览加入,到 Ubuntu Xenial 16.04 实现完整支持。注意 ZFS 只支持 64位架构。另外,ZFS 仅支持 data storage, 不支持 root filesystem(在18.04经过配置后可以支持)。

运行ZFS要求空余内存多于 2GB,建议 ZFS 系统不少于 8GB 内存。

安装 ZFS, 使用:

sudo apt install zfsutils-linux

下面快速预览 ZFS, 更多的关于 ZFS的信息请参考 excellent documentation ,由 Aaron Toponce 编写。

注意

为了节约篇幅,本文档中 devices 指 /dev/sda /dev/sdb 等等。 使用device路径 /dev/disk/by-uuid 可以唯一地代表一个设备从而避免在设备名称映射改变时启动失败。

ZFS 虚拟设备 (ZFS VDEVs)

一个 VDEV 是一个meta-device,代表着一个或多个设备。ZFS 支持 7 中不同类型的 VDEV:

  • File - 预先分类的文件,为*.img的文件,可以作为一个虚拟设备载入ZFS。
  • 物理磁盘驱动器 (HDD, SDD, PCIe NVME, etc)。
  • Mirror - 标准的 RAID1 mirror。
  • ZFS 软件RAID,如 raidz1, raidz2, raidz3 'distributed' parity。
  • Hot Spare - hot spare(热备)用于 ZFS 的软件 raid。
  • Cache - a device for level 2 adaptive read cache (ZFS L2ARC)
  • Log - ZFS Intent Log (ZFS ZIL)。

VDEVS 动态地由 ZFS. 进行分带。一个 device 可以被加到 VDEV, 但是不能移除。

ZFS Pools

zpool 是存储池,从一系列VDEVS中创建出来。更多的 ZFS 文件系统可以从 ZFS pool 中创建出来。

下面的例子中,名为 "pool-test"的存储池从3个物理磁盘驱动器中创建出来:

$ sudo zpool create pool-test /dev/sdb /dev/sdc /dev/sdd

Striping 被动态地执行,创建了一个零冗余的RAID-0存储池。

注意:如果管理很多存储驱动器,很容易引起混淆,可以使用 /dev/disk/by-id/ 名称机制,提供基于序列号的驱动器标识。上面的方法主要是为了方便演示。

查看存储池的状态:

$ sudo zpool status pool-test

删除存储池:

$ sudo zpool destroy pool-test

创建 2 x 2 镜像的 zpool 例子

下面创建 zpool,包含的 VDEV 有两个 drives组成为一个镜像。

$ sudo zpool create mypool mirror /dev/sdc /dev/sdd

我们再加两个驱动器组成的镜像到存储池中:

$ sudo zpool add mypool mirror /dev/sde /dev/sdf -f

$ sudo zpool status
  pool: mypool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            sde     ONLINE       0     0     0
            sdf     ONLINE       0     0     0

该例子中:

  • /dev/sdc, /dev/sdd, /dev/sde, /dev/sdf 是物理存储设备。
  • mirror-0, mirror-1 是虚拟的设备 VDEVs。
  • mypool 是 pool 存储池。

有很多种布局 VDEVs 的方法来创建一个存储池(zpool)。

基于单个文件的 zpool

在下面的例子中,我们使用单个 2GB 文件作为 VDEV,然后从该虚拟存储设备创建 zpool :

$ dd if=/dev/zero of=example.img bs=1M count=2048
$ sudo zpool create pool-test /home/user/example.img
$ sudo zpool status
  pool: pool-test
 state: ONLINE
  scan: none requested
config:

        NAME                      STATE     READ WRITE CKSUM
        pool-test                 ONLINE       0     0     0
          /home/user/example.img  ONLINE       0     0     0

该例子中:

  • /home/user/example.img 是基于文件的VDEV。
  • pool-test 是存储池。

RAID-磁盘阵列功能

ZFS 提供几个 RAID 选项:

条带,Striped VDEVS

等价于 RAID0。没有校验和镜像用于数据重建恢复。该方法不建议使用,当驱动器失效时会造成数据丢失。下面创建一个条带化的存储池,使用了 4 个 VDEVs:

$ sudo zpool create example /dev/sdb /dev/sdc /dev/sdd /dev/sde

镜像,Mirrored VDEVs

类似于 RAID1,使用 2 个以上的VDEVs。对于 N VDEVs,当小于 N-1 个磁盘失效时数据可以恢复。下面的例子使用 2 个VDEVs创建存储池。

  • $ sudo zpool create example mirror /dev/sdb /dev/sdc

条带+镜像,Striped Mirrored VDEVs

类似于 RAID10,对于小的随机读 I/O 比较好。创建镜像对,然后基于镜像进行条带化。 下面创建 2 x 2 条带化的镜像池:

sudo zpool create example mirror /dev/sdb /dev/sdc mirror /dev/sdd /dev/sde

或者:

sudo zpool create example mirror /dev/sdb /dev/sdc
sudo zpool add example mirror /dev/sdd /dev/sde

软件磁盘阵列,RAIDZ

类似于 RAID5, 使用可变宽度的条带用于奇偶校验。允许在奇偶校验的情况下得到较大的容量,而又不牺牲太多的性能。允许单个盘失败的情况下不丢失信息。创建 4 个VDEV的RAIDZ:

$ sudo zpool create example raidz /dev/sdb /dev/sdc /dev/sdd /dev/sde

软件磁盘阵列,RAIDZ2

类似于 RAID6,与RAIDZ类似但具有双重奇偶校验。例如,创建 2 parity 5 VDEV 的 pool:

$ sudo zpool create example raidz2 /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf

软件磁盘阵列,RAIDZ3

3 parity bits,允许三块盘失败而不丢失数据,性能与 RAIDZ2 和 RAIDZ差不多。例如,创建 3 parity 6 VDEV 的pool:

$ sudo zpool create example raidz3 /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg

软件磁盘阵列,Nested RAIDZ

类似 RAID50, RAID60, striped RAIDZ volumes。比 RAIDZ更好的执行性能,但是会减少容量,从而增加了使用成本。例如 2 x RAIDZ:

$ sudo zpool create example raidz /dev/sdb /dev/sdc /dev/sdd /dev/sde
$ sudo zpool add example raidz /dev/sdf /dev/sdg /dev/sdh /dev/sdi

日志加速,ZFS Intent Logs

ZIL (ZFS Intent Log) 驱动器可以被添加到 ZFS pool 来加速写入的能力,适用于任何级别的ZFS RAID。最好使用快速的 SSD来存储ZIL。从概念上说,ZIL 是一种对于 data 和 metadata 的日志机制,先写入然后再刷新为写事务。实际上, ZIL 更为复杂,参考 described in detail here。一个或多个驱动器可以被用于 ZIL。

例如,加入SSDs 到存储池 'mypool', 使用:

$ sudo zpool add mypool log /dev/sdg -f

缓存加速,ZFS Cache Drives

Cache devices 提供在 memory 和 disk的缓冲层。用于改善静态数据的随机读写性能。

例如,添加缓冲磁盘 /dev/sdh 到存储池 'mypool', 使用:

$ sudo zpool add mypool cache /dev/sdh -f

ZFS 文件系统

ZFS 允许每个存储池最多创建 2^64 文件系统。我们在存储池  'mypool'创建文件系统,如下:

sudo zfs create mypool/tmp
sudo zfs create mypool/projects

删除文件系统,使用:

sudo zfs destroy mypool/tmp

每一个 ZFS 文件系统都可以有属性设置,例如设置最多 10 gigabytes的使用限额:

sudo zfs set quota=10G mypool/projects

添加压缩支持:

sudo zfs set compression=on mypool/projects

ZFS snapshot,快照

ZFS snapshot(快照)是 ZFS 文件系统或卷的只读拷贝。可以用于保存 ZFS 文件系统的特定时点的状态,在以后可以用于恢复该快照,并回滚到备份时的状态。

下面的例子中,我们创建 mypool/projects 文件系统的快照:

$ sudo zfs snapshot -r mypool/projects@snap1

可以查看所有的snapshots列表,使用:

$ sudo zfs list -t snapshot
NAME                     USED  AVAIL  REFER  MOUNTPOINT
mypool/projects@snap1   8.80G      -  8.80G  -

现在, 'accidentally' 破坏文件然后回滚:

$ rm -rf /mypool/projects
$ sudo zfs rollback mypool/projects@snap1

移除snapshot,使用:

$ sudo zfs destroy mypool/projects@snap1

ZFS Clones,克隆

一个ZFS clon是文件系统的可写的拷贝。一个 ZFS clone 只能从 ZFS snapshot中创建,该 snapshot 不能被销毁,直到该 clones 也被销毁为止。

例如,克隆 mypool/projects,首先创建一个 snapshot 然后 clone:

$ sudo zfs snapshot -r mypool/projects@snap1
$ sudo zfs clone mypool/projects@snap1 mypool/projects-clone

ZFS Send 和 Receive

ZFS send 发送文件系统的快照,然后流式传送到文件或其他机器。ZFS receive 接收该 stream 然后写到 snapshot 拷贝,作为 ZFS 文件系统。 这对于备份和通过网络发送拷贝 (e.g. using ssh) 来拷贝文件系统。

例如,创建 snapshot 然后 save 到文件:

sudo zfs snapshot -r mypool/projects@snap2
sudo zfs send mypool/projects@snap2 > ~/projects-snap.zfs

..然后接收回来:

sudo zfs receive -F mypool/projects-copy < ~/projects-snap.zfs

ZFS Ditto Blocks,重复块

Ditto blocks 创建更多的冗余拷贝。对于只有一个设备的 storage pool ,ditto blocks are spread across the device, trying to place the blocks at least 1/8 of the disk apart。对于多设备的 pool,ZFS 试图分布 ditto blocks 到多个 独立的 VDEVs. 1 到 3 份拷贝可以被设置。设置三份拷贝到 mypool/projects:

$ sudo zfs set copies=3 mypool/projects

ZFS Deduplication,文件去重

ZFS dedup 将丢弃重复数据块,并以到现有数据块的引用来替代。这将节约磁盘空间,大需要大量的内存。内存中的去重记录表需要消耗大约 ~320 bytes/block。表格尺寸越大,写入时就会越慢。

启用去重功能在 mypool/projects, 使用:

$ sudo zfs set dedup=on mypool/projects

为了更多的去重 pros/cons ,参考 http://constantin.glez.de/blog/2011/07/zfs-dedupe-or-not-dedupe

ZFS Pool Scrubbing,检修

初始化数据完整性检测,通过 zfs scrub 命令执行。如:

$ sudo zpool scrub mypool

通过zpool status 使用 scrub,例如:

$ sudo zpool status -v mypool

数据恢复,简单的例子

假设有一个 2 x 2 镜像的zpool:

$ sudo zpool create mypool mirror /dev/sdc /dev/sdd mirror /dev/sde /dev/sdf -f
$ sudo zpool status
  pool: mypool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            sde     ONLINE       0     0     0
            sdf     ONLINE       0     0     0

填充数据,然后检查:

$ dd if=/dev/urandom of=/mypool/random.dat bs=1M count=4096
$ md5sum /mypool/random.dat
f0ca5a6e2718b8c98c2e0fdabd83d943  /mypool/random.dat

模拟 catastrophic data loss,覆盖 VDEV devices:

$ sudo dd if=/dev/zero of=/dev/sde bs=1M count=8192

初始化 scrub:

$ sudo zpool scrub mypool

然后检测状态:

$ sudo zpool status
  pool: mypool
 state: ONLINE
status: One or more devices has experienced an unrecoverable error.  An
        attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
        using 'zpool clear' or replace the device with 'zpool replace'.
   see: http://zfsonlinux.org/msg/ZFS-8000-9P
  scan: scrub in progress since Tue May 12 17:34:53 2015
    244M scanned out of 1.91G at 61.0M/s, 0h0m to go
    115M repaired, 12.46% done
config:

        NAME        STATE     READ WRITE CKSUM
        mypool      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            sde     ONLINE       0     0   948  (repairing)
            sdf     ONLINE       0     0     0

...从 pool移除驱动器:

$ sudo zpool detach mypool /dev/sde

..热切换,然后添加一个新的:

$ sudo zpool attach mypool /dev/sdf /dev/sde  -f

..然后初始化scrub,修复 2 x 2 mirror:

$ sudo zpool scrub mypool

ZFS 压缩

如之前提到,ZFS支持数据的压缩。通过现代的 CPUs,压缩减少了数据尺寸,从而读写的数据量减少而获得更好的 I/O。ZFS提供了一系列的压缩方法。缺省的是 lz4 (a high performance replacement of lzjb) ,提供了较快的压缩和解压缩效率和较高的压缩比。可以设置压缩的级别。

sudo zfs set compression=gzip-9 mypool

以及设置压缩的类型:

sudo zfs set compression=lz4 mypool

检查压缩比:

sudo zfs get compressratio

lz4 比其它的要快,lz4 是最安全的选项。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!