Ubuntu 18.04 LTS - LXD Ubuntu 使用环回 ZFS 启动(约 400MB)
# lxc launch ubuntu:16.04 test -s ianzfspool
(我还有另外一个空闲的多 GB 容器使用相同的 ianzfspool。)我在池中有很多空间:
# zpool list
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
ianzfspool 99.5G 13.7G 85.8G - 2% 13% 1.00x ONLINE -
如果我循环使用lxc
来创建空闲测试容器 (400MB) 的快照,第一个快照会在几秒钟内创建。随着lxc
快照数量的增加(目前超过 1,200 个),现在它们需要几分钟才能创建。我在测试容器中运行一个脚本,每隔几秒钟将当前日期放入 /tmp 中的文件中,因此我有一个文件在每个快照中都在容器中发生变化;否则,容器大部分时间处于空闲状态。第一个lxc
快照使用了大约 25K;当前快照(1,200 个快照后)使用了 66K。(2,470 个快照后,它们每个使用 115K,7,500 个快照后,它们每个使用 293K。)
#!/bin/sh -u
# Create snapshots of the Ubuntu test container.
count=0
while : ; do
count=$(( count + 1 ))
cp=$( printf "%05d" $count )
lxc snapshot test snap$cp
echo "$0: done $cp" >/tmp/icount.txt
done
编辑1:我目前有大约 2,470 个lxc
快照,每个新快照大约需要四分钟来创建,并使用大约 115K。如果我zfs snapshot
直接调用来拍摄容器快照,而不是使用lxc snapshot
,则拍摄快照只需不到一秒钟,即使有 2,470 个现有快照。直接zfs
快照仅使用 20K(而不是 115K)。运行zfs list
只需一两秒钟。如果我运行lxc list
(而不是zfs list
),目前需要四分钟以上,现有快照有 2,470 个。因此,快照创建和列表速度减慢不是由 ZFS 引起的,而是由 LXD 引起的。事实上,lxd
到目前为止,在这个快照创建实验中,该过程本身已经使用了 4,253 CPU 秒,VSIZE 为 3.9G。
我暂停了lxc
快照创建脚本,并编写了一个脚本来循环创建直接zfs
快照,它在五分钟内创建的快照比lxc
三天内创建的还多。我在大约 3,000 个直接 ZFS 快照后暂停了它。
我刚刚重新运行lxc list
,当然它仍然只显示 2,471 个lxc
快照,但现在它只运行了 40 秒,而不是 4 分钟。我刚刚创建了另一个lxc snapshot
,它只花了 49 秒,而不是 4 分钟。发生了什么变化?创建一堆直接zfs
快照是否以某种方式加快了lxc
快照创建和列表?lxc
快照的创建速度仍然比直接zfs
快照慢得多,但快照创建方面有所改进lxc
(从 4 分钟到 49 秒)。
我让 ZFS 快照创建继续进行,直到创建了 10,000 个直接 ZFS 快照。(因此现在我有 2,472 个lxc
快照和 10,000 个zfs
此测试容器的直接快照。)lxc list
现在需要 90 秒(而不是 40 秒)和lxc snapshot
100 秒(而不是 49 秒)。直接使用 ZFS 仍然比通过 LXD 快两个数量级。
编辑2:重启后,LXD 快照创建速度加快了。我通过lxc snapshot
循环创建了 7,470 个快照,每个快照现在大约需要 30 秒才能创建,大小为 293K。需要lxc list
45 秒。zfs list
需要 105 秒并产生 17,507 行输出(其中包括 10,000 个直接 ZFS 快照)。zfs snapshot ianzfspool/containers/test@iansnap10001
直接执行(不通过 LXD)只需不到半秒——仍然比通过 LXD 快得多。
在哪里可以找到有关 LXD 快照创建速度变慢的原因以及如何加快速度的文档?(如果带有 ZFS 快照的 LXD 像我所相信的那样便宜,我希望每 5 分钟运行一次快照并保留大约一周,也就是 2,016 个快照。我读到过 LVM 快照会降低性能,但我读到的关于带有 ZFS 的 LXD 的说法都不一样。我知道我可以绕过 LXD 并使用 ZFS 快照,但为什么我需要这样做?LXD 可以修复吗?)
主机上的进程lxd
正在使用大量 CPU,并且变得越来越大(这是在 1,200 个快照之后):
PID VSTACK VSIZE RSIZE PSIZE VGROW RGROW SWAPSZ MEM CMD 1/8
10663 132K 3.7G 1.1G 0K 0K 0K 2580K 14% lxd
答案1
我没有使用过lxd snapshot
,所以我能做的就是猜测它的实现并告诉你有关 ZFS 快照的更多细节。
ZFS 快照的设计不会给正在进行的读写增加任何开销。(正如您所提到的,LVM 快照确实会以写入放大的形式增加性能损失。)为了实现这一点,ZFS 有一个名为 a 的内部操作,它就txg_sync
像是对所有最近的异步 IO 进行批量写入,并且每 10 秒自动发生一次,以及在文件系统结构发生变化时(例如当您拍摄快照时)。这会导致大量 IO 发生,因此理论上会由于拥塞导致并发同步写入速度减慢(尽管同步写入应该优先)。但是,似乎您几乎没有向文件系统写入任何内容(并且可能没有向池的其余部分写入太多内容)。
我猜想是元数据读取变慢了。理论上,lxd snapshot
可以只拍摄 ZFS 快照并继续,这应该需要一段恒定的时间(假设 IO 负载恒定)。但是,我猜想它还会尝试在该操作期间列出所有快照(相当于zfs list
),这涉及读取每个快照的一大堆元数据,这些元数据通常分布在整个池中,并且会随着快照数量线性增长。要检查是否是这种情况,您可以尝试zfs snapshot
直接在文件系统上计时,然后在文件系统及其快照上执行zfs list -t all
,看看哪一个比另一个花费的时间长得多(应该是第二个)。
在 ZFS 社区中,这是一个众所周知的问题,但很难修复,因为这需要更改大量磁盘上的元数据结构才能改进,而且保留这么多快照的情况很少见。如果lxd
努力避免列出所有快照来运行其快照操作,我认为这可以解决您的问题。
或者,您可以每 5 分钟拍摄一次快照,然后相对较快地删除它们,只保留(例如)5 分钟、10 分钟、15 分钟、30 分钟、1 小时、2 小时、3 小时、6 小时、12 小时、24 小时等的快照。这样可以在您最有可能需要的时间段内为您提供高分辨率,并且不会导致lxd snapshot
速度变慢。