坑边闲话:本文最早发布于哔哩哔哩专栏。ZFS 凭借 ARC 缓存设计,使得它在内存足够大、足够安全的情况下性能极高。注意,并不是所有的基于内存的缓存系统都有极高的性能和良好的存储层次化兼容性。然而,在 NVMe 时代,底层设备完成了革新,NVMe 允许 64K 个队列和 64K 的队列深度,这在 SAS/SATA 时代是天文数字。ZFS 亟需革新存储底层,以适应 NVMe 设备。Direct-IO 就是迈向新时代的第一步。

最近发现 OpenZFS 合并了一项重要的内核支持 PR:Direct-IO.

说人话就是绕过 ARC 内存级缓存,直接读写存储池。

直接的好处就是对全闪存的支持变得更好了!毕竟 NVMe 硬盘自身就相当于很多的 CE 做 RAID0,而且自身支持强大的随机与多队列,因此给 NVMe 设备做缓存其实并不明智。事实上,给 NVMe 开缓存,在性能上往往适得其反。PureStorage 的 NVRAM 模块一般都只有几个 GB,足以说明问题。

此前我认为这在 OpenZFS on Linux 上支持 Direct-IO 是不可能的,因为这违背了 ZFS 层次化设计的的原则。详细阅读提交记录后我才发现,事实没有我想的那么简单。首先如果要绕开 ARC,使用 Direct-IO 的读写,必须要做到本次写入是 recordsize 对齐的,而且写入的时候不能对 page 进行修改,当然,这不难做到。此外,由于 dedup 去重和 direct-io 先天八字不合,所以系统强制要求 dedup 和 direct-io 二选一或者都不选。

如何实现缓存一致性呢?很简单,如果用户真的满足要求并做了直接磁盘写入,相应的缓存在 ARC 里的数据就直接被丢掉,强制随后的读操作从磁盘获取数据。

题外话·

此间发现了一个澳大利亚的公司 Klara Systems,做了很多与 ZFS 相关的博客,适合初学者和进阶学习者。推荐给各位。

PS. Klara 的工程师在 Slog 设备的理解上,与我此前视频里的内容是一致的。开心😄

图 1. Jim Salter 的文章截图。