为什么“zfs list -t snapshot”比“ls .zfs/snapshot”慢几个数量级?

为什么“zfs list -t snapshot”比“ls .zfs/snapshot”慢几个数量级?

对于我曾经尝试过的所有 ZFS-on-Linux 版本,使用zfs list列出文件系统或卷的所有快照(zfs list -r -t snapshot -H -o name pool/filesystem)总是比 花费更多数量级的时间来运行ls .zfs/snapshot,而 是即时的:

$ time ls -1 /srv/vz/subvol-300-disk-1/.zfs/snapshot
[list of 1797 snapshots here]
real    0m0.023s
user    0m0.008s
sys     0m0.014s

# time zfs list -r -t snapshot -H -o name vz/subvol-300-disk-1
[same list of 1797 snapshots]
real    1m23.092s
user    0m0.110s
sys     0m0.758s

这个错误是 ZFS-on-Linux 独有的吗?

任何拥有 Solaris 或 FreeBSD ZFS 盒的人都可以执行类似的测试(在旋转硬盘上具有数百个快照的文件系统上)吗?

有没有一种解决方法可以快速获取快照列表体积,其本质上没有.zfs目录?

我已经在内核 2.6.32-43-pve x86_64(Proxmox)上使用 ZFS-on-Linux 0.6.5.2-2-wheezy 运行了上述测试,但我总是看到这个问题,无论是在旧版本还是新版本的 ZFS 和内核上。


以下是游泳池统计数据:

# zpool list
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
vz    25.2T  9.42T  15.8T         -     5%    37%  1.00x  ONLINE  -

它包含 114 个文件系统和 1 个卷,每个都有数百个快照,因为这是一个zfs send/zfs recv备份服务器。


解决方案: zfs list很慢,因为它会获取其他信息,即使这些信息没有显示出来。解决方案是同时添加-o name -s name,即使用zfs list -t snapshot -o name -s name

答案1

快照操作取决于您拥有的快照数量、RAM、磁盘性能和驱动器空间。这是一个常见的 ZFS 问题,并不是 Linux 版本所独有的东西。

更好的问题是:为什么 zvol 有 1797 个快照?这绝对是超出推荐的范围,并且让我想知道系统上还发生了什么。

人们说“ZFS 快照是免费的”,但这并不总是正确的。

虽然 ZFS snap 不会影响生产性能,您拥有的高数字显然需要磁盘访问来枚举。

Disk access time > RAM access time,因此数量级存在差异。


strace输出。注意每个系统调用的时间,并想象一下它与文件系统中快照数量的扩展有多差。

# strace -c ls /ppro/.zfs/snapshot

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0        10           read
  0.00    0.000000           0        17           write
  0.00    0.000000           0        12           open
  0.00    0.000000           0        14           close
  0.00    0.000000           0         1           stat
  0.00    0.000000           0        12           fstat
  0.00    0.000000           0        28           mmap
  0.00    0.000000           0        16           mprotect
  0.00    0.000000           0         3           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           fcntl
  0.00    0.000000           0         2           getdents
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0         1           statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         2         1 futex
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                   133         2 total

相对

# strace -c zfs list -t snapshot

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.003637          60        61         7 ioctl
  0.00    0.000000           0        12           read
  0.00    0.000000           0        50           write
  0.00    0.000000           0        19           open
  0.00    0.000000           0        19           close
  0.00    0.000000           0        15           fstat
  0.00    0.000000           0        37           mmap
  0.00    0.000000           0        19           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         4           brk
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         3         1 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         2         1 futex
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    0.003637                   250         9 total

答案2

zfs list -t snapshot总是比ls .zfs/snapshot

您还在比较两个完全不同的操作。

zfs list -t snapshot枚举系统上的所有 ZFS 快照 -提供了有关这些快照的大量信息,例如已使用的空间量。运行该命令strace可查看执行的系统调用。

ls .zfs/snapshot只是从目录中发出一个简单的名称列表。除了读取名称外,没有其他操作 - 并且不提供任何其他内容。

相关内容