我正在尝试检查我的 ZFS 池的 ARC 是如何使用的,动机是“我是否需要更多的 RAM,即使很贵”。
我有 128GB 快速 ECC,并使用 NVMe SSD 进行 L2ARC,但它仍然会进行大量与 DDT/spacemaps 混合相关的小 IO 读取抖动。该系统针对 DDT 进行了配置,重复数据删除率约为 3.5 倍至 4 倍,因此请不要回复“DDT 很糟糕”,我知道这一点,但需要 DDT,所以我正在努力最小化通过确保至少 ddt/spacemap 元数据在系统预热后几乎全部保留在 ARC 中来减少剩余的读取抖动。
我预计 RAM 的使用方式是 - DDT 大约为 35-40GB,我已使用 sysctls 为元数据保留 85GB 的 ARC。我还将空间图块大小设置为更大的大小,并对池进行了碎片整理(复制到新池),这看起来很有帮助。但由于我看不到加载或驱逐了多少不同类型的元数据(ddt/spacemap/other)的指标,并且没有工具来设置 ZFS ddt 块大小或将 DDT 条目预加载到 ARC,因此我不知道确切的影响,或者更多的 RAM 是否有帮助,或者是否有其他系统方法可以做得更好。
我已经寻找解决方案。zdb
等arc-stats
没有公开元数据 ARC 情况的细分,只是所有元数据的总和。
有没有一种直接的方法来了解正在发生的事情,以便评估更多的 RAM 是否有帮助(即使它并不精确),或者更好地了解(即使不精确)正在加载/缓存/逐出的 ddt/spacemap/“其他”元数据 MRU/MFU 数量的细分?
答案1
我认为没有任何内置工具像 arcstats 一样可以用于此目的,特别是因为你使用的是 FreeBSD,我猜它没有mdb
(来自 illumos/Solaris)。
最简单的解决方案是提供更多内存,然后看看是否有帮助。当然,这需要花钱,但这可能比你花时间找出答案要便宜(如果你为此工作有报酬的话)。
下一个最简单的尝试是在运行一些测试工作负载时调整 ARC 内存限制。这些对工作负载的影响通常不直观,因此我的建议是从所有默认设置开始,然后逐渐更改内容以使其更复杂。例如,当您尝试设置元数据保留的最小内存时,您实际上可能会错误地设置最大值,这会导致您所描述的抖动——因此请务必仔细阅读这些设置的“文档”。
最后,如果您有点勇敢,并且对自己分析复杂数据以确定问题答案的能力相当有信心,那么您也可以使用 DTrace 来实现这一点。每次 ARC 中发生缓存未命中时都会触发此探测:
DTRACE_PROBE4(arc__miss, arc_buf_hdr_t *, hdr, blkptr_t *, bp,
uint64_t, lsize, zbookmark_phys_t *, zb);
因此,您可以编写一个 D 脚本来监听:::arc_miss
探测,并使用args[0]
、args[1]
和/或回溯来找出哪些类型的请求缺少缓存。
blockptr_t
我认为最简单的方法是查看in的类型args[1]
。不幸的是,提取它有点麻烦,因为它是位字段的一部分。可以找到块指针对象的定义这里,并且您希望 DTrace 脚本输出与输出相同的内容BP_GET_TYPE(args[1])
,然后通过与dmu_object_type
来自的值进行比较来解释这些值这里。
另外,我可以推荐一个更简单但解释起来可能更复杂的脚本。它会在每次探测器触发时收集回溯,然后你可以对跟踪进行后处理,以制作一个火焰图以便于解释。ZFS 中的方法名称通常非常具有描述性(至少它们都有首字母缩写词,例如ddt
您可以在线搜索“dedup table”),因此您可能可以通过这种方式弄清楚调用者正在做什么。
如果出现大量不是文件或目录数据的值,您可能需要在缓存中保留更多元数据。您可以通过使用可调参数为其分配更多空间或为机器提供更多 RAM 来实现这一点。