从ZFS中有效地删除10M +文件

我写了一个错误的程序,在/ tmp下意外创build了大约30M的文件。 (这个bug是在几个星期前引入的,它每秒创build一些子目录。)我可以将/ tmp重命名为/ tmp2,现在我需要删除这些文件。 系统是FreeBSD 10,根文件系统是zfs。

与此同时,镜子中的一个驱动器出错了,我已经取代了它。 该驱动器有两个120GB SSD磁盘。

这里是一个问题:更换硬盘和重新arrays整个arrays不到一个小时。 删除文件/ tmp2是另一回事。 我写了另一个程序来删除文件,它只能删除每秒30-70个子目录。 删除所有文件需要2-4天的时间。

如何重新整理arrays需要一个小时,但从磁盘删除需要4天? 为什么我的performance如此糟糕? 70次/秒的performance看起来非常糟糕。

我可以手动删除/ tmp2的inode,但不会释放空间,对不对?

这可能是一个ZFS的问题,或硬盘或什么?

在ZFS中删除是昂贵的。 如果您在文件系统上启用了重复数据删除,则更是如此(因为解除引用的重复数据文件非常昂贵)。 快照也可能使问题复杂化。

删除/tmp目录而不是其中包含的数据可能会更好。

如果/tmp是ZFS文件系统,请删除它并重新创build。

如何重新整理arrays需要一个小时,但从磁盘删除需要4天?

考虑一个办公大楼。

从所有楼层的所有办公室拆除所有电脑和家具以及固定装置需要长时间,但可以让办公室立即使用另一个客户。

使用RDX拆除整个build筑物的速度要快得多,但下一个客户可能会抱怨这个地方有多大。

这里有很多事情要做。

首先,所有现代磁盘技术都针对批量传输进行了优化。 如果你需要移动100MB的数据,如果他们在一个连续的块中,而不是分散在各处,他们会更快地做到这一点。 固态硬盘在这方面有很多帮助,但即使他们更喜欢连续块的数据。

其次,就磁盘操作而言,重新同步是非常理想的。 您从一个磁盘上读取大量连续的数据块,对其执行一些快速的CPU操作,然后将其重新写入另一个大的连续块到另一个磁盘。 如果电源中途中断,没有什么大不了的 – 你会忽略任何校验和不好的数据,并按正常进行。

第三,删除文件真的很慢 。 ZFS特别糟糕,但实际上所有文件系统的删除速度都很慢。 他们必须修改磁盘上的大量不同的数据块并正确计时(即等待),以便在断电时文件系统不会被损坏。

如何重新整理arrays需要一个小时,但从磁盘删除需要4天?

Resilvering是磁盘真正快速的地方,删除是磁盘缓慢的地方。 每兆字节的磁盘,你只需要做一点点的重新同步。 您可能在该空间有一千个文件需要删除。

70次/秒的performance看起来非常糟糕

这取决于。 我不会为此感到惊讶。 你还没有提到你使用的是什么types的SSD。 现代英特尔和三星SSD在这种操作(读取 – 修改 – 写入)方面非常出色,性能会更好。 更便宜的/旧的固态硬盘(例如海盗船)将会很慢。 每秒I / O操作数(IOPS)是决定性的因素。

ZFS删除的东西特别慢。 通常情况下,它会在后台执行删除,所以你看不到延迟。 如果你做的人数很多,就不能隐藏它,必须拖延你。


附录:为什么删除速度慢?

  • 删除文件需要几个步骤。 文件元数据必须标记为“已删除”,最终必须回收,以便空间可以重复使用。 ZFS是一个“日志结构化文件系统”,如果你只是创build了一些东西,那么它的性能performance最好,不会删除它们。 日志结构意味着如果你删除了一些东西,那么日志中就有一个缺口,所以其他数据必须重新排列(碎片整理)以填补空缺。 这对用户是不可见的,但通常很慢。
  • 必须以这样的方式做出改变,如果权力中途失败,文件系统将保持一致。 通常,这意味着要等到磁盘确认数据确实在介质上; 对于SSD,可能需要很长时间(几百毫秒)。 这样做的最终结果是有更多的簿记(即磁盘I / O操作)。
  • 所有的变化都很小。 而不是读取,写入和擦除整个闪存块(或磁盘的磁盘),你需要修改一点点。 要做到这一点,硬件必须读取整个块或圆柱体,在内存中修改它,然后再写出到媒体。 这需要很长时间。

