文件/镜像复制

5
我有一个简单的问题,想听听其他人在多个主机之间复制图像的最佳方法的经验。
我已确定将图像存储在数据库中,然后使用数据库复制在多个主机上将导致最大可用性。
我对文件系统的担忧在于同步图像的困难(例如,我不希望5个服务器都访问同一个服务器以获取图像!)。
现在,我对将图像存储在数据库中唯一担心的是额外的查询会影响数据库,并且如果我想要“虚拟”图像链接指向数据库条目,则必须放置额外的处理(例如AddHandler)。
就我所了解的而言:
如果您有一个脚本提供图像:每个图像都需要一个数据库调用。
如果您将图像显示为二进制数据:可以在单个数据库调用中完成。
为了提供外部/可链接的图像,您必须为您想要“伪造”的扩展名添加addHandler,并将其指向您的脚本语言(例如php,asp)。
我可能漏掉了什么,但我很好奇是否有其他更好的想法?
编辑:Tom建议使用mod_rewrite来保存使用AddHandler,我已接受作为解决AddHandler问题的建议方案。但是,我仍然觉得没有完整的解决方案,请继续回答;)
一些人建议使用lighttpd而不是Apache。 lighttpd的ISAPI模块有多大不同?
4个回答

3
如果您将图像存储在数据库中,那么您需要额外访问数据库,并且会失去 Web 服务器本身的缓存/文件服务优化。Apache 可以比 PHP 更快地提供静态图像。

在我们的大型应用程序环境中,我们使用多达 4 个集群:

  • 应用程序服务器集群
  • Web 服务/数据服务集群
  • 静态资源(图像、文档、多媒体)集群
  • 数据库集群

您会惊讶于静态资源服务器可以处理多少流量。由于它不需要计算(没有应用逻辑),响应可以被大大优化。如果您选择单独的静态资源集群,则还可以打开更改架构的一部分的可能性。例如,在某些基准测试中,lighttpd 甚至比 Apache 更快地提供静态资源。如果您有一个单独的集群,您可以在不改变应用程序环境中的任何其他内容的情况下更改您的 HTTP 服务器。

我会从一个由两台静态资源组成的集群开始,并查看其性能如何。这是分离函数的另一个好处 - 您只需在需要的地方扩展即可。至于文件同步,可以查看现有的文件同步工具,而不是自己编写。您可能会发现某个工具可以满足您的需求,而无需编写任何代码。

嗨,Corbin,感谢您的回复。说实话,我甚至没有考虑过Web服务器缓存,您是正确的,Web服务器可能会响应HTTP 200而不是HTTP 304的图像。您是否百分之百确定Web服务器不会看到URI和文件大小并响应304。 - Jay
我并没有太考虑200与304的问题。即使服务器没有捕捉到,你也可以编写处理程序返回一个304状态码。当我提到文件服务优化时,我更多地考虑的是你的服务器是否针对静态文件进行了优化——缓存常用请求的文件并避免脚本执行。 - Corbin March
嗨Corbin,谢谢并且我同意。然而,如果记录实际上已更改,则可能会遇到“伪造”HTTP 304的陷阱。我肯定希望图像请求在访问数据库之前先访问缓存,但必须有某种缓存失效机制。 - Jay

2
从任何你决定存储的地方提供图像是一个微不足道的问题;我不会讨论如何解决它。
决定在哪里存储它们是你需要做出的真正决策。你需要考虑你的目标:
- 硬件冗余 - 大量廉价存储 - 读取扩展性 - 写入扩展性
后两者并不相同,肯定会引起问题。
如果你有信心这个图像库的大小不会超过你愿意放在网页服务器上的磁盘(比如,现在写作时最大的高速服务器级磁盘为200G,我假设你想使用1U网页服务器,所以你不能存储更多的RAID1,这取决于你的供应商),那么你可以通过在每个网页服务器上放置所有图像的副本来获得非常好的读取扩展性。
当然,你可能也想在某个地方保留一个主副本,并有一个守护进程或进程定期同步它们,并监控它们是否保持同步和这个守护进程是否工作,但这些都是细节。在每个网页服务器上保留一个副本将使读取扩展性几乎完美。
但是,到处保留副本将破坏写入可扩展性,因为每个网页服务器都必须写入每个更改/新文件。因此,你的总写入吞吐量将受限于集群中最慢的单个网页服务器。
将图像数据在许多服务器之间进行“分片”将提供良好的读/写扩展性,但这是一个非常复杂的练习。它也可能允许你使用廉价的存储。
拥有一个单一的中央服务器(或者主/备份对等体或其他东西)与昂贵的IO硬件将比在所有地方使用“便宜”的IO硬件提供更好的写入吞吐量,但你将受到读取扩展性的限制。

感谢您的回复,MarkR。我目前正在考虑这里的回复,看哪种解决方案最适合我。我最不想看到的是有4个不同的服务器,数据不同步!我听说过Stackless IO的好处,您有什么看法? - Jay

1

将图像存储在数据库中并不意味着每个图像都需要进行数据库调用;当检索图像时,您可以在每个主机上单独缓存这些图像(例如,存储为临时文件)。源图像仍然保存在数据库中,并且很容易在服务器之间进行同步。

您实际上也不需要添加Apache处理程序来通过PHP脚本提供图像并保持良好的URL格式 - 您可以创建类似于http://server/image.php/param1/param2/param3.JPG的URL,并通过$_SERVER['PATH_INFO']读取参数。如果需要的话,您还可以使用mod_rewrite删除URL中的'image.php'部分。


嗨Tom, 感谢您的回复。使用mod_rewrite肯定可以避免使用apache AddHandler。我已经在使用mod rewrite,所以实现这个不会太费力。 - Jay

1

您正在寻找的已经存在,它被称为MogileFS。 目标设置涉及mogilefsd、复制的mysql数据库以及用于提供文件的lighttd/perlbal;它将为您带来故障转移、细粒度文件复制(例如,您可以决定在多个物理设备上复制最终用户图像,并仅保留缩略图的一个物理实例)。负载均衡也可以很容易地实现。


嗨MatthieuP,感谢您的非常有趣的回复!我需要研究一下这个,但听起来确实很理想! - Jay
我已经更新了我的问题,我很好奇:lighttpd的ISAPI模块有多不同? - Jay

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