V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
谷否 | 三分谷地,为你喜欢
AI 大模型 + 柔性供应链,不仅可以为你测试香水味道,还能一件定制实体香水,快速发货。
Promoted by wuqiwen
juniorzhou
V2EX  ›  Linux

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

  •  
  •   juniorzhou · 2024-05-21 02:14:26 +08:00 · 4857 次点击
    这是一个创建于 420 天前的主题,其中的信息可能已经有所发展或是发生改变。

    因为某些需求,经常要在 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 条附言  ·  2024-05-21 11:06:15 +08:00
    补充一下,没有 root 权限。所以很多命令用不了。
    第 2 条附言  ·  2024-05-22 05:37:54 +08:00
    感谢大家的回复。
    看了一下,感觉最靠谱的还是用 多线程 调用 rm/rsync 删 比较靠谱。实在不行就调用一个 128 核心的运算 node 来删除吧。

    有没有什么关于打包的建议。不需要压缩,硬盘容量足够。就是想 快速 把千万个小文件集合成一个大文件,甚至可以接受容量 10 倍左右的损失(增长)。主要就是要快,打包解包都快最好。我这个文件系统文件数有配额限制,不能超过 2 亿,但是体积几乎没有。
    39 条回复    2024-05-23 10:11:51 +08:00
    syncake
        1
    syncake  
       2024-05-21 04:05:51 +08:00
    抛砖引玉
    mkdir /tmp/a
    rsync -av --delete /tmp/a/ /dir-you-need-del/
    zeusho871
        2
    zeusho871  
       2024-05-21 04:53:17 +08:00 via Android
    rimraf 不知道基于啥实现,node_modules 都能干,window/linux 都可以
    RobinHuuu
        3
    RobinHuuu  
       2024-05-21 07:34:25 +08:00 via Android
    容器或者虚拟磁盘?
    iceheart
        4
    iceheart  
       2024-05-21 07:50:07 +08:00 via Android
    mkfs
    ho121
        5
    ho121  
       2024-05-21 08:01:57 +08:00 via Android
    或许可以换个思路。挂载磁盘镜像,写文件写到镜像里,删除只需要删除镜像文件即可。

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

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

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


    @lrh3321 我也考虑过建个文件表。这样性能会比 find 直接删文件夹好么?这样可以考虑用 mpi 来删倒是。
    wenxueywx
        12
    wenxueywx  
       2024-05-21 11:19:18 +08:00
    我也推荐#1 的方法
    a7851578
        13
    a7851578  
       2024-05-21 11:35:34 +08:00
    需要都保留吗?不需要的话根据时间间隔删。
    需要全部放一起吗?不需要的话分 N 个文件夹慢慢删
    tar 不能做压缩
    BeautifulSoap
        14
    BeautifulSoap  
       2024-05-21 11:47:44 +08:00
    确实路过问一下,为什么 linux 删除一个目录只能一个个删掉目录下文件,而不是直接把目录对应的 node 直接删了,这样所有文件不就失去索引相当于被删了吗
    如果我不在乎数据安全之类的只追求快速删目录,有办法直接把目录的 node 干掉吗?
    julyclyde
        15
    julyclyde  
       2024-05-21 13:20:41 +08:00
    你这个需求可能有问题
    如果有删除掉需求,那么创建的时候就应该面向删除做优化
    ll26571
        16
    ll26571  
       2024-05-21 14:08:08 +08:00
    @BeautifulSoap 最直接的一点,删目录得把其子文件所占用的空间全部释放掉,这里其实有个容易混淆的点就在于,这个目录下面假设有两个 1g 的.txt 文件,那么从上层视角来看,这个目录占了 2g ,但真实情况是,这个目录本身可能只占用了 2 个块( inode 占一个块,dentry table 占一个块),也就是 8KB 而已。因此,如果你不去遍历下面的子文件,而是只拿掉这个目录本身,那意味着最多只能回收 8KB ,而下面的那两个 1g 的 txt 所占用的块你怎么回收?
    yang0327519
        17
    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
        18
    mayli  
       2024-05-21 14:14:11 +08:00
    @juniorzhou 感觉目前应该没啥更优的解法了,普通的文件系统可能要删更久,大部分文件系统都没有对删除一堆小文件做特殊优化,每个删除都是个复杂的原子操作。除非你可以不走 linux 的文件系统,直接调用某些 gpfs 的某些接口。
    Jirajine
        19
    Jirajine  
       2024-05-21 14:18:47 +08:00
    @BeautifulSoap btrfs subvolume 可以当目录用,删就是整个删,一次操作完成。因为 vfs 需要支持各种文件系统的实现,一个远程挂载的共享你怎么“直接把目录对应的 node 干掉”?
    zhixi
        20
    zhixi  
       2024-05-21 14:41:37 +08:00
    @syncake rsync 在 ext4 这样的文件系统上快,在 GPFS 上真不一定能跑过 parallel
    tianice
        21
    tianice  
       2024-05-21 15:24:32 +08:00
    如果需要频繁的创建、删除,是不是可以直接修改,别再删了😄️
    lucasj
        22
    lucasj  
       2024-05-21 16:14:14 +08:00
    可以试试 find + -delete ,我感觉挺快的
    find . -type f -name "{file_pattern}" -delete
    lucasj
        23
    lucasj  
       2024-05-21 16:21:17 +08:00
    并行删除不一定比顺序删除快,因为瓶颈在文件 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)."
    zlowly
        24
    zlowly  
       2024-05-21 16:42:22 +08:00
    @lucasj 附议
    我的实践经验也是 find 的 -delete 参数比 xargs 并行删除要快得多
    LJason
        25
    LJason  
       2024-05-21 16:52:12 +08:00
    歪个楼,Linux 不知道,但我在 Win 下这么搞:
    Get-ChildItem -Recurse "PATH" | Remove-Item -Force -Recurse

    比单纯 Remove-Item -Force -Recurse "PATH" 快很多
    julyclyde
        26
    julyclyde  
       2024-05-21 18:50:31 +08:00
    @ll26571 fsck 回收。哈哈哈哈
    zsj1029
        27
    zsj1029  
       2024-05-21 18:56:09 +08:00
    rm -rf node_modules
    想不到更快的了,这个比 win 删除可快多了
    即便是在 win 下,用 git bash rm 也比 win 点删方便快速
    lolizeppelin
        28
    lolizeppelin  
       2024-05-21 19:20:29 +08:00 via iPhone
    不要删 移送到回收站
    定期清理回收站
    ETiV
        29
    ETiV  
       2024-05-21 19:34:54 +08:00
    楼上有提到过,find 有个 -delete 参数,可以试一下
    leetom
        30
    leetom  
       2024-05-21 20:27:09 +08:00
    我记得看过一个测试,大多数情况下都是 rm 最快,比 rsync find 之类快多了,毕竟专门干这个的。

    上面说的 qcow2 是个好方案,不一定非要 root 权限,可以丢到虚拟机里操作
    jpuyy
        31
    jpuyy  
       2024-05-21 23:43:26 +08:00
    有没有可能一个程序把很多文件内容清空,另一个进程来删文件?
    sunqb
        32
    sunqb  
       2024-05-21 23:49:11 +08:00 via Android
    有个思路,直接改文件系统的索引
    sendi
        33
    sendi  
       2024-05-22 03:44:11 +08:00
    juniorzhou
        34
    juniorzhou  
    OP
       2024-05-22 05:31:55 +08:00
    @a7851578 是的,我知道 tar 不能压缩,我只是为了把小文件打包而已,硬盘容量足够大,1~2PB 呢。

    @julyclyde 可惜运行的是一个比较大且老旧的程序,比较难改了。而且为了删文件去改好像也不值当。

    @mayli 赞同。我去查查 gpfs 的手册吧。

    @tianice 创建新的比修改旧的快的多的多,而且也节省计算资源,没理由去修改啊。

    @lucasj 我这里 IO 应该不是瓶颈,并行删除肯定是更快的。就是想问问有没有什么更高效的删除操作。

    @zsj1029 rm 单线程删除的确还行,可惜本身不支持多线程,我现在其实就是多开 rm 。
    Hf1G1sGBYS8QSLN8
        35
    Hf1G1sGBYS8QSLN8  
       2024-05-22 08:51:20 +08:00
    我问了一下 GPT-4o,感觉答案挺靠谱的。
    P0P
        36
    P0P  
       2024-05-22 09:41:18 +08:00
    删除卡在元数据操作,线程高了估计也没太大帮助。
    如果能改代码,把文件操作变为操作一个大文件不同 offset ,最后把大文件删除即可。
    MrKrabs
        37
    MrKrabs  
       2024-05-22 10:15:01 +08:00
    那你用 unlink 嘛,多少能快点
    julyclyde
        38
    julyclyde  
       2024-05-22 14:11:01 +08:00
    @P0P offset ?是不是可以 loopback ?
    realpg
        39
    realpg  
    PRO
       2024-05-23 10:11:51 +08:00
    自己搞个 file system 是最省事的办法
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1486 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 23:57 · PVG 07:57 · LAX 16:57 · JFK 19:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.