删除大量的文件从来不是一个真正的快速操作。

为了删除任何文件系统上的文件,您需要读取文件索引,删除(或标记为已删除)索引中的文件条目,删除与该文件关联的任何其他元数据,并将为该文件分配的空间标记为没用过。 必须对每个要删除的文件单独执行,这意味着删除大量文件需要很多小I / O。 为了确保电力故障时的数据完整性,增加了更多的开销。

即使没有ZFS引入的特性,删除3000万个文件通常意味着超过一亿个单独的I / O操作。 即使使用快速SSD, 需要很长时间。 正如其他人所提到的,ZFS的devise进一步解决了这个问题。

如何重新整理arrays需要一个小时,但从磁盘删除需要4天?

这是可能的,因为这两个操作在文件系统堆栈的不同层上工作。 Resilvering可以低级运行,实际上并不需要查看单个文件,一次只能复制大量的数据。

为什么我的performance如此糟糕? 70次/秒的performance看起来非常糟糕。

它必须做很多簿记…

我可以手动删除/ tmp2的inode,但不会释放空间,对不对?

我不知道ZFS,但是如果能够自动恢复的话,最后可能会在后台执行与之前一样的操作。

这可能是一个ZFS的问题,或硬盘或什么?

zfs scrub说什么吗?

伊恩·豪森(Ian Howson)为什么这么慢,给出了一个很好的答案。

如果您并行删除文件,则由于删除操作可能会使用相同的块,因此可能会看到速度提高,因此可以多次保存同一个块的重写。

所以试试:

 find /tmp -print0 | parallel -j100 -0 -n100 rm 

看看这个performance是否比你每秒删除70次更好。

很简单,如果你反过来思考。

  1. 获得第二个驱动器(你似乎已经有了)

  2. 使用rsync从驱动器A复制到驱动器B,不包括/ tmp目录。 Rsync将比块拷贝慢。

  3. 重新启动,使用驱动器B作为新的启动卷

  4. 重新格式化驱动器A.

这也将碎片整理你的驱动器,并给你一个新的目录(罚款,碎片整理不是很重要的固态硬盘,但线性化你的文件从来没有受到伤害)

您在未sorting的列表中有三千万条logging。 您扫描您想要删除的条目列表,然后将其删除。 现在,您的未sorting列表中只有29,999,999个条目。 如果他们都在/ tmp,为什么不重新启动?


编辑以反映评论中的信息:问题陈述:删除/ tmp中大部分( 但不是全部) 30M +错误创build的文件需要很长时间。
问题1)从/ tmp中删除大量不需要的文件的最佳方法。
问题2)了解为什么删除文件太慢。

解决scheme1) – 大多数* nix发行版在启动时将/ tmp重置为空。 然而,FreeBSD不是其中之一。
第1步 – 在其他地方复制有趣的文件。
第2步 – 作为根

  $ grep -i tmp /etc/rc.conf clear_tmp_enable="YES" # Clear /tmp at startup. 

第3步 – 重新启动。
第4步 – 将clear_tmp_enable更改回“否”。
不需要的文件现在消失了,因为FreeBSD上的ZFS具有这样的function:“销毁数据集比删除数据集中的所有文件快得多,因为它不涉及扫描所有文件并更新所有相应的元数据。 “ 所以在启动时必须重置/ tmp数据集的元数据。 这很快。

解决scheme2)为什么这么慢? ZFS是一个很好的文件系统,它包含诸如定时目录访问等function。 如果你知道自己在做什么,这就很好,但是证据表明OP不是ZFS专家。 OP没有说明他们是如何删除这些文件的,但是我猜测他们使用了“find regex -exec rm {} \;”这个变种。 这与小数字,但没有规模,因为有三个串行操作正在进行1)得到可用文件的列表(按照散列顺序返回3000万文件),2)使用正则expression式来select下一个要删除的文件,3 )告诉操作系统find并从3000万列表中删除该文件。 即使ZFS从内存中返回一个列表,并且如果 “查找”caching它,正则expression式仍然需要从列表中识别下一个要处理的文件,然后通知操作系统更新其元数据以反映该更改,然后更新列表它不会再被处理。