56

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

但是,我不确定如何在我的应用程序中实现这种可扩展的图像存储组件。我已经考虑过不同的解决方案,但由于缺少经验,我期待听到您的建议。除了图像,还必须保存元数据。以下是我的初步想法:

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

  2. 在 HDFS 之上使用 HBase 等面向 BigTable 的系统,并将图像和元数据一起保存。同样,网络服务器桥接图像上传和请求。

  3. 使用像 CouchDB 这样完全无模式的数据库来存储图像和元数据。此外,使用基于 HTTP 的 RESTful API 使用数据库本身进行上传和交付。(附加问题:CouchDB 确实通过 Base64 保存 blob。但是它能否以图像/jpeg 等形式返回数据)?

4

11 回答 11

46

为此,我们一直在使用 CouchDB,将图像保存为“附件”。但一年后,数十个 GB CouchDB 数据库文件变得令人头疼。例如,如果您将 CouchDB 复制用于非常大的文档大小,它仍然存在问题。

所以我们只是重写了我们的软件,使用 CouchDB 存储图像信息,使用 Amazon S3 存储实际图像。该代码可在http://github.com/hudora/huImages获得

您可能希望为您的项目现场设置与 Amazon S3 兼容的存储服务。这使您保持灵活性,并且暂时无需外部服务即可离开亚马逊选项。Walruss似乎成为最流行和可扩展的 S3 克隆。

我还敦促您研究 Livejournal 的设计及其出色的开源MogileFSPerlbal产品。这种组合可能是最著名的图像服务设置。

flickr 架构也可以成为一种灵感,尽管他们不像 Livejournal 那样向公众提供开源软件。

于 2009-12-26T22:39:29.793 回答
14

“附加问题:CouchDB 确实通过 Base64 保存 blob。”

CouchDB 不会blob 保存为 Base64,它们存储为直接二进制文件。在检索 JSON 文档时,?attachments=true我们确实将磁盘上的二进制文件转换为 Base64,以便将其安全地添加到 JSON 中,但这只是表示级别的事情。

请参阅独立附件

CouchDB 使用它们存储的内容类型来提供附件,实际上很常见的是,将 HTML、CSS 和 GIF/PNG/JPEG 附件直接提供给浏览器。

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

于 2011-06-07T09:10:13.463 回答
9

使用Seaweed-FS(以前称为 Weed-FS),这是 Facebook 的 haystack paper 的实现。

Seaweed-FS 非常灵活并且精简到基础。它的创建是为了存储数十亿张图像并快速提供服务。

于 2012-06-17T08:05:06.423 回答
3

你考虑过亚马逊网络服务吗?S3是基于web的文件存储,SimpleDB是key->attribute store。两者都是高性能和高度可扩展的。它比维护自己的服务器和设置更昂贵(假设您要自己做而不是雇用人员),但是您可以更快地启动和运行。

编辑:我收回了这一点——从长远来看,大批量生产的成本更高,但对于小批量生产,它超过了购买硬件的初始成本。

S3:http ://aws.amazon.com/s3/ (您可以将图像文件存储在这里,为了提高性能,您的服务器上可能有图像缓存,也可能没有)

SimpleDB:http ://aws.amazon.com/simpledb/ (元数据可以在这里:图像 id 映射到您想要存储的任何数据)

编辑 2:我什至不知道这一点,但有一个名为 Amazon CloudFront ( http://aws.amazon.com/cloudfront/ ) 的新 Web 服务。它用于快速 Web 内容交付,并且与 S3 很好地集成。有点像 Akamai 的图像。您可以使用它来代替图像缓存。

于 2009-12-25T13:58:02.497 回答
3

我们使用 MogileFS。我们是少于 8TB 和大约 5000 万个文件的小规模用户。几年前,我们从存储在 Amazon S3 中转为更好地控制文件名和性能。

它不是最漂亮的软件,但它经过了非常“现场测试”,基本上所有用户都以与您相同的方式使用它。

于 2010-09-29T06:29:53.267 回答
2

也许看看 Facebook hayStack 的描述

大海捞针:高效存储数十亿张照片

于 2010-01-14T15:22:15.717 回答
2

作为 Cloudant 的一部分,我不想推销产品……但是 BigCouch 在我的科学应用程序堆栈中解决了这个问题(物理学——与 Cloudant 无关,当然也与利润无关!)。它将 CocuhDB 设计的简单性与单服务器 CouchDB 中缺少的自动分片和可扩展性结合在一起。我一般用它来存储少量的大文件(多 GB)和大量的小文件(100MB 或更少)。我使用的是 S3,但对于重复访问的小文件,获取成本实际上开始增加。

于 2011-03-07T18:49:03.247 回答
1

好的,如果所有 AWS 的东西都不起作用,这里有几个想法。

至于(3),如果你把二进制数据放入数据库,同样的数据会出来。使它成为 jpeg 的是数据的格式,而不是数据库认为的格式。当您将Content-type标头设置为image/jpeg. 您也可以将其设置为其他内容(不推荐),例如文本,这就是浏览器尝试解释它的方式。

对于磁盘存储,我喜欢 CouchDB 的简单性,但 HDFS 肯定可以。这是关于从 CouchDB 提供图像内容的帖子的链接:http: //japhr.blogspot.com/2009/04/render-couchdb-images-via-sinatra.html

编辑:这里有一个有用的讨论链接,该讨论关于在 memcached 中缓存图像与从 linux/apache 下的磁盘提供图像。

于 2009-12-25T14:20:00.627 回答
1

我一直在试验我的 Python 视图服务器中 CouchDB 视图服务器可用的一些 _update 功能。

我做的一件很酷的事情是图像上传的更新功能,这样我就可以使用 PIL 创建缩略图和其他相关图像,并在它们被推送到 CouchDB 时将它们附加到文档中。

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

于 2009-12-27T20:07:37.303 回答
1

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

于 2010-09-29T06:18:51.363 回答
0

这是一个使用 PHP Laravel 在 CouchDB 中存储 blob 图像的示例。在此示例中,我根据用户要求存储了三个图像。

在 CouchDB 中建立连接。

$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);

...

就像您可以存储单个图像一样。

于 2016-11-30T05:41:22.920 回答