我知道 ZFS 的性能在很大程度上取决于可用空间量:
将池空间的利用率保持在 80% 以下以维持池性能。当前,当池非常满且文件系统更新频繁时(例如在繁忙的邮件服务器上),池性能可能会下降。满池可能会导致性能下降,但没有其他问题。[...] 请记住,即使大部分静态内容在 95-96% 范围内,写入、读取和重新同步性能也可能会受到影响。ZFS_Best_Practices_Guide,solarisinternals.com (archive.org)
现在,假设我有一个托管 ZFS 文件系统的 10T raidz2 池volume
。现在我创建了一个子文件系统volume/test
并为其预留了 5T。
然后我将每个 NFS 的两个文件系统挂载到某个主机并执行一些工作。我明白我不能写入volume
超过 5T,因为剩下的 5T 是保留给volume/test
.
我的第一个问题是,如果我volume
用 ~5T 填充挂载点,性能会如何下降?它会因为 ZFS 的写时复制和其他元数据的文件系统中没有可用空间而下降吗?或者它会保持不变,因为 ZFS 可以使用为保留的空间内的可用空间volume/test
吗?
现在第二个问题。如果我按如下方式更改设置,会有什么不同吗?volume
现在有两个文件系统,volume/test1
和volume/test2
. 两者都获得了 3T 预留(但没有配额)。现在假设,我将 7T 写入test1
. 两个文件系统的性能是否相同,还是每个文件系统都不同?它会下降还是保持不变?
谢谢!
当您的zpool非常满或非常零散时,就会出现性能下降。原因是 ZFS 使用的空闲块发现机制。与 NTFS 或 ext3 等其他文件系统相反,没有块位图显示哪些块被占用,哪些块空闲。相反,ZFS 将您的 zvol 划分为(通常为 200 个)称为“metaslabs”的更大区域,并在每个 metaslab 中存储空闲块信息(空间映射)的 AVL 树1。平衡的 AVL 树允许有效地搜索适合请求大小的块。
虽然出于规模原因而选择了这种机制,但不幸的是,当出现高度碎片化和/或空间利用率时,它也被证明是一个主要的痛苦。一旦所有元实验室都携带大量数据,您就会获得大量小块空闲块区域,而不是池为空时的少量大块区域。如果 ZFS 然后需要分配 2 MB 的空间,它会开始读取和评估所有 metaslabs 的空间映射,以找到合适的块或将 2 MB 分解成更小块的方法。这当然需要一些时间。更糟糕的是,它会花费大量的 I/O 操作,因为 ZFS 确实会读取物理磁盘上的所有空间映射。对于您的任何写作。
性能下降可能很严重。如果您喜欢漂亮的图片,请查看Delphix 上的博客文章,其中有一些数字来自(过于简单但有效的)zfs 池。我无耻地窃取了其中一张图表 - 看看这张图表中的蓝色、红色、黄色和绿色线条,它们(分别)代表池在 10%、50%、75% 和 93% 的容量下绘制的写入吞吐量KB/s,同时随着时间的推移变得碎片化:
传统上,对此的快速而肮脏的修复是metaslab 调试模式(仅
echo metaslab_debug/W1 | mdb -kw
在运行时发出以立即更改设置)。在这种情况下,所有空间映射都将保存在操作系统 RAM 中,从而消除了每次写入操作时对过多且昂贵的 I/O 的要求。最终,这也意味着您需要更多内存,尤其是对于大型池,因此它是一种用于存储马交易的 RAM。您的 10 TB 池可能会花费您 2-4 GB 的内存2,但是您可以毫不费力地将其提高到 95% 的利用率。1有点复杂,有兴趣的可以看Bonwick关于空间地图的帖子了解详情
2如果您需要一种计算内存上限的方法,请使用
zdb -mm <pool>
检索segments
每个 metaslab 中当前使用的数量,将其除以 2 以模拟最坏情况(每个占用的段后面都有一个空闲段),将它乘以 AVL 节点的记录大小(两个内存指针和一个值,考虑到 zfs 的 128 位性质和 64 位寻址将总计为 32 字节,尽管人们似乎通常假设某些情况下为 64 字节原因)。参考:基本大纲包含在Markus Kovero 在 zfs-discuss 邮件列表上的这篇帖子中,尽管我相信他在计算中犯了一些错误,我希望在我的计算中更正这些错误。
是的。您需要在池中保留可用空间。它主要用于写时复制操作和快照。性能下降到大约 85% 的利用率。你可以走得更高,但有一定的影响。
不要搞砸预订。特别是对于 NFS。这不是必需的。也许对于 zvol,但不是 NFS。
不过,我没有看到混乱。如果你有 10T,不要使用超过 85%。适当调整您的份额,使用配额来限制它们的使用。或者不使用任何配额并监控您的整体池使用情况。