AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 411091
Accepted
user1717828
user1717828
Asked: 2017-12-16 08:16:04 +0800 CST2017-12-16 08:16:04 +0800 CST 2017-12-16 08:16:04 +0800 CST

文件夹中有数百万个(小)文本文件

  • 772

我们希望在 Linux 文件系统中存储数百万个文本文件,目的是能够压缩并将任意集合作为服务提供。我们尝试了其他解决方案,例如键/值数据库,但我们对并发性和并行性的要求使得使用本机文件系统成为最佳选择。

最直接的方法是将所有文件存储在一个文件夹中:

$ ls text_files/
1.txt
2.txt
3.txt

这在 EXT4 文件系统上应该是可能的,它对文件夹中的文件数量没有限制。

两个 FS 进程将是:

  1. 从网络抓取中写入文本文件(不受文件夹中文件数量的影响)。
  2. 压缩选定的文件,由文件名列表给出。

我的问题是,在文件夹中存储多达一千万个文件会影响上述操作的性能或一般系统性能,这与为文件创建子文件夹树有什么不同吗?

files filesystems
  • 5 5 个回答
  • 12448 Views

5 个回答

  • Voted
  1. roaima
    2017-12-16T09:03:59+08:002017-12-16T09:03:59+08:00

    这非常接近基于意见的问题/答案,但我会尝试提供一些事实和我的意见。

    1. 如果文件夹中有大量文件,任何尝试枚举它们的基于 shell 的操作(例如mv * /somewhere/else)都可能无法成功扩展通配符,或者结果可能太大而无法使用。
    2. ls枚举大量文件比枚举少量文件需要更长的时间。
    3. 文件系统将能够处理单个目录中的数百万个文件,但人们可能会遇到困难。

    一种建议是将文件名分成两个、三个或四个字符块,并将它们用作子目录。例如,somefilename.txt可能存储为som/efi/somefilename.txt. 如果您使用数字名称,则从右到左而不是从左到右拆分,以便分布更均匀。例如12345.txt可能存储为345/12/12345.txt.

    您可以使用等效项zip -j zipfile.zip path1/file1 path2/file2 ...来避免在 ZIP 文件中包含中间子目录路径。

    如果您从网络服务器提供这些文件(我不完全确定这是否相关),隐藏此结构以支持在 Apache2 中具有重写规则的虚拟目录是微不足道的。我认为 Nginx 也是如此。

    • 18
  2. Best Answer
    telcoM
    2017-12-16T09:11:24+08:002017-12-16T09:11:24+08:00

    ls命令,甚至是 shell 的 TAB 补全或通配符扩展,通常会以字母数字顺序显示它们的结果。这需要阅读整个目录列表并对其进行排序。在单个目录中有一千万个文件,此排序操作将花费不可忽略的时间。

    如果你能抵制制表符完成的冲动,例如写下要压缩的文件名,应该没有问题。

    通配符的另一个问题可能是通配符扩展可能会产生比最大长度命令行更多的文件名。对于大多数情况,典型的最大命令行长度绰绰有余,但是当我们谈论单个目录中的数百万个文件时,这不再是一个安全的假设。当通配符扩展中超过最大命令行长度时,大多数 shell 将简单地使整个命令行失败而不执行它。

    这可以通过使用以下find命令执行通配符操作来解决:

    find <directory> -name '<wildcard expression>' -exec <command> {} \+
    

    或尽可能使用类似的语法。将find ... -exec ... \+自动考虑最大命令行长度,并根据需要多次执行命令,同时为每个命令行拟合最大数量的文件名。

    • 11
  3. Reactgular
    2017-12-17T08:52:40+08:002017-12-17T08:52:40+08:00

    我经营一个网站,该网站处理电影、电视和视频游戏的数据库。对于其中的每一个,电视都有多个图像,每个节目包含数十个图像(即剧集快照等)。

    最终会有很多图像文件。在 250,000+ 范围内的某个地方。这些都存储在访问时间合理的已安装块存储设备中。

    我第一次尝试存储图像是在一个文件夹中/mnt/images/UUID.jpg

    我遇到了以下挑战。

    • ls通过远程终端只会挂起。该过程将变成僵尸并且CTRL+C不会破坏它。
    • 在我到达那一点之前,任何ls命令都会快速填充输出缓冲区并且CTRL+C不会停止无休止的滚动。
    • 从一个文件夹中压缩 250,000 个文件大约需要 2 个小时。您必须运行与终端分离的 zip 命令,否则任何连接中断都意味着您必须重新开始。
    • 我不会冒险尝试在 Windows 上使用 zip 文件。
    • 该文件夹很快变成了一个禁止人类进入的区域。

    我最终不得不使用创建时间将文件存储在子文件夹中来创建路径。比如/mnt/images/YYYY/MM/DD/UUID.jpg。这解决了上述所有问题,并允许我创建以日期为目标的 zip 文件。

    如果您拥有的文件的唯一标识符是数字,并且这些数字往往按顺序运行。为什么不按 和 对它们100000进行10000分组1000。

    例如,如果您有一个名为384295.txt路径的文件,则为:

    /mnt/file/300000/80000/4000/295.txt
    

    如果你知道你会达到几百万。使用01,000,000 的前缀

    /mnt/file/000000/300000/80000/4000/295.txt
    
    • 5
  4. jmullee
    2017-12-17T12:20:54+08:002017-12-17T12:20:54+08:00

    首先:防止 'ls' 使用 'ls -U' 进行排序,也许更新你的 ~/bashrc 以具有 'alias ls="ls -U"' 或类似的。

    对于您的大型文件集,您可以这样尝试:

    • 创建一组测试文件

    • 查看是否有许多文件名导致问题

    • 使用 xargs 参数批处理和 zip 的(默认)将文件添加到 zip 的行为以避免出现问题。

    这很好用:

    # create ~ 100k files
    seq 1 99999 | sed "s/\(.*\)/a_somewhat_long_filename_as_a_prefix_to_exercise_zip_parameter_processing_\1.txt/" | xargs touch
    # see if zip can handle such a list of names
    zip -q /tmp/bar.zip ./*
        bash: /usr/bin/zip: Argument list too long
    # use xargs to batch sets of filenames to zip
    find . -type f | xargs zip -q /tmp/foo.zip
    l /tmp/foo.zip
        28692 -rw-r--r-- 1 jmullee jmullee 29377592 2017-12-16 20:12 /tmp/foo.zip
    
    • 2
  5. Peter
    2017-12-17T00:55:42+08:002017-12-17T00:55:42+08:00

    从网络抓取中写入文本文件(不受文件夹中文件数量的影响)。

    要创建新文件,需要扫描目录文件,为新目录条目寻找足够的空白空间。如果没有找到足够大的空间来存储新的目录条目,它将被放置在目录文件的末尾。随着目录中文件数量的增加,扫描目录的时间也会增加。

    只要目录文件保留在系统缓存中,这样做对性能的影响不会很差,但是如果数据被释放,从磁盘读取目录文件(通常是高度碎片化的)可能会消耗相当多的时间。SSD 改善了这一点,但对于包含数百万个文件的目录,仍然可能会对性能造成明显影响。

    压缩选定的文件,由文件名列表给出。

    在包含数百万个文件的目录中,这也可能需要额外的时间。在具有散列目录条目的文件系统(如 EXT4)中,这种差异很小。

    在文件夹中存储多达一千万个文件会影响上述操作的性能或一般系统性能,这与为文件创建子文件夹树有什么不同吗?

    子文件夹树没有上述性能缺陷。此外,如果将底层文件系统更改为没有散列文件名,树方法仍然可以正常工作。

    • 1

相关问题

  • Virtualbox 动态分配磁盘 *.vdi 不断增长

  • 如何找到特定的文件类型并将它们 tar?

  • du/df 和 ls 报告不同的磁盘使用情况

  • Linux 内核开发人员如何处理数百万行代码的工作?他们是一种方法吗?[关闭]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    JSON数组使用jq来bash变量

    • 4 个回答
  • Marko Smith

    日期可以为 GMT 时区格式化当前时间吗?[复制]

    • 2 个回答
  • Marko Smith

    bash + 通过 bash 脚本从文件中读取变量和值

    • 4 个回答
  • Marko Smith

    如何复制目录并在同一命令中重命名它?

    • 4 个回答
  • Marko Smith

    ssh 连接。X11 连接因身份验证错误而被拒绝

    • 3 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Marko Smith

    systemctl 命令在 RHEL 6 中不起作用

    • 3 个回答
  • Marko Smith

    rsync 端口 22 和 873 使用

    • 2 个回答
  • Marko Smith

    以 100% 的利用率捕捉 /dev/loop -- 没有可用空间

    • 1 个回答
  • Marko Smith

    jq 打印子对象中所有的键和值

    • 2 个回答
  • Martin Hope
    EHerman JSON数组使用jq来bash变量 2017-12-31 14:50:58 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Drux 日期可以为 GMT 时区格式化当前时间吗?[复制] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC 如何复制目录并在同一命令中重命名它? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve “root”用户的文件权限如何工作? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe 将默认编辑器更改为 vim for _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey 如何下载软件包而不是使用 apt-get 命令安装它? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao 为什么目录 /home、/usr、/var 等都具有相同的 inode 编号 (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg —list-keys 命令在将私钥导入全新安装后输出 uid [未知] 2017-11-26 18:26:02 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve