MongoDB GridFS文件大小适用于相对较小的文件

时间:2012-10-15 11:20:44

标签: mongodb storage gridfs filesize

我正在做一些测试,看看我们是否可以在MongoDB上使用GridFS来存储未来应用程序的文件;我正在使用10gen的C#驱动程序将80Mb文件“上传”到数据库中。

第一次添加很好,花了大约3秒钟,这在我的测试机上并不算太糟糕;然而,未来相同文件的添加需要更长时间,最多30秒,MongoDB最终告诉我内存耗尽并崩溃。

添加10个文件,大小为80Mb,导致在我的数据库中创建8个文件,然后系统崩溃名为dbaseName.0到dbaseName.7,文件大小从16Mb到512Mb从文件0到5呈指数增长,然后是文件6和7都是512Mb。

这些文件低于2Gb,显然第10次添加文件需要dbase超过2Gb,这超出了我的32位测试版本的限制。

为什么存储800Mb的文件会占用2Gb?有没有我错过的地方?

MongoDB是否经常在RAM中保存整个GridFS?如果是这样的话,磁盘有什么意义呢?如果我的生产服务器上只有32Gb的RAM,那么我只能在GridFS中存储32Gb吗?

我在MongoGridFS对象上使用了EnsureIndexes,并检查了显示为GridFS创建索引的数据库,所以Mongo不应该尝试将整个数据存储区放入RAM中吗?

MongoDB满足了我们的所有需求,但我们需要它能够容纳大型文件集;我错过了一些明显的东西吗?

堆栈追踪:

Mon Oct 15 11:57:15 [conn15] insert busyNow.fs.chunks keyUpdates:0 locks(micros) w:112892 113ms
Mon Oct 15 11:57:15 [conn15] MapViewOfFileEx for /data/db/busyNow.7 failed with errno:8 Not enough storage is available to process this command. (file size is 536608768) in MemoryMappedFile::map

Mon Oct 15 11:57:15 [conn15]  busyNow.fs.chunks Fatal Assertion 16166
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\util\assert_util.cpp(124)                               mongo::fassertFailed+0x75
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\util\mmap_win.cpp(211)                                  mongo::MemoryMappedFile::map+0x4ce
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\mongommf.cpp(182)                                    mongo::MongoMMF::create+0xa3
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\pdfile.cpp(469)                                      mongo::MongoDataFile::open+0x141
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\database.cpp(280)                                    mongo::Database::getFile+0x34f
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\database.cpp(332)                                    mongo::Database::suitableFile+0x129
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\database.cpp(359)                                    mongo::Database::allocExtent+0x41
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\pdfile.cpp(1271)                                     mongo::outOfSpace+0x107
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\pdfile.cpp(1293)                                     mongo::allocateSpaceForANewRecord+0x5d
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\pdfile.cpp(1463)                                     mongo::DataFileMgr::insert+0x493
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\pdfile.cpp(1217)                                     mongo::DataFileMgr::insertWithObjMod+0x33
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\instance.cpp(761)                                    mongo::checkAndInsert+0x72
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\instance.cpp(821)                                    mongo::receivedInsert+0x4cd
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\instance.cpp(434)                                    mongo::assembleResponse+0x62a
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\db\db.cpp(192)                                          mongo::MyMessageHandler::process+0xe8
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\mongo\util\net\message_server_port.cpp(86)                    mongo::pms::threadRun+0x424
Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\third_party\boost\boost\thread\detail\thread.hpp(62)          boost::detail::thread_data<boost::_bi::bind_t<void,void (__cdecl*)(mongo::MessagingPort *),boost::_bi::list1<boost::_bi::value<mongo::MessagingPort *
> > > >::run+0x9Mon Oct 15 11:57:17 [conn15] mongod.exe  ...\src\third_party\boost\libs\thread\src\win32\thread.cpp(16707566)  boost::`anonymous namespace'::thread_start_function+0x47
Mon Oct 15 11:57:17 [conn15] mongod.exe  f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c(314)                _callthreadstartex+0x1b
Mon Oct 15 11:57:17 [conn15] mongod.exe  f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c(292)                _threadstartex+0x64
Mon Oct 15 11:57:17 [conn15]

***aborting after fassert() failure


Mon Oct 15 11:58:33 [initandlisten] connection accepted from 127.0.0.1:56308 #16 (3 connections now open)

2 个答案:

答案 0 :(得分:5)

确定;经过大量搜索后,似乎MongoDB在指数大小的文件中预先分配空间,最多2Gb,之后每个文件将为2G。

http://www.mongodb.org/display/DOCS/Excessive+Disk+Space

我的测试程序在后台文件(.0 - .7等)中添加80Mb文件,并且当数据块开始写入最后一个文件时,Mongo预分配另一个指数大于上一个文件的文件。

所以第一个80Mb文件,填满了16Mb文件,32Mb文件和64Mb后台文件,并且由于元数据占用了更多空间并且必须稍微侵入128Mb文件,这会触发mongo预分配256Mb文件总计496Mb;随着更多文件的添加,预先分配了更多文件,当我的测试机器上出现2Gb时,Mongo无法访问该空间并崩溃。

因此,虽然看起来一个80Mb的文件占用的空间比它应该多得多 - 但它以迂回的方式有意义。

使用--noprealloc运行mongod可以关闭此功能,但建议仅用于测试机器。

感谢您的回复!

答案 1 :(得分:0)

GridFS不会仅将所有文件存储在RAM中。

你有堆栈跟踪还是可以再次重现崩溃?