将100万个图像文件迁移到Amazon S3

8
我经营着一个图片分享网站,拥有超过100万张照片(约150GB)。目前我将它们存储在专用服务器上的硬盘上,但是空间很快就会用完,所以我想将它们转移到Amazon S3。
我尝试了进行RSYNC同步,但扫描和创建图像文件列表就花费了一天时间。在传输另外一天后,仅完成了7%,并将我的服务器速度降到了极慢,因此我不得不取消同步。
是否有更好的方法来处理这个问题?例如,将它们GZIP压缩到另一个本地硬盘中,然后传输/解压缩该单个文件?
我还想知道是否将这些文件存储在多个子目录中是有意义的,或者将100万个以上的文件放在同一个目录中是否可以。

3
这与编程无关。 - Alan
你可以在服务器不太繁忙的时候晚上运行它。此外,还有“nice”工具,可能会减少你的缓慢问题。由于rsync可以配置为跳过重复项,速度最终会提高。我肯定会将图像分成子目录,因为许多Linux命令一旦超过100,000个文件就开始失败。另一个问题是,如果文件太多,你可能会用完inode。 - PJ Brunet
3个回答

25

一种选项可能是懒惰式地进行迁移。

  • 所有新的图片都存储到Amazon S3中。
  • 对于尚未在Amazon上的任何图片的请求,则会触发将该图片迁移到Amazon S3。(将其排队)

这样可以相当快速地将所有最近或常用的图像移至Amazon,从而减少服务器负载。然后,您可以添加另一个任务,以在服务器最不繁忙时缓慢迁移其他图像。


2
最近我采用了这种方法,将4000万张图片迁移到S3。我已经将我使用的代码放在Github上,希望其他人也会发现它有用:https://github.com/mikery/s3cacher - Mike Ryan
我也赞同这个想法。优雅。 - Ali Muzaffar Khan

5
  1. 考虑到文件还未存在于S3上,将它们作为归档文件发送比使用同步协议更快。

  2. 然而,对于图像文件来说,压缩归档文件并不会(或者只会稍微)有所帮助,因为假设这些图像文件已经以JPEG等压缩格式存储。

  3. 传输约150 GB的数据将消耗大量网络带宽,并且需要很长时间。如果可能的话,离线传输会更好;例如,发送硬盘、一组磁带或DVD。

  4. 将100万个文件放入一个平面目录中从性能角度来看是一个不好的想法。尽管某些文件系统可以处理O(logN)的文件名查找时间,但其他文件系统则无法做到O(N)的文件名查找。乘以N来访问目录中的所有文件。另一个问题是,需要按文件名顺序访问文件的实用程序如果需要排序100万个文件名,则可能会显著减慢速度。(这可能部分解释了为什么rsync花费了1天进行索引。)

  5. 将所有图像文件放在一个目录中从管理角度来看是一个不好的想法;例如,进行备份、存档、移动文件或扩展到多个磁盘或文件系统等。


将1百万个文件分成1,000个子目录是合理的吗?难道需要超过1层的文件吗? - makeee
是的,它可以。有多种方法可以实现这一点,具体取决于它们的命名和组织方式,以及您想如何管理它们等因素。 - Stephen C
1
如果我要将文件拆分,gzip 似乎没有意义...我可能只需循环遍历数据库中的每个项目,获取文件名,将文件复制到 S3,将其文件名更改为其 mysql 自动增量 ID。然后,我可以根据它们的 ID 拆分文件(而且我将不再需要在数据库中具有文件名列)。即使需要一个月时间,我也至少可以每天完成一部分工作,并开始从 S3 中读取已存在 S3 上的文件,并删除旧文件以节省空间。这听起来合理吗? - makeee
1
S3没有“文件夹”的扩展问题 - 因为它没有文件夹。每个文件都有一个键(通常应该看起来像路径)images/892849845.png。 - Tom Andersen
S3文件系统中的一个好处是它是一个“无限分叉”的文件系统。假设您想将所有数据存储在S3中,包括每个图像的标签、图像名称、地理位置等,则可以存储类似于images/8248478798.png/tags.json和images/8248478798.png/info.json等内容,这真的很酷。 - Tom Andersen

4

与其通过网络传输文件,您可以将它们放在硬盘上并将其运送到亚马逊的导入/导出服务中。这样您就不必担心服务器的网络连接被饱和等问题。


很不幸,这并不是一个可行的选择,因为我无法轻松进入数据中心来执行此类操作。 - makeee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接