我有一个 Ubuntu 16.04 工作站,带有 ext4 文件系统。
- 在玩 LxD 时,我希望有一个快如闪电快照功能(因为我的图像通常很大)。据我所知,只有当备份文件系统是 CoW 文件系统(例如 Btrfs)时,才能实现此功能。
(注意:到目前为止,我遇到的与 Btrfs 性能相关的唯一主要警告是建议使用noatime
mount 标志。)
- 但是由于我在这个系统上还有一个 MySQL 实例,我不希望它的性能受到影响(相对于 ext4 文件系统),所以我决定做最后一次检查,看看是否在切换到支持 Btrfs 的 MySQL 时可能出现问题。并且,看我发现了什么:
通常最好使用
'nodatacow'
选项来挂载 Btrfs,禁用写时复制,因为当您有大量随机写入时,COW 会导致碎片化、磁盘抖动以及 CPU 和 RAM 峰值。
现在,这似乎是一个真正的阻碍!
问题:有没有什么办法可以让我同时通过 Btrfs 获得快速快照和高性能 MySQL 实例?
答案1
对于采用写时复制设计的文件系统来说,碎片化是一个不可避免的副作用。这也是首先允许几乎免费的文件系统快照的原因。
原因很简单:每次更改块时,新块都必须写入原始块以外的某个位置。因此,即使文件最初是连续的,修改后也不会是连续的。
我不知道 Btrfs 如何nodatacow
与快照交互,但我有一种感觉,当你在数据集上创建快照时,无论你使用什么标志,你都会强制至少部分写时复制行为;否则你如何能够通过快照访问旧数据?
然而,这不一定严重影响你的 MySQL 性能,原因有二:
- 现代磁盘对于单用户工作负载来说确实非常快(我认为你最感兴趣的是这一点,因为你提到你的系统是一个“工作站”)
- 现代操作系统有相当好的缓存算法,从而减少了实际访问物理存储的需要
举个例子,我自己也在运行 ZFS(Btrfs 借鉴了许多想法),目前正在进行清理。所讨论的池是一个六磁盘 raidz2,它并不以出色的性能而闻名,物理上由六个 7200 rpm 磁盘(两个 SATA,四个 SAS)支持,这些磁盘也不以出色的 IOPS 而闻名。ZFS 清理会浏览整个磁盘上的 Merkle 树,读取所有数据,并验证所有内容的校验和,以确保所有内容都按之前写入的方式读回;在我的情况下,沿途计算所有内容的 SHA-256 哈希值。当前的清理速度(在经过最初的、元数据繁重的部分之后,这涉及大量寻道)徘徊大约 200 MB/s并且实际上缓慢地爬升。这是实际的拼盘I/O,不涉及缓存(因为当您想要验证持久存储上的内容时,缓存没有任何意义)。
当然,如果您转向写时复制文件系统,您很可能会发现碎片化会导致性能下降。但鱼与熊掌不可兼得;如果您想要快速、低成本的快照,您很可能不得不放弃其他东西才能获得它们。
针对你的情况,我会进行基准测试。设置一些 Btrfs 存储,将 MySQL 数据库的副本放在那里,然后看看两者在合理的工作负载下的表现。
答案2
我尝试了自己的评论,一切似乎都运行良好。仍然欢迎更好的替代方案。
这是我所做的。
# 1. Initial, onetime setup.
# 1.a) Create a sparse, 20G file.
$ truncate -s 20G disk.20g
# 1.b) Format the loopback device with Btrfs.
$ losetup /dev/loop0 disk.20g
$ mkfs.btrfs /dev/loop0
# 2. Do this every time you wish to actually start using LxD.
# Note: Replace '/dev/loop0' with whatever loop-device is free on your system.
$ sudo service lxd stop
$ sudo mkdir -p /var/lib/lxd
$ sudo mount -o noatime /dev/loop0 /var/lib/lxd
$ sudo service lxd start
# 3. Do this to gracefully 'shutdown' the effects of Step 2.
$ sudo service lxd stop
$ sudo umount /var/lib/lxd
$ losetup -d /dev/loop0
$ sudo service lxd start
因此,重申一下:
- 我的主机操作系统的主文件系统是 Ext4。上述
disk.20g
文件仅驻留在此文件系统上。此文件系统可以继续托管 MySQL 和其他可能因 Btrfs 而性能受到不利影响的软件。 - LxD 将其镜像和容器存储在 Btrfs 分区中。这样可以实现极快的快照。