blob - Web 应用程序的对象存储

标签 blob gridfs object-storage glusterfs distributed-filesystem

我目前正在一个网站上工作,应该向其用户提供大约 4000 万份文档和图像。我需要关于哪种方法最适合存储符合这些要求的内容的建议。

  • 系统应该具有高可用性、可扩展性和耐用性。
  • 文件必须永久存储,用户应该能够修改它们。
  • 由于客户端限制,不适合使用 Amazon S3 和 CDN 等 3rd 方对象存储提供商。
  • 内容的文件大小可以从 1 MB 到 30 MB 不等。 (但是,大约 90% 的文件小于 2 MB)
  • 内容检索延迟不是什么大问题。因此索引或缓存不是很重要。

  • 我做了一些研究,发现了以下解决方案;
  • 将内容作为 BLOB 存储在数据库中。
  • 使用 GridFS 对内容进行分块和存储。
  • 使用哈希将文件服务器中的内容存储在目录中,并将元数据存储在数据库中。
  • 使用分布式文件系统(例如 GlusterFS 或 HDFS)并将文件元数据存储在数据库中。

  • 该网站是使用 PHP 开发的,并使用 Couchbase 社区版作为数据库。

    我真的很感激任何输入。

    谢谢你。

    最佳答案

    过去两年我一直在研究类似的系统,工作仍在进行中。但是,要求与您的略有不同:无法修改(我将在稍后解释原因),文件大小范围从几个字节到几兆字节,最重要的是重复数据删除,这两个都应该实现在文档和块级别。如果两个不同的用户将同一文件上传到存储,则应保留该文件的唯一副本。此外,如果两个不同的文件彼此部分交叉,则有必要存储这些文件的公共(public)部分的唯一副本。

    但是让我们专注于您的需求,因此重复数据删除并非如此。首先,高可用意味着复制 .您必须将文件存储在独立机器上的多个副本(通常为 2 或 3 个,但有一些技术可以减少数据奇偶校验)中,以便在后端的其中一台存储服务器死机时保持事件状态。此外,考虑到数据量的估计,很明显,您的所有数据都无法放入单个服务器中,因此垂直扩展是不可能的,您必须考虑 分区 .最后,你需要考虑并发控制当两个不同的客户端尝试同时写入或更新相同的数据时,以避免出现竞争条件。这个话题接近的概念交易 (我的意思不是字面上的酸,而是接近的意思)。因此,总而言之,这些事实意味着您实际上正在寻找旨在存储 BLOB 的分布式数据库。

    分布式系统中最大的问题之一是系统全局状态的困难。简而言之,有两种方法:

  • 选择将与其他对等方通信并维护分布式系统全局状态的领导者。这种方法提供了强一致性线性化 保证。主要的缺点是在这种情况下领导者成为单点故障。如果领导者死了,某个观察者必须将领导者角色分配给其中一个副本(在 RDBMS 世界中 master-slave 复制的常见情况),或者剩余的对等节点需要选举新的(像 PaxosRaft 之类的算法旨在针对这个问题)。无论如何,几乎所有传入的系统流量都经过领导者。这导致了后端的“热点”:CPU 和 IO 成本在整个系统中分布不均的情况。顺便说一句,Raft基于系统的写入吞吐量非常低(如果您有兴趣,请查看 etcdconsul 限制)。
  • 完全避免全局状态。弱化保证到最终一致性 .禁用文件更新。如果有人要编辑该文件,则需要将其另存为新文件。使用组织为对等网络的系统。集群中没有对等点来保持系统的完整跟踪,因此不存在单点故障。这导致高写入吞吐量和良好的水平可扩展性。

  • 所以现在让我们讨论您找到的选项:

    Storing content as BLOBs in databases.



    我认为将文件存储在传统 RDBMS 中不是一个好的选择,因为它们为结构化数据和强一致性提供了优化,而您不需要这两者。此外,您在备份和扩展方面也会遇到困难。人们通常不会以这种方式使用 RDBMS。

    Using GridFS to chunk and store content.



    我不确定,但看起来 GridFS 是建立在 MongoDB 之上的。同样,这是面向文档的数据库,旨在存储 JSON,而不是 BLOB。 MongoDB 的集群问题也有很多年了。 MongoDB passed Jepsen 仅在 2017 年进行测试。这可能意味着 MongoDB 集群尚未成熟。如果您这样做,请进行性能和压力测试。

    Storing content in a file server in directories using a hash and storing the metadata in a database.



    这个选项意味着你需要自己开发对象存储。考虑我上面提到的所有问题。

    Using a distributed file system such as GlusterFS or HDFS and storing the file metadata in a database.



    我没有使用这些解决方案,但 HDFS 看起来有点矫枉过正,因为你依赖于 Hadoop 堆栈。不知道 GlusterFS 的性能。始终考虑分布式文件系统的设计。如果他们有某种专用的“元数据”服务,请将其视为单点故障。

    最后,我对可能适合您需求的解决方案的想法:
  • Elliptics .这种对象存储在俄语部分以外的互联网并不为人所知,但它成熟稳定,性能完美。它由 Yandex(俄罗斯搜索引擎)开发,许多 Yandex 服务(如磁盘、邮件、音乐、图片托管等)都建立在它之上。我在之前的项目中使用过它,这可能需要您的操作人员花费一些时间才能使用它,但是如果您对 GPL 没问题,那么这是值得的。执照。
  • Ceph .这是真正的对象存储。也是开源的,不过好像只有Red Hat人们知道如何部署和维护它。所以准备好供应商锁定。我也听说它的设置太复杂了。从未在生产中使用过,所以不知道性能。
  • Minio .这是 S3 兼容的对象存储,目前正在积极开发中。从未在生产中使用它,但它似乎设计得很好。

  • 您也可以查看 wiki包含可用解决方案完整列表的页面。

    最后一点:我强烈建议不要使用 OpenStack Swift(原因有很多,但首先,Python 不适合这些用途)。

    关于blob - Web 应用程序的对象存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53061611/

    相关文章:

    C#:作为字节数组下载后文件损坏

    mysql - 包含加密数据的 BLOB 上的索引

    Node.js 通过 REST API 发送图像

    azure - 在 Azure 中使用时间戳访问 blob 文件

    node.js - 从 Gridfs 读取 block 并转换为缓冲区

    java - Mongo 将 Document 转换为 DBObject

    amazon-s3 - 对象存储有哪些用例?

    ibm-cloud - IBM Cloud Object Storage - 它是否支持对象版本控制以及如何获取 UUID?

    java - 文件处理使用struts2 + hibernate3 + MySql