可扩展图片存储

57

我目前正在设计一个基于Web的应用程序架构,还需要提供某种图片存储功能。用户将能够上传照片作为服务的关键特性之一,同时查看这些图片也将是主要用途之一(通过Web)。

然而,我不确定如何在我的应用程序中实现可扩展的图片存储组件。我已经考虑了不同的解决方案,但由于缺乏经验,我期待听到您的建议。除了图像外,元数据也必须保存。

以下是我的初步想法:

  1. 使用(分布式)文件系统,例如HDFS,并准备专用的Web服务器作为“文件系统客户端”,以便保存上传的图像和服务请求。图像元数据保存在另一个数据库中,包括每个图像的文件路径信息。

  2. 在HDFS上使用类似BigTable的系统,例如HBase,并将图像和元数据一起保存。同样,Web服务器桥接图像上传和请求。

  3. 使用完全无模式的数据库,例如CouchDB,用于存储图像和元数据。此外,使用基于HTTP的RESTful API将其本身用于上传和交付。(附加问题:CouchDB通过Base64保存BLOB,但它是否能返回图像/ JPEG等形式的数据?)

11个回答

47
我们一直使用CouchDB,将图像保存为“附件”。但是一年后,多十几GB的CouchDB数据库文件成为一个头疼的问题。例如,如果你在非常大的文档大小下使用,CouchDB复制仍然有问题。
因此,我们重新编写了软件,使用CouchDB处理图像信息,Amazon S3用于实际的图像存储。该代码可在http://github.com/hudora/huImages上找到。
您可能希望为项目设置本地Amazon S3兼容的存储服务。这使您保持灵活性,并且不需要外部服务即可离开Amazon选项。 Walruss似乎成为最受欢迎和可扩展的S3克隆。
我还敦促您查看Livejournal的设计,以及其出色的开源MogileFSPerlbal 产品。这种组合可能是最著名的图像服务设置。
此外,flickr架构可能会给您带来启示,尽管他们不像Livejournal那样向公众提供开源软件。

请您详细阐述一下图像存储的实现方式,特别是授权部分。非常感兴趣。 - Eugeniu Torica
授权仅通过不可猜测的URL进行。 - max
我的意思是,一方面您必须将图像添加到图像存储中,并且该功能应该对需要进行身份验证的特定用户可用。另一方面,读取应该对每个人都可用,以便实际向用户显示图像。 - Eugeniu Torica
1
啊,我明白了。CouchDB 只能被我们内部服务器访问。他们都有完全的读写权限。更多关于上传权限的控制由 Web 应用程序处理。https://bitbucket.org/petrilli/django-storages/src/5cac7fceb0f8/backends/couchdb.py 是我们一直在使用的工具之一。 - max
对于那些寻找此问题替代方案的人,RiakCS现在已经开源,并提供S3兼容的API:http://basho.com/riak-cloud-storage/ - vdaubry

15

附加问题: CouchDB是否通过Base64保存blob。

CouchDB不会将blob保存为Base64,它们以纯二进制的形式存储。当使用?attachments=true检索带有JSON文档时,我们将磁盘上的二进制转换为Base64,以便安全地添加到JSON中,但这只是一种演示级别的东西。

参见Standalone Attachments

CouchDB按其存储的内容类型提供附件。实际上,将HTML、CSS和GIF/PNG/JPEG附件直接提供给浏览器是可能的、常见的做法。

附件可以流式传输,在CouchDB 1.1中,甚至支持范围标头(用于媒体流传输和/或恢复被中断的下载)。


1
在提问时,它们确实被存储为Base64。 - b_erb
7
CouchDB从未将附件存储为Base64格式。可能让你误解的是,CouchDB可以要求返回文档JSON格式的附件。为了实现这一点,需要将它们包装在Base64中。但实际上,在磁盘上,它们始终是真正的字节。 - Robert Newson
是的,我的评论有误导性。我指的不是底层存储机制,而是通过API访问附件的方式。 - b_erb

10

使用Seaweed-FS(曾称Weed-FS),这是Facebook的Haystack论文的一种实现。

Seaweed-FS非常灵活,只保留了基本功能。它被创建用于存储数十亿个图像,并快速地提供服务。


1
你好。我们有一台服务器,其中包含约3百万的缩略图。在高峰期,它每秒可以处理12,000个请求。一切都很正常,所以尝试使用weed-fs是一个好主意。 - fedor.belov

