2013-02-22 97 views
17

我试图找到最好的解决方案来为大文件创建可伸缩存储。文件大小可以从1-2兆字节到500-600千兆字节不等。MongoDB作为文件存储

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

而现在的问题:

  1. 将GridFS的发生什么,当我尝试写一些文件 兼任。读/写操作是否会有锁定? (我将只用它作为文件存储)
  2. 将gridfs中的文件缓存在ram中,以及它如何影响读写性能?
  3. 也许还有一些解决方案可以更有效地解决我的问题?

谢谢。

回答

15

我只能在这里回答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;写入会一样好。

对于大文件,并非如此。大多数计算机不会有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没有集合级别锁定,它是一个数据库级别锁定。

+0

我_think_全局锁定已更改? (https://blog.serverdensity.com/goodbye-global-lock-mongodb-2-0-vs-2-2/) – Jeff 2014-04-07 23:27:27

+1

@Jeff这是一个旧的答案,我可以更新它,如果人们仍在使用它? – Sammaye 2014-04-08 07:08:07

+0

@Jeff哦,挂了,我其实说数据库级锁,我在哪里说全球? – Sammaye 2014-04-08 07:08:53

3

我会回答前两个开始:

  1. 到GridFS的写入时,有一个写锁,是的。读取没有锁定。
  2. 当你查询文件时,文件不会被缓存在内存中,但它们的元数据将会被缓存。

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

+0

如果计算机内存足够大,可以根据OS LRU将文件缓存在内存中,以便从这些工作集中读取数据。 – Sammaye 2013-02-22 19:36:18

+0

Chris,谢谢你的回答。几乎没有关于HDFS的问题。在这个分布式文件系统中是否存在读/写锁,可能和GridFS中的锁一样痛苦?而NameNode的限制又是什么(只有一个或多个instaces)。也许我会试着用它来试验 – cmd 2013-02-22 20:39:00

+0

@Sammaye“工作集”相当于索引。在GridFS上它只加载,而不是所有的文件。如果这样做,它将是无用的。 – 2013-02-23 00:18:26

3

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

+1

Concur和S3的含义。我看到这个Google网上论坛组发布了https://groups.google.com/forum/?fromgroups=#!topic/mongoose-orm/G85Q2QaA1QI,探索了GridFS,然后回到了这个观点。 – prototype 2013-02-23 02:23:07