如何在网络服务器上存储许多图像?

时间:2012-12-14 19:13:39

标签: mysql filesystems storage

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

文件名将为ex。

  

324-2012-07-25-143544.jpg

文件名是这样构建的:

  

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

此文件名将保存在mysqldatabase中,并且将从您知道文件路径的文件名中读取 - >

  

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

所以在这个例子中它将是

  

图像/二千零十二分之三百二十四/ 07/25 / 324-2012-07-25-143544.jpg

将所有内容保存在basefolder / images中时可能出现的任何性能问题?

谢谢你!

2 个答案:

答案 0 :(得分:5)

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

你应该考虑几件事。

身份

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

与@Veger建议:imageid 123456变为/12/1234/123456.jpg

安全

使用日期,用户ID或自动增加数字可能会带来安全风险,因为它们相对容易猜测,因此某人收集所有图像非常容易。

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

如果您使用的是非常难以猜测的密钥,它可以提供一定程度的安全性来防止收获和信息泄漏。例如,您可以使用GUID:图像ID 6f33395e-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最大。您必须预测您的网站下次获得的流量。不要发疯,在某种程度上思考你每天可能会有数百万用户。重新粉碎并非不可能,但这是一种痛苦。预测未来几年的增长并处理。如果你成长得更快并且不得不重新粉碎,那么,这是一个很好的解决问题。如果你的磁盘空间不足,因为你的目录条目比你的图像占用更多空间,那么,这是一个愚蠢的问题需要处理。

答案 1 :(得分:1)

我会这样做:

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

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

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

如果确实要存储批次图像,请使用2个子目录!比如,/0/0/1.jpg/1/12345/123456789.jpg