0

我计划在网络服务器上存储许多图像(>100,000)。

文件名将是前。

324-2012-07-25-143544.jpg

文件名是这样构建的:

用户 ID-年-月-日-HHMMSS.jpg

此文件名将保存在 mysql 数据库中,并将被读取,并且从文件名中您知道文件路径 ->

图片/用户ID/年/月/日/用户ID-年-月-日-HHMMSS.jpg

所以在这个例子中

图片/324/2012/07/25/324-2012-07-25-143544.jpg

将所有内容保存在基本文件夹 /images 中时可能出现的任何性能问题?

谢谢你!

4

2 回答 2

5

像您正在做的那样,分片文件是避免在一个目录中包含许多文件时出现性能问题的好方法:在这种方法中,您可以确保在任何给定目录中只有少数条目(目录或文件)。如果需要,也可以轻松拆分多个卷 - 您只需将一些高级目录安装在不同的位置。

不过,您应该考虑几件事。

身份

如果您要对这些图像进行基本永久存储,则可能需要基于 id 进行分片。这在数据库方面更容易处理(出于同样的原因,我们在数据库设计中使用任意主键)。

就像@Veger 建议的那样: imageid123456变成/12/1234/123456.jpg.

安全

但是,使用日期、用户 ID 或自动递增数字可能会带来安全风险,因为它们相对容易猜到,因此有人很容易收集所有图像。

此外,如果用户没有理由知道上传日期,则在 URL 中包含日期可能会泄露信息。

如果您使用的是一个非常难以猜测的密钥,它可以提供一定程度的安全性,防止收集和信息泄露。例如,您可以使用 GUID:图像 ID6f33395e-eda8-4486-8b8e-51ea0f91751b存储为/6/6f33/6f33395e/6f33395e-eda8-4486-8b8e-51ea0f91751b.jpg.

有大量的 GUID(它是 128 位),因此有人可能需要数百万年才能收获所有东西(即使您不采取任何额外的步骤,例如限制每小时每个 IP 的连接等)。

易失性图像

如果您的图像是不稳定的——也就是说,它们会在一段时间后过期——那么实际上最好根据日期结构进行分片,例如/2012/12/14/2012-12-14-hhmmss-userid.jpg,或者您可以将它与 guid 结合并获取/2012/12/14/6f/6f33395e-eda8-4486-8b8e-51ea0f91751b.jpg

如果你想删除所有 2011 的文件,你只需rm -rf 2011. 使用它的一个很好的例子是日志文件。

您必须记住,这仅对大量图像才有意义因为您可以在数据库中进行查询以根据日期查找过时的图像,然后将它们一一删除。

分片粒度

对您计划最终存储的图像使用更高粒度的分片,但请记住,如果您太细化,您将失去大量用于目录条目的开销磁盘空间。

目标是将每个目录的条目数保持在文件系统可以处理的范围内;好的经验法则似乎是最大约 10,000。您必须预测您的网站将在接下来的一段时间内获得的流量。不过不要发疯,想想在某个时候你可能每天会拥有数百万用户。重新分片并非不可能,但这很痛苦。预测未来几年的增长并处理好。如果你增长得更快并且因此不得不重新分片,那么,这是一个很好的解决问题。如果由于目录条目占用的空间多于图像而导致磁盘空间不足,那么这是一个愚蠢的问题。

于 2012-12-14T19:33:25.900 回答
1

我会这样做:

  • 只需为您存储的每个图像使用唯一的 id(只是一个数字,如表 id 字段)
  • 检查您的网络服务器上一个目录中的最大文件数是多少
  • 将 id 除以该数字以获取目录名称
  • 将图像(带有数字)存储在此目录中

例如,图像编号1存储为/0/1.jpg,图像编号1234567存储为/123/1234567.jpg(假设您可以在一个目录中存储 10000 个文件)。

最简单,噪音最少,并优化目录中的文件数量(而不是浪费大量半满的目录)。

如果您真的要存储大量图像,请使用 2 个子目录!像,/0/0/1.jpg/1/12345/123456789.jpg

于 2012-12-14T19:23:23.457 回答