我需要使用 nginx 提供大约 70,000 个静态文件 (jpg)。我应该将它们全部转储到一个目录中,还是有更好 (更高效) 的方法?由于文件名是数字,我考虑采用如下目录结构:
xxx/xxxx/xxx
操作系统是CentOS 5.1
答案1
基准测试,基准测试,基准测试!你可能会发现没有显著差异两种方案之间,这意味着您最好将时间花在其他问题上。如果您进行了基准测试,发现没有真正的区别,则选择更简单的方案 — 如果只有程序必须访问文件,则选择易于编码的方案;如果人们需要频繁使用文件,则选择易于人类操作的方案。
至于哪个更快,我相信目录查找时间与目录中文件数量的对数成正比。因此,嵌套结构的三次查找中的每一次都会比一次大查找快,但三次查找的总和可能会更大。
但不要相信我,我根本就不知道自己在做什么!衡量绩效当它重要的时候!
答案2
这实际上取决于您用来存储文件的文件系统。
有些文件系统(比如 ext2 和程度较轻的 ext3)在一个目录中有数千个文件时会变得非常慢,所以使用子目录是一个非常好的主意。
其他文件系统,例如 XFS 或 reiserfs(*),不会因为一个目录中有数千个文件而减慢速度,因此无论您有一个大目录还是许多较小的子目录都没有关系。
(*) reiserfs 有一些不错的功能,但它是一个实验性的玩具,有过灾难性失败的历史。不要将它用在任何甚至稍微重要的事情上。
答案3
正如其他人所说,目录散列很可能是最优化的。
我建议你做的是让你的 URI独立的无论你使用什么目录方案,使用 nginx 的重写模块,例如将 example.com/123456.jpg 映射到 /path/12/34/123456.jpg
然后,如果您的目录结构由于性能原因需要改变,您可以更改它而不更改已发布的 URI。
答案4
您可以在 nginx 服务器的前端放置一个 squid 缓存。Squid 可以将热门图片保存在内存中,也可以使用自己的文件布局进行快速查找。
对于 Squid,默认为 16 个一级目录和 256 个二级目录。对于我的文件系统来说,这些是合理的默认值。
如果您不使用 Squid 之类的产品,而是创建自己的文件结构,那么您需要为您的文件设计一个合理的哈希算法。如果文件名是随机生成的,这很容易,您可以使用文件名本身来划分存储桶。如果您的所有文件都看起来像 IMG_xxxx,那么您要么需要使用最低有效数字,要么对文件名进行哈希处理并根据该哈希数字进行划分。