使用数千个数据集创建缓慢的 zfs

Slow zfs create with thousands of datasets

我正在创建一个 zfs 系统,其中我系统中某个实体的每个实例在 zfs 中都有自己的数据集。这是必需的,因为每个实体都由许多小文件组成,这些文件复制或删除的速度非常慢。因此,我决定尝试依靠 zfs 数据集来销毁或 snapshot/copy 整个实体,而不考虑其内容。

但现在在我的基准测试中,大约有 5000 多个数据集并且还在增加,使用 'zfs create' 创建一个新数据集有时需要长达 9 分钟。虽然 9 分钟真的很慢但仍然可以接受,但我担心如果我增加数据集的数量只会变得更糟。 5000在我看来还不算多。

系统信息:

有没有人有使用 zfs 处理大量数据集的经验,可以告诉我更多关于这种情况下的性能?或者我是否以非预期的方式使用 zfs?

ZFS 内部工作的方式是使用一个称为 txg(事务组)的概念。这个概念帮助 ZFS 了解发生的顺序操作,因此在任何给定时间只有一个整数 txg 可用(设计上没有并行性)。在正常情况下,每隔几秒创建一个新的 txg,以便在系统崩溃时创建一个合理的最新恢复点。发生这种情况时,需要完成一些工作,主要是将所有未完成的写入刷新到磁盘。但是,每当您通过创建新数据集、拍摄快照等方式改变 ZFS 元数据时,都必须创建新的 txg ,这意味着这些操作有点繁重超出您的预期。

在你的情况下,我对发生的事情的猜测是你的应用程序正在执行大量这些文件系统操作(创建、删除、快照等),并且处理你的请求的队列越来越长因为系统跟不上。

存在三种可能的解决方案:

  1. 对系统进行分析以找出瓶颈所在,并在可能的情况下投入更多硬件解决问题(我猜这不太可能奏效)
  2. 通过将目录组合成较少的文件系统或其他方式来减少文件系统操作
  3. 使用 ZFS channel program 将多个文件系统操作合并为单个 txg,这基本上是一个 Lua 脚本,可以在 txg 中间调用创建可以 运行 任意 ZFS 文件系统操作

我最后想留给您的是:在 ZFS 中删除文件系统看起来立竿见影,但在内部,文件系统会立即隐藏,但其数据由后台线程异步释放,这可能需要一段时间。您可以通过 运行 命令 zpool get -o freeing <pool> 查看等待释放的 space 数量。因此,使用 ZFS 更快地删除内容的整个设计实际上可能不会为您做那么多。如果您想在没有 txg 开销的情况下获得此行为,您可以在应用程序中创建一个队列,其中包含一个后台线程,该线程将删除不再使用的目录。