我正在努力寻找为大文件创建可扩展存储的最佳解决方案。文件大小可以从1-2兆字节到500-600千兆字节不等。
我找到了一些关于Hadoop和它的HDFS的信息,但它看起来有点复杂,因为我不需要任何Map / Reduce作业和许多其他功能。现在我正在考虑使用MongoDB和它的GridFS作为文件存储解决方案。
现在的问题是:
感谢。
答案 0 :(得分:17)
我只能在这里回答MongoDB,我不会假装我对HDFS和其他类似技术有太多了解。
GridFs实现完全是驱动程序本身的客户端。这意味着MongoDB本身没有特殊的加载或理解文件服务的上下文,实际上MongoDB本身甚至不理解它们是文件(http://docs.mongodb.org/manual/applications/gridfs/)。
这意味着查询files
或chunks
集合的任何部分将导致与任何其他查询相同的过程,从而将所需数据加载到您的工作集中( 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)
我首先回答前两个问题:
GridFS可能不是解决您问题的最佳方案。当你处理这种情况时,写锁可能会变得很痛苦,特别是对于大文件。还有其他数据库可以为您解决此问题。 HDFS是一个不错的选择,但正如你所说,它非常复杂。我建议考虑像Riak或亚马逊的S3这样的存储机制。它们更倾向于存储文件,并且最终没有主要缺点。 S3和Riak都有出色的管理功能,可以处理大量文件。虽然最后我知道Riak,你必须做一些文件分块来存储超过100mb的文件。尽管如此,对于大文件大小进行某种程度的分块通常是最佳做法。将文件传输到DB时会发生很多不好的事情 - 从网络超时到缓冲区溢出等。无论哪种方式,您的解决方案都需要对大量文件大小进行大量调整。
答案 2 :(得分:4)
您是否考虑将元数据保存到MongoDB并将实际文件写入Amazon S3?两者都有出色的驱动程序,后者是高度冗余的云/ cdn就绪文件存储。我会试一试。