请教一下各位如何在 Linux 环境下快速删除大量文件

2024-05-21 02:14:26 +08:00
 juniorzhou

因为某些需求,经常要在 linux 环境下读写/删除创建 千万量级的文件,每个文件大小在 1M 左右。

文件系统是 GPFS parallel file system ,顺序 IO 估计有个 100GB/s 吧。创建的时候问题不大,用 mpi 速度还挺快,几乎无感。2000 个 mpi 任务几分钟就写好了,所以感觉 IO 应该不是瓶颈(?)

只不过删除的时候有点痛苦,不太想调用运算集群来删,有点浪费资源,希望能用一个 node 来快速完成删除,最好调用小于 128 个核心。

rm 太慢,就不考虑了。试过 rscyn ,性能也一般。现在用 find + parellel rm ,用 10 个进程删,凑合能用。不知道各位有没有什么好的建议快速删除这些文件。

另外偶尔也有备份的需求,因为不太常用,基本就用 tar 打包,丢在那半天一天也就打包好了,打包完 1~10t 左右的量级。如果哪位大佬有快速打包/解包的方案建议在此一并谢过。

4978 次点击
所在节点    Linux
39 条回复
syncake
2024-05-21 04:05:51 +08:00
抛砖引玉
mkdir /tmp/a
rsync -av --delete /tmp/a/ /dir-you-need-del/
zeusho871
2024-05-21 04:53:17 +08:00
rimraf 不知道基于啥实现,node_modules 都能干,window/linux 都可以
RobinHuuu
2024-05-21 07:34:25 +08:00
容器或者虚拟磁盘?
iceheart
2024-05-21 07:50:07 +08:00
mkfs
ho121
2024-05-21 08:01:57 +08:00
或许可以换个思路。挂载磁盘镜像,写文件写到镜像里,删除只需要删除镜像文件即可。

另外 qcow2 可以开启压缩,直接当作是打包
lrh3321
2024-05-21 08:11:58 +08:00
我觉得可能是这个文件系统读取文件夹下文件的性能比较差,时间都花在 find 命令上了。试试创建的时候手动 redis,sqlite 之类的方法把文件信息记下来,然后删除时,用完整路径直接去删
mayli
2024-05-21 08:53:24 +08:00
的确 删除文件一直是个老大难问题
一般来说单线程 rsync 是最快的
你后台 io 够的话,试试多线程 rsync ,find 限制深度 然后用 xargs/parallel 去删
ruidoBlanco
2024-05-21 08:54:57 +08:00
换个思路,不在乎时间段话,ionice 慢慢删?
cnleon
2024-05-21 09:11:47 +08:00
单独分块盘来写,写完就直接格式化
june4
2024-05-21 09:34:37 +08:00
经常删除 npm 一大堆上万个小文件,发现 ssd 的在线 trim 和定时 trim 性能差别太大了,至少速度差有好几倍以上。
似乎现在的 linux 也都推荐定时 trim 了。

https://wiki.archlinux.org/title/Solid_state_drive
juniorzhou
2024-05-21 11:13:08 +08:00
@mayli 我现在就是 find 限制深度然后 xargs/parallel 删,感觉还是性能不满意,不说 10 分钟删完,至少写入时间的 2~3 倍内删完吧。我写入大概只要 10 分钟。

@RobinHuuu
@cnleon
@ho121 可惜没权限挂载硬盘。


@lrh3321 我也考虑过建个文件表。这样性能会比 find 直接删文件夹好么?这样可以考虑用 mpi 来删倒是。
wenxueywx
2024-05-21 11:19:18 +08:00
我也推荐#1 的方法
a7851578
2024-05-21 11:35:34 +08:00
需要都保留吗?不需要的话根据时间间隔删。
需要全部放一起吗?不需要的话分 N 个文件夹慢慢删
tar 不能做压缩
BeautifulSoap
2024-05-21 11:47:44 +08:00
确实路过问一下,为什么 linux 删除一个目录只能一个个删掉目录下文件,而不是直接把目录对应的 node 直接删了,这样所有文件不就失去索引相当于被删了吗
如果我不在乎数据安全之类的只追求快速删目录,有办法直接把目录的 node 干掉吗?
julyclyde
2024-05-21 13:20:41 +08:00
你这个需求可能有问题
如果有删除掉需求,那么创建的时候就应该面向删除做优化
ll26571
2024-05-21 14:08:08 +08:00
@BeautifulSoap 最直接的一点,删目录得把其子文件所占用的空间全部释放掉,这里其实有个容易混淆的点就在于,这个目录下面假设有两个 1g 的.txt 文件,那么从上层视角来看,这个目录占了 2g ,但真实情况是,这个目录本身可能只占用了 2 个块( inode 占一个块,dentry table 占一个块),也就是 8KB 而已。因此,如果你不去遍历下面的子文件,而是只拿掉这个目录本身,那意味着最多只能回收 8KB ,而下面的那两个 1g 的 txt 所占用的块你怎么回收?
yang0327519
2024-05-21 14:12:40 +08:00
//创建并挂载虚拟磁盘
fallocate -l 10G t.img && mkfs.ext4 t.img && mkdir /tmp/TestMountPoint && mount -o loop t.img /tmp/TestMountPoint

//用完删除
umount /tmp/TestMountPoint && rm -f t.img
mayli
2024-05-21 14:14:11 +08:00
@juniorzhou 感觉目前应该没啥更优的解法了,普通的文件系统可能要删更久,大部分文件系统都没有对删除一堆小文件做特殊优化,每个删除都是个复杂的原子操作。除非你可以不走 linux 的文件系统,直接调用某些 gpfs 的某些接口。
Jirajine
2024-05-21 14:18:47 +08:00
@BeautifulSoap btrfs subvolume 可以当目录用,删就是整个删,一次操作完成。因为 vfs 需要支持各种文件系统的实现,一个远程挂载的共享你怎么“直接把目录对应的 node 干掉”?
zhixi
2024-05-21 14:41:37 +08:00
@syncake rsync 在 ext4 这样的文件系统上快,在 GPFS 上真不一定能跑过 parallel

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1042452

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX