代码之家  ›  专栏  ›  技术社区  ›  b_erb

可扩展的图像存储

  •  52
  • b_erb  · 技术社区  · 14 年前

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

    但是,我不知道如何在我的应用程序中实现这样一个可伸缩的图像存储组件。我已经考虑过不同的解决方案,但是由于经验的缺失,我很期待听到你的建议。除了图像之外,还必须保存元数据。 以下是我的初步想法:

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

    2. 在hdfs上使用类似hbase的面向大表的系统,并将图像和元数据一起保存。同样,WebServer桥接图像上载和请求。

    3. 使用像couchdb这样完全无模式的数据库来存储图像和元数据。另外,通过使用基于HTTP的RESTfulAPI,使用数据库本身进行上传和传递。(附加问题:CouchDB通过base64保存blob。但是,它能以图像/jpeg等形式返回数据吗?

    11 回复  |  直到 7 年前
        1
  •  42
  •   Jonathan Hall    8 年前

    为此,我们一直在使用CouchDB,将图像保存为“附件”。但一年之后,数十个GB的CouchDB数据库文件却成了一个头痛的问题。例如,如果将couchdb复制用于非常大的文档大小,那么它仍然存在问题。

    所以我们重新编写了我们的软件,用couchdb来存储图像信息,用AmazonS3来存储实际的图像。代码可在 http://github.com/hudora/huImages

    您可能需要为您的项目在现场设置与AmazonS3兼容的存储服务。这使您保持了灵活性,现在不需要外部服务就可以选择Amazon。 Walruss 似乎成为最流行和可扩展的S3克隆。

    我还敦促您研究LiveJournal的设计及其优秀的开放源代码。 MogileFS Perlbal 供品。 This combination 可能是最著名的图像服务设置。

    flickr Architecture 虽然他们不像LiveJournal那样向公众提供开源软件,但这可能是一种启发。

        2
  •  13
  •   Jonathan Hall    8 年前

    “其他问题:CouchDB确实通过base64保存了blob。”

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

    参见 Standalone Attachments .

    couchdb提供与存储内容类型相同的附件,实际上很常见,可以将HTML、CSS和GIF/PNG/JPEG附件直接服务器到浏览器。

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

        3
  •  8
  •   chrislusf    8 年前

    使用 Seaweed-FS (曾被称为weed fs),是Facebook Haystack Paper的一个实现。

    海藻是非常灵活和削减到基本。它是为了存储数十亿图像并快速提供服务而创建的。

        4
  •  3
  •   danben    14 年前

    你考虑过亚马逊网络服务吗?S3是基于Web的文件存储,simpleDB是一个key->属性存储。两者都具有良好的性能和高度的可扩展性。它比维护您自己的服务器和设置(假设您要自己做,而不是雇佣人员)更昂贵,但是您的启动和运行速度更快。

    编辑:我收回它——从长远来看,它在高容量下更昂贵,但在低容量下,它超过了购买硬件的初始成本。

    S3: http://aws.amazon.com/s3/ (您可以将图像文件存储在这里,出于性能考虑,可能在服务器上有一个图像缓存,或者没有)

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

    编辑2:我甚至不知道这一点,但是有一个新的网络服务叫做AmazonCloudFront( http://aws.amazon.com/cloudfront/ )它用于快速的Web内容交付,并且与S3很好地集成。就你的图片而言,有点像Akamai。您可以使用这个来代替图像缓存。

        5
  •  3
  •   Ask Bjørn Hansen    14 年前

    我们使用Mogilefs。我们是小规模用户,容量不足8TB,文件数量约为5000万。几年前,为了更好地控制文件名和性能,我们从在AmazonS3中存储转向了存储。

    它不是最漂亮的软件,但它是非常“现场测试”的,基本上所有用户使用它的方式都和你一样。

        6
  •  3
  •   aehlke    11 年前

    也许可以看看Facebook Haystack的描述

    Needle in a haystack: efficient storage of billions of photos

        7
  •  2
  •   Mike Miller    13 年前

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

        8
  •  1
  •   danben    14 年前

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

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

    对于磁盘存储,我喜欢CouchDB的简单性,但HDF当然可以工作。这里有一个链接,指向一篇关于从CouchDB提供图像内容的文章: http://japhr.blogspot.com/2009/04/render-couchdb-images-via-sinatra.html

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

        9
  •  1
  •   mikeal    14 年前

    我一直在尝试在我的python视图服务器中提供给couchdb视图服务器的一些更新功能。

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

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

        10
  •  1
  •   baklarz2048    14 年前

    我在卡桑德拉的顶上写了一个形象商店。我们有很多,写和随机读/写都很低。对于高读写比,我建议您使用mongodb(gridfs)。

        11
  •  -1
  •   Pang Mohammad Imran    7 年前

    下面是一个使用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);
    
    ...
    

    与您可以存储单个图像相同。