2012-10-15 90 views
2

我正在做一些測試,看看我們是否可以在MongoDB上使用GridFS來存儲未來應用程序的文件;我使用10gen的C#驅動程序將80Mb文件「上傳」到數據庫中。MongoDB GridFS文件大小相對較小的文件

第一個加法很好,花了大約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是否將整個GridFS持續保存在RAM中?如果是這樣的話,磁盤有什麼意義?如果我的生產服務器上只有32GB內存,我只能在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) 

回答

5

好的;經過大量搜索,看起來MongoDB似乎預先在指數大小的文件中分配高達2Gb的空間,之後每個文件將爲2G。

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

我的測試程序增加了80MB的文件,背景文件中(0.0 - 0.7等)和數據塊開始被寫入最後一個文件蒙戈預先分配的另一個文件呈指數比大持續。

因此,第一個80Mb文件填滿了16Mb文件,32Mb文件和64Mb背景文件,由於元數據需要更多的空間,並且必須侵入128Mb文件,這會觸發mongo預先分配256Mb文件共計496Mb;隨着更多的文件被添加,更多的文件被預先分配,當2Gb在我的測試機器上被擊中時,Mongo無法訪問該空間並崩潰。

所以儘管看起來80Mb的文件佔用了比應該多得多的空間 - 這是一種迂迴的方式。

可以通過使用--noprealloc運行mongod來關閉此功能,儘管這僅建議用於測試機器。

感謝您的回覆!

0

GridFS的不所有文件只保存在RAM中。

你有堆棧跟蹤還是可以再次重現崩潰?

+0

我編輯了我的原始問題以包含堆棧跟蹤。謝謝。 – Dale

+0

問題是,在32位系統中,您無法分配2GB以上的文件。 '--smallfiles'將數據文件限制爲500MB,因此應該有所幫助。 雖然不建議在32位系統中運行MongoDB。 更多的信息在這裏http://www.mongodb.org/display/DOCS/32+bit –

+0

32位版本只是在我的測試機器上;我在我們的服務器上運行64位版本,但是我使用的單個文件只有80Mb,遠不及2Gb,所以我不知道爲什麼Mongo似乎無法處理它們。 – Dale