【问题标题】:Why would I use a document store instead of regular file storage?为什么我要使用文档存储而不是常规文件存储?
【发布时间】:2014-10-25 20:12:57
【问题描述】:

我将构建一个 Web 服务,我将在其中存储大量图像和 PDF。为了存储它,我可以选择将文件存储为常规文件并将它们的文件名以及它们可能的标题、cmets 等记录在数据库中。另一方面,我也可以使用文档存储,例如 Cassandra或 MongDB。看到我没有使用文档存储的经验,我有点不确定为什么我会选择那个选项。

据我了解,文档存储的优势主要在于可扩展性和复制可能性,而使用简单文件的主要优势(至少对我而言)是其简单性。

您认为还有哪些其他原因不利于选择其他原因?欢迎所有提示!

【问题讨论】:

  • 如果您不确定这些好处,那么通常没有

标签: mongodb file cassandra nosql


【解决方案1】:

嗯,根据你的描述,我想到了一些事情:

我要存储相当多的图像和 PDF。

好的,假设每个用户要存储大约 10 MB,这实际上并不多。现在让我们假设您有 10000 个用户。这只是 100GB 的数据,没问题,您可以轻松地将其存储在文件系统中(这还有其他缺点,但稍后会详细介绍)。现在让我们假设您的应用程序很受欢迎,并且您的用户数增加了 10。现在我们有 1TB 的数据,即使在最大的磁盘上,我们也应该开始找到一种扩展方法,而对于 EBS,您已经达到了硬限制。您的扩展选项是设置集群文件系统,这并不容易管理,或者使用网络文件系统进行手动分区。现在,如果其中一台服务器出现故障会发生什么?自动故障转移?运气不好,您必须自己设置高可用性解决方案。易于设置冗余?运气也不好。两者结合?这不是一件容易的事,你真的需要知道你在做什么。

使用 MongoDB,横向扩展要容易得多(尽管正确地做到这一点并不容易)。如果您知道自己在做什么,则可以相当快地设置复制的分片集群。分片集群是分布在一个到数百甚至数千个节点上的存储,这实质上意味着读取和写入分布在集群上,并且集群共享它的资源,从而可以存储 PB 级的数据。由于集群中的一台机器在运行成百上千台机器时很可能出现故障,因此 MongoDB 提供了一种称为副本集的自动故障转移机制。因此,单个分片至少包含两个数据承载节点,当其中一个发生故障时,另一个会自动接管。

这是我在 MongoDB 中存储文件时看到的另一个优势:无论如何您都必须访问数据库,而且我没有看到询问数据库文件可能在哪里的意义,等待数据库响应然后当我可以首先将文件从数据库发回给我时,访问文件系统(在访问失败时进行所有必要的检查)以检索文件。

将元数据存储在数据库中并将文件存储在文件系统中的另一个但微妙的问题是,要保持元数据和实际文件之间的一致性要困难得多。毕竟,数据存储在两个未连接的系统中。

这是我要做的:如果文件大小超过 16MB(MongoDB 中 BSON 文档的限制),我会使用 MongoDB's GridFS 并存储对相应文件的引用单个文件的metadata 中的所有者。在某些情况下,将文件的引用存储在所有者文档中可能是合理的。

如果单个文件不会超过 16MB 的限制,您可以使用标准的 MongoDB 集合来存储文件。

如果您决定使用 MongoDB,一些建议:

  • 如果是商业项目,明智的做法是聘请一名 MongoDB DBA 至少一段时间。虽然 MongoDB 似乎非常简单,但仍有一些注意事项需要处理。由于这些通常取决于个人情况,因此我无法在此给出太多笼统的建议。
  • 尽早计划您的扩展策略。我建议您从具有单个分片的分片集群开始,如果您有可能突破硬件限制的话。
  • 总是 具有由具有至少 2 个数据承载节点和arbiter 的副本集组成的单个分片。 (根据经验:承载数据的节点越多越好。)否则,您没有自动故障转移,维护集群总是会导致停机或数据不可用。根据您的写入关注设置,如果您的分片不包含副本集并且目标分片已关闭,则数据甚至可能在写入操作期间静默丢失。再次重申:始终让集群的分片由副本集组成!

【讨论】:

  • 这是一个很棒的答案!感谢您的澄清。那我肯定会使用文档存储。我只需要在 MongoDB 和 Cassandra 之间做出决定。据我了解,MongoDB 更容易设置,而 Cassandra 在横向扩展时更快(planetcassandra.org/nosql-performance-benchmarks)。除了 MongoDB,你也有使用 Cassandra 的经验吗?
  • 那么请随意接受答案。 ;) 我没有使用 Cassandra 的经验。快速忽略,在第一个测试的测试设置中关于 mongodb 设置的测试设置中存在重大错误,选择未散列的默认 Id 字段作为分片键是性能杀手,因为在这种情况下发生的情况是所有写入操作都会进行到一个分片,集群的其余部分将只接收从该分片迁移的块,导致读取和写入性能不佳。我会更深入地研究这一点,但从我的角度来看,至少我不会太相信第一次比较。
  • 另外,测试有点老了,运行在现在已经过时的 mongodb 2.2.2 上。在 2.4 尤其是 2.6 中进行了重大的性能改进。其中一个版本重写了整个存储引擎(不记得是哪一个了),查询引擎从2.6版本开始重写。
猜你喜欢
  • 2019-12-23
  • 2011-04-10
  • 2019-11-17
  • 1970-01-01
  • 2012-11-20
  • 2011-02-03
  • 1970-01-01
  • 2011-03-23
  • 1970-01-01
相关资源
最近更新 更多