因为某些需求,经常要在 linux 环境下读写/删除创建 千万量级的文件,每个文件大小在 1M 左右。
文件系统是 GPFS parallel file system ,顺序 IO 估计有个 100GB/s 吧。创建的时候问题不大,用 mpi 速度还挺快,几乎无感。2000 个 mpi 任务几分钟就写好了,所以感觉 IO 应该不是瓶颈(?)
只不过删除的时候有点痛苦,不太想调用运算集群来删,有点浪费资源,希望能用一个 node 来快速完成删除,最好调用小于 128 个核心。
rm 太慢,就不考虑了。试过 rscyn ,性能也一般。现在用 find + parellel rm ,用 10 个进程删,凑合能用。不知道各位有没有什么好的建议快速删除这些文件。
另外偶尔也有备份的需求,因为不太常用,基本就用 tar 打包,丢在那半天一天也就打包好了,打包完 1~10t 左右的量级。如果哪位大佬有快速打包/解包的方案建议在此一并谢过。
1
syncake 215 天前
抛砖引玉
mkdir /tmp/a rsync -av --delete /tmp/a/ /dir-you-need-del/ |
2
zeusho871 215 天前 via Android
rimraf 不知道基于啥实现,node_modules 都能干,window/linux 都可以
|
3
RobinHuuu 215 天前 via Android
容器或者虚拟磁盘?
|
4
iceheart 215 天前 via Android
mkfs
|
5
ho121 215 天前 via Android
或许可以换个思路。挂载磁盘镜像,写文件写到镜像里,删除只需要删除镜像文件即可。
另外 qcow2 可以开启压缩,直接当作是打包 |
6
lrh3321 215 天前 via Android
我觉得可能是这个文件系统读取文件夹下文件的性能比较差,时间都花在 find 命令上了。试试创建的时候手动 redis,sqlite 之类的方法把文件信息记下来,然后删除时,用完整路径直接去删
|
7
mayli 215 天前
的确 删除文件一直是个老大难问题
一般来说单线程 rsync 是最快的 你后台 io 够的话,试试多线程 rsync ,find 限制深度 然后用 xargs/parallel 去删 |
8
ruidoBlanco 215 天前
换个思路,不在乎时间段话,ionice 慢慢删?
|
9
cnleon 215 天前
单独分块盘来写,写完就直接格式化
|
10
june4 215 天前
经常删除 npm 一大堆上万个小文件,发现 ssd 的在线 trim 和定时 trim 性能差别太大了,至少速度差有好几倍以上。
似乎现在的 linux 也都推荐定时 trim 了。 https://wiki.archlinux.org/title/Solid_state_drive |
11
juniorzhou OP |
12
wenxueywx 215 天前
我也推荐#1 的方法
|
13
a7851578 215 天前
需要都保留吗?不需要的话根据时间间隔删。
需要全部放一起吗?不需要的话分 N 个文件夹慢慢删 tar 不能做压缩 |
14
BeautifulSoap 215 天前
确实路过问一下,为什么 linux 删除一个目录只能一个个删掉目录下文件,而不是直接把目录对应的 node 直接删了,这样所有文件不就失去索引相当于被删了吗
如果我不在乎数据安全之类的只追求快速删目录,有办法直接把目录的 node 干掉吗? |
15
julyclyde 215 天前
你这个需求可能有问题
如果有删除掉需求,那么创建的时候就应该面向删除做优化 |
16
ll26571 215 天前
@BeautifulSoap 最直接的一点,删目录得把其子文件所占用的空间全部释放掉,这里其实有个容易混淆的点就在于,这个目录下面假设有两个 1g 的.txt 文件,那么从上层视角来看,这个目录占了 2g ,但真实情况是,这个目录本身可能只占用了 2 个块( inode 占一个块,dentry table 占一个块),也就是 8KB 而已。因此,如果你不去遍历下面的子文件,而是只拿掉这个目录本身,那意味着最多只能回收 8KB ,而下面的那两个 1g 的 txt 所占用的块你怎么回收?
|
17
yang0327519 215 天前
//创建并挂载虚拟磁盘
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 |
18
mayli 215 天前
@juniorzhou 感觉目前应该没啥更优的解法了,普通的文件系统可能要删更久,大部分文件系统都没有对删除一堆小文件做特殊优化,每个删除都是个复杂的原子操作。除非你可以不走 linux 的文件系统,直接调用某些 gpfs 的某些接口。
|
19
Jirajine 215 天前
@BeautifulSoap btrfs subvolume 可以当目录用,删就是整个删,一次操作完成。因为 vfs 需要支持各种文件系统的实现,一个远程挂载的共享你怎么“直接把目录对应的 node 干掉”?
|
21
tianice 215 天前
如果需要频繁的创建、删除,是不是可以直接修改,别再删了😄️
|
22
lucasj 215 天前
可以试试 find + -delete ,我感觉挺快的
find . -type f -name "{file_pattern}" -delete |
23
lucasj 215 天前
并行删除不一定比顺序删除快,因为瓶颈在文件 I/O 操作。
"The I/O bound is the limiting factor (CPU, disk and memory utilisation was very low) and parallelisation just adds some overhead (in the simple case)." |
25
LJason 215 天前
歪个楼,Linux 不知道,但我在 Win 下这么搞:
Get-ChildItem -Recurse "PATH" | Remove-Item -Force -Recurse 比单纯 Remove-Item -Force -Recurse "PATH" 快很多 |
27
zsj1029 215 天前
rm -rf node_modules
想不到更快的了,这个比 win 删除可快多了 即便是在 win 下,用 git bash rm 也比 win 点删方便快速 |
28
lolizeppelin 215 天前 via iPhone
不要删 移送到回收站
定期清理回收站 |
29
ETiV 215 天前
楼上有提到过,find 有个 -delete 参数,可以试一下
|
30
leetom 215 天前
我记得看过一个测试,大多数情况下都是 rm 最快,比 rsync find 之类快多了,毕竟专门干这个的。
上面说的 qcow2 是个好方案,不一定非要 root 权限,可以丢到虚拟机里操作 |
31
jpuyy 214 天前
有没有可能一个程序把很多文件内容清空,另一个进程来删文件?
|
32
sunqb 214 天前 via Android
有个思路,直接改文件系统的索引
|
33
sendi 214 天前
|
34
juniorzhou OP |
35
Hf1G1sGBYS8QSLN8 214 天前
我问了一下 GPT-4o,感觉答案挺靠谱的。
|
36
P0P 214 天前
删除卡在元数据操作,线程高了估计也没太大帮助。
如果能改代码,把文件操作变为操作一个大文件不同 offset ,最后把大文件删除即可。 |
37
MrKrabs 214 天前
那你用 unlink 嘛,多少能快点
|
39
realpg 213 天前
自己搞个 file system 是最省事的办法
|