3
您考虑过使用亚马逊网络服务吗?S3是基于Web的文件存储,SimpleDB是一个键值对属性存储。两者都具有高性能和可扩展性。相比自己维护服务器和设置(假设您要自行完成而不是雇佣人员),它更昂贵,但可以更快地启动和运行。
编辑:撤回之前的说法 - 在高容量下,长期来看更昂贵,但在低容量下,它击败了购买硬件的初始成本。
S3:http://aws.amazon.com/s3/(您可以在这里存储图像文件,并为了提高性能,在您的服务器上建立图像缓存,或者不建立)
SimpleDB:http://aws.amazon.com/simpledb/(元数据可以放在这里:将图像ID映射到您想要存储的任何数据)
编辑2:我甚至不知道这个,但有一个新的Web服务叫做Amazon CloudFront(http://aws.amazon.com/cloudfront/)。它用于快速的Web内容交付,并与S3集成良好。就像Akamai一样,用于处理您的图像。您可以使用它来代替图像缓存。

谢谢您的想法,我已经考虑过了。然而,这是一个教育项目,我们不能使用外部服务,尤其是我们不能花钱购买它们。不幸的是,S3和SimpleDB对我们来说都不是选项。 - b_erb
哦,也许把那个放在问题里会更好。 - danben
由于您无法花费资金,那么您的硬件限制是什么? - danben
我们可以在内部获得所需的硬件数量,作为一堆虚拟化服务器。这也是一个概念验证项目,至少在开始阶段不使用来自外部的应用程序。然而,可扩展性问题是主要的项目影响之一,因此应该有远见地考虑。 - b_erb

3
我们使用MogileFS。我们是小规模用户,存储不到8TB和大约5000万个文件。几年前,我们从Amazon S3切换过来,以获得更好的文件名控制和性能。
虽然它不是最漂亮的软件,但它经过了很多“实地测试”,基本上所有用户都是以相同的方式使用它。

2
据我了解,MogileFS比分布式数据库更适合这个任务(在那里存储文件不是很自然的事情),也比例如HDFS更适合(适用于大文件,切片可以存储在不同的节点上,这对于MapReduce数据本地性非常有优势)。图像是不需要切片的小文件,而MogileFS看起来可以有效地处理这些文件,因为它是为此目的编写的(针对LiveJournal.com)。 - Alexey Tigarev

2

如果您的回答包含一些您链接到的信息,那将会很有用。特别是因为您链接到一个需要Facebook登录的文档,对我来说等于无法访问。 - Samuel Harmer

2
作为Cloudant的一部分,我不想推销产品...但是BigCouch解决了我的科学应用堆栈(物理学——与Cloudant无关,当然也与利润无关!)中的问题。它将CocuhDB设计的简单性与单服务器CouchDB缺失的自动分片和可伸缩性相结合。通常,我用它来存储较少数量的大文件(多GB)和大量小文件(100MB或更少)。我以前使用S3,但是对于反复访问的小文件,获取成本实际上开始累加。

你是否考虑在CouchDB之上使用HTTP缓存来缓存图像,例如Akamai或Varnish? - onejigtwojig
1
我曾经使用S3,但是对于那些需要反复访问的小文件,获取费用实际上开始累积起来。默认情况下,Amazon S3不会为图像设置缓存过期头,这本身可能会在账单中占据一定比例。你应该考虑自己设置它。 - user860672

1

好的,如果所有AWS的东西都行不通,这里有几个想法。

关于(3),如果你将二进制数据放入数据库中,同样的数据将会出现。使其成为jpeg的是数据的格式,而不是数据库认为它是什么。当你将Content-type头设置为image/jpeg时,客户端(Web浏览器)认为它是jpeg。你也可以将它设置为其他内容(不建议),比如文本,这就是浏览器尝试解释它的方式。

对于磁盘存储,我喜欢CouchDB的简单性,但HDFS肯定也可以。这里有一个链接,介绍了如何从CouchDB中提供图像内容:http://japhr.blogspot.com/2009/04/render-couchdb-images-via-sinatra.html

编辑:这里有一个有用的讨论链接,讨论了在Linux / Apache下将图像缓存到memcached与从磁盘提供它们之间的区别。


4
您说“这是一个有用讨论的链接...” 链接丢失了吗? - user860672

1

我一直在使用Python视图服务器中可用的CouchDB视图服务器_update功能进行实验。

我做的一个非常酷的事情是为图像上传编写了一个更新函数,以便我可以使用PIL创建缩略图和其他相关图像,并在它们被推送到CouchDB时将它们附加到文档上。

如果您需要图像处理并希望减少所需的代码和基础设施的数量,这可能会很有用。


1

我已经在cassandra之上编写了图像存储。我们有很多写入和随机读取,但读写比低。对于高读写比率,我建议您使用mongodb(GridFs)。


3
现在我有4 PB的数据,现在正在转移到Hadoop平台。 - baklarz2048
每个节点存储多少数据?你在压缩方面有问题吗(你说你的情况是大量写入)?修复效率如何? - odiszapc
@odiszapc 我不再使用Cassandra了。每个节点有500G到2T的存储容量。Cassandra满足可用性和“自动”扩展需求,但在一致性和容量规划方面存在很多问题。我在压缩、仅写入、极少更新读取的情况下没有遇到任何问题。 - baklarz2048
你说过你转向了Hadoop。Hadoop是MapR框架。你是指转向HDFS吗? - odiszapc
你曾经遇到故障转移的情况吗?HDFS如何处理故障转移? - odiszapc
显示剩余2条评论

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