可扩展的图像存储
我目前正在devise一个基于networking的应用程序的体系结构,也应该提供某种forms的图像存储。 用户将能够上传照片作为服务的关键function之一。 同时查看这些图像将成为主要用途之一(通过networking)。
但是,我不知道如何在我的应用程序中实现这样一个可伸缩的图像存储组件。 我已经想过不同的解决scheme,但由于缺less经验,我期待听到您的build议。 除了图像,还必须保存元数据。 这是我最初的想法:
-
使用(分布式)文件系统,如HDFS,并准备专门的Web服务器作为“文件系统客户端”,以保存上传的图像和服务请求。 图像元数据保存在附加数据库中,包括每个图像的文件path信息。
-
在HDFS之上使用HBase等面向BigTable的系统,并将图像和元数据保存在一起。 再次,networking服务器桥接图片上传和请求。
-
使用像CouchDB这样的完全无模式数据库来存储图像和元数据。 另外,通过使用基于HTTP的RESTful API,使用数据库本身来进行上传和发布。 (另外的问题:CouchDB确实通过Base64保存斑点,但是它能以image / jpeg等forms返回数据)?
我们一直在使用CouchDB,将图像保存为“附件”。 但是一年之后,数十个GB的CouchDB数据库文件变得令人头疼。 例如,如果您使用非常大的文档大小,CouchDB复制仍然有问题。
所以我们只是重写了我们的软件,使用CouchDB的图像信息和亚马逊S3的实际图像存储。 该代码可在http://github.com/hudora/huImages上获得;
您可能需要在现场为您的项目设置Amazon S3兼容的存储服务。 这使您保持灵活性,离开亚马逊的select,而不需要现在的外部服务。 Walruss似乎成为最受欢迎和可扩展的S3克隆。
我也敦促你用他们优秀的开源MogileFS和Perlbal产品来研究Livejournal的devise 。 这个组合可能是最着名的图像服务设置。
另外flickr架构可以是一个灵感,虽然他们不提供开源软件,像Livejournal一样。
“另外的问题:CouchDB确实通过Base64保存了斑点。”
CouchDB不会将Blob保存为Base64,它们以直接二进制forms存储。 当使用?attachments=true
检索JSON文档时,我们将磁盘上的二进制文件转换为Base64,以便将其安全地添加到JSON中,但这只是一个表示层次的东西。
请参阅独立附件 。
CouchDB为附件提供存储的内容types,事实上通常可以将HTML,CSS和GIF / PNG / JPEG附件直接提供给浏览器。
附件可以stream式传输,并且在CouchDB 1.1中甚至支持Range头(用于媒体stream和/或恢复被中断的下载)。
使用海草FS (以前称为Weed-FS),Facebook的干草堆纸的实施。
海藻-FS是非常灵活的,削减到基本。 它被创build用于存储数十亿的图像并快速提供服务。
你考虑过amazon web services吗? S3是基于Web的文件存储,SimpleDB是一个key->属性存储。 两者都是高性能和高度可扩展的。 这比维护你自己的服务器和设置要贵(假设你自己做,而不是雇用人),但是你的启动和运行要快得多。
编辑:我收回 – 从长远来看,它的成本较高,但是成本较低,这比购买硬件的初始成本要高。
S3: http : //aws.amazon.com/s3/ (你可以在这里存储你的图像文件,为了提高性能,你的服务器上可能有一个图像caching,或者可能没有)
SimpleDB: http : //aws.amazon.com/simpledb/ (元数据可以在这里:图像ID映射到任何你想存储的数据)
编辑2:我甚至不知道这个,但有一个名为Amazon CloudFront的新Web服务( http://aws.amazon.com/cloudfront/ )。 这是为了快速的网页内容交付,并与S3集成得很好。 有点像你的图像Akamai。 你可以使用这个而不是图像caching。
我们使用MogileFS。 我们是小于8TB,大约5000万个文件的小型用户。 几年前,我们从存储在Amazon S3中进行转换,以更好地控制文件名和性能。
这不是最漂亮的软件,但它是非常“现场testing”,基本上所有的用户都在使用它,就像你将会。
也许看看Facebook hayStack的描述
大海捞针:高效存储数十亿张照片
作为Cloudant的一部分,我不想推出产品….但是BigCouch在我的科学应用程序堆栈中解决了这个问题(物理 – 与Cloudant无关,当然与利润无关)。 它将CocuhDBdevise的简单性与单服务器CouchDB中缺less的自动分片和可伸缩性结合在一起。 我通常用它来存储较小数量的大文件(多GB)和大量小文件(100MB或更less)。 我正在使用S3,但实际上开始增加了重复访问的小文件。
好吧,如果所有AWS的东西都不起作用,这里有几个想法。
就(3)而言,如果将二进制数据放入数据库中,则会出现相同的数据。 什么使得它是一个JPEG格式的数据,而不是数据库认为它是。 什么使客户端(networking浏览器)认为它是一个JPEG文件是当你的Content-type
头设置为image/jpeg
。 您也可以将其设置为其他(不推荐),如文本,这是浏览器将如何解释它。
对于磁盘存储,我很喜欢CouchDB,但是HDFS肯定会起作用。 以下是关于从CouchDB提供图片内容的文章的链接: http : //japhr.blogspot.com/2009/04/render-couchdb-images-via-sinatra.html
编辑:这里有一个关于cachingmemcached中的图像与linux / apache下的磁盘服务的有用讨论的链接。
我一直在尝试在我的Python视图服务器中为CouchDB视图服务器提供的一些_updatefunction。
我做的一个很酷的事情是图像上传的更新function,以便我可以使用PIL创build缩略图和其他相关图像,并将它们附加到文档,当它们被推送到CouchDB。
如果您需要image processing,并希望减less需要跟上的代码和基础架构数量,这可能会非常有用。
我已经在cassandra上写下了图像存储。 我们有很多,写和随机读取读/写低。 对于高读/写比,我build议你mongodb(GridFs)。
以下是使用PHP Laravel在CouchDB中存储Blob映像的示例。 在这个例子中,我根据用户需求存储了三张图片。
在CouchDB中build立连接。
$connection = DB::connection('your database name'); /*region Fetching the Uers Uploaded Images*/ $FirstImage = base64_encode(file_get_contents(Input::file('FirstImageInput'))); $SecondImage =base64_encode(file_get_contents(Input::file('SecondImageInput'))); $ThirdImage = base64_encode(file_get_contents(Input::file('ThirdImageInput'))); list($id, $rev) = $connection->putDocument(array( 'name' => $name, 'location' => $location, 'phone' => $phone, 'website' => $website, "_attachments" =>[ 'FirstImage.png' => [ 'content_type' => "image/png", 'data' => $FirstImage ], 'SecondImage.png' => [ 'content_type' => "image/png", 'data' => $SecondImage ], 'ThirdImage.png' => [ 'content_type' => "image/png", 'data' => $ThirdImage ] ], ), $id, $rev); ...
同样可以存储单个图像。