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

Tob*_*bia 7 zfs zfsonlinux

对于我尝试过的所有 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
Run Code Online (Sandbox Code Playgroud)

此错误是否特定于 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  -
Run Code Online (Sandbox Code Playgroud)

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


解决方案: zfs list很慢,因为它会获取附加信息,即使它没有显示。解决方案是添加两者-o name -s name,即使用zfs list -t snapshot -o name -s name

eww*_*ite 2

快照操作取决于您拥有的快照数量、RAM、磁盘性能和驱动器空间。这是一个普遍的 ZFS 问题,而不是 Linux 变体所特有的问题。

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

人们说“ZFS 快照是免费的”,但事实并非总是如此。

虽然 ZFS 快照不会对生产性能产生影响,但您拥有的大量快照显然需要磁盘访问来枚举。

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
Run Code Online (Sandbox Code Playgroud)

相对

# 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
Run Code Online (Sandbox Code Playgroud)

  • 它不会将其称为“简单目录列表”,因为它是一个调用特定内核代码的虚拟目录,很像“/proc”。您有任何关于将快照保持在 1000 以下的官方消息吗?这是一个备份服务器,因此大量的文件系统和快照是该服务器的全部目的。 (4认同)
  • 我也不同意“[1797 个快照]绝对超过推荐”,[ZFS 开发人员甚至说数千不是问题](http://web.archive.org/web/20120211211239/http://mail.opensolaris .org/pipermail/zfs-discuss/2009-March/027191.html)。OP 在这里看到的只是 O(N) 时间来枚举 1797 个项目的数据。(我在生产机器上有超过 40k 的快照,性能很好) (3认同)
  • 该页面包含以下可行的解决方法“zfs list -t snapshot -o name -s name”。我缺少“-s name”。谢谢 (2认同)