如何解决linux子目录数量限制?

Non*_*-da 10 linux filesystems directory scalability

我有一个网站,可以存储用户个人资料图片。每个图像都存储在用户特定的目录 (Linux) 中。目前我有 30 多个客户群,这意味着我将拥有 30 多个文件夹。但是我当前的 Linux 机器(ext2/ext3)不支持创建超过 32000 个目录。我该如何度过这一关?即使是 YouTube 的人也有同样的问题,视频缩略图。但是他们通过迁移到 ReiserFS 解决了这个问题。我们不能有更好的解决方案吗?

更新:当在 IRC 中询问时,人们询问是否将其升级到 ext4,它有 64k 的限制,当然你甚至可以通过它。或者内核黑客来改变限制。

更新:如何根据用户 ID 范围将用户群拆分为文件夹。意思是一个文件夹中的 1-1000,另一个文件夹中的 1000-2000。这似乎很简单。你说呢,伙计们?

坦白说,就没有其他办法吗?

Dav*_*ett 16

该限制是针对每个目录的,而不是针对整个文件系统的,因此您可以通过进一步细分来解决它。例如,不是让同一目录中的所有用户子目录按照名称的前两个字符拆分它们,因此您有如下内容:

top_level_dir
|---aa
|   |---aardvark1
|   |---aardvark2
|---da
|   |---dan
|   |---david
|---do
    |---don
Run Code Online (Sandbox Code Playgroud)

更好的是创建某种形式的名称散列并将其用于除法。通过这种方式,您将在目录中得到更好的分布,而不是像最初的字母示例那样,“da”非常满而“zz”完全为空。例如,如果您使用 CRC 或 MD5 名称并使用前 8 位,您将得到如下结果:

top_level_dir
|---00
|   |---some_username
|   |---some_username
|---01
|   |---some_username
...
|---FF
|   |---some_username
Run Code Online (Sandbox Code Playgroud)

这可以根据需要扩展到更深的深度,例如,如果使用用户名而不是哈希值:

top_level_dir
|---a
|   |---a
|       |---aardvark1
|       |---aardvark2
|---d
    |---a
    |   |---dan
    |   |---david
    |---o
        |---don
Run Code Online (Sandbox Code Playgroud)

这个方法用在很多地方,比如squid的缓存,复制Ludwig的例子,以及浏览器的本地缓存。

需要注意的一件重要事情是,使用 ext2/3,您将在接近 32,000 限制之前开始遇到性能问题,因为目录是线性搜索的。移动到另一个文件系统(例如 ext4 或 reiser)将消除这种低效率(reiser 使用二进制拆分算法搜索目录,以便更有效地处理长目录,ext4 也可以这样做)以及每个目录的固定限制。


Lud*_*erl 7

如果您绑定到 ext2/ext3,我看到的唯一可能性就是对您的数据进行分区。找到一个标准,将您的数据分成大小相似的可管理块。

如果只是关于个人资料图片,我会这样做:

  1. 使用图像的哈希(例如 SHA1)
  2. 使用 SHA1 作为文件和目录名

例如,SQUID 缓存就是这样做的:

f/4b/353ac7303854033

顶级目录是第一个十六进制数字,第二级是接下来的两个十六进制数字,文件名是剩下的十六进制数字。