MongoDB作为文件存储

时间:2013-02-22 18:09:10

标签: mongodb storage gridfs bigdata

我正在努力寻找为大文件创建可扩展存储的最佳解决方案。文件大小可以从1-2兆字节到500-600千兆字节不等。

我找到了一些关于Hadoop和它的HDFS的信息,但它看起来有点复杂,因为我不需要任何Map / Reduce作业和许多其他功能。现在我正在考虑使用MongoDB和它的GridFS作为文件存储解决方案。

现在的问题是:

  1. 当我尝试写几个文件时,gridfs会发生什么     同时。读/写操作会有锁定吗? (我将仅将其用作文件存储)
  2. 来自gridfs的文件是否会在ram中缓存,以及它将如何影响读写性能?
  3. 也许有一些其他解决方案可以更有效地解决我的问题?
  4. 感谢。

3 个答案:

答案 0 :(得分:17)

我只能在这里回答MongoDB,我不会假装我对HDFS和其他类似技术有太多了解。

GridFs实现完全是驱动程序本身的客户端。这意味着MongoDB本身没有特殊的加载或理解文件服务的上下文,实际上MongoDB本身甚至不理解它们是文件(http://docs.mongodb.org/manual/applications/gridfs/)。

这意味着查询fileschunks集合的任何部分将导致与任何其他查询相同的过程,从而将所需数据加载到您的工作集中( http://en.wikipedia.org/wiki/Working_set)表示MongoDB在给定时间范围内所需的一组数据(或当时所有加载的数据),以保持最佳性能。它通过将其分配到RAM(技术上操作系统)来实现这一点。

要考虑的另一点是这是驱动程序实现的。这意味着规范可能会有所不同,但我不认为这样做。所有驱动程序都允许您查询files集合中的一组文档,这些文档仅包含文件元数据,允许您稍后通过单个查询从chunks集合中提供文件本身。

然而,这不是重要的事情,你想要提供文件本身,包括其数据;这意味着您将files集合及其后续chunks集合加载到您的工作集中。

考虑到这一点,我们已经遇到了第一个障碍:

  

来自gridfs的文件是否会在ram中缓存以及它将如何影响读写性能?

小文件的读取性能可能非常棒,直接来自RAM;写作也一样好。

对于较大的文件,不是这样。大多数计算机都没有600 GB的RAM,实际上,在单个mongod实例上容纳单个文件的600 GB分区是很正常的。这会产生一个问题,因为为了提供服务,该文件需要适合您的工作集,但它不可能大于您的RAM;此时你可能有页面颠簸(http://en.wikipedia.org/wiki/Thrashing_%28computer_science%29),服务器只是试图加载文件的页面错误24/7。这里的写作也没有好转。

解决这个问题的唯一方法是开始在多个分片:\中放置一个文件。

注意:还需要考虑的另一件事是chunks“块”的默认平均大小是256KB,因此600GB文件的文档很多。此设置在大多数驱动程序中是可操作的。

  

当我尝试同时写几个文件时,gridfs会发生什么。读/写操作会有锁定吗? (我将仅将其用作文件存储)

GridFS,只是一个规范,使用与任何其他集合相同的锁,数据库级别(2.2+)或全局级别(2.2之前)的读写锁定。这两者确实相互干扰,即如何确保对正在写入的文档的一致读取?

据说存在争用的可能性取决于您的方案细节,流量,并发写入/读取的数量以及我们不知道的许多其他事项。

  

也许有一些其他解决方案可以更有效地解决我的问题?

我个人发现S3(如@mluggy所说)减少冗余格式最好在MongoDB中存储关于文件的元数据的一部分,就像使用GridFS但没有块集合一样,让S3处理所有的分发,备份和其他东西给你。

希望我很清楚,希望它有所帮助。

编辑:与我意外说的不同,MongoDB没有集合级锁,它是一个数据库级锁。

答案 1 :(得分:4)

我首先回答前两个问题:

  1. 写入GridFS时有写锁定,是的。没有锁定读取。
  2. 查询文件时,文件不会缓存在内存中,但是元数据会。
  3. GridFS可能不是解决您问题的最佳方案。当你处理这种情况时,写锁可能会变得很痛苦,特别是对于大文件。还有其他数据库可以为您解决此问题。 HDFS是一个不错的选择,但正如你所说,它非常复杂。我建议考虑像Riak或亚马逊的S3这样的存储机制。它们更倾向于存储文件,并且最终没有主要缺点。 S3和Riak都有出色的管理功能,可以处理大量文件。虽然最后我知道Riak,你必须做一些文件分块来存储超过100mb的文件。尽管如此,对于大文件大小进行某种程度的分块通常是最佳做法。将文件传输到DB时会发生很多不好的事情 - 从网络超时到缓冲区溢出等。无论哪种方式,您的解决方案都需要对大量文件大小进行大量调整。

答案 2 :(得分:4)

您是否考虑将元数据保存到MongoDB并将实际文件写入Amazon S3?两者都有出色的驱动程序,后者是高度冗余的云/ cdn就绪文件存储。我会试一试。