【问题标题】:MongoDB GridFS File Sizes huge for relatively small fileMongoDB GridFS 文件大小对于相对较小的文件来说很大
【发布时间】:2012-10-05 08:42:52
【问题描述】:

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

第一次添加很好,大约花了 3 秒,这在我的测试机器上还算不错;但是,以后添加同一个文件需要更长的时间,最多 30 秒,最终 MongoDB 告诉我它内存不足并崩溃了。

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

这些文件不到 2Gb,显然第 10 次添加文件会使 dbase 超过 2Gb,这超出了我的 32 位测试版本的限制。

为什么存储 800Mb 的文件会占用 2Gb?有没有我遗漏的设置?

MongoDB 是否经常将整个 GridFS 保存在 RAM 中?如果是这样,磁盘的意义何在?如果我的生产服务器上只有 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)

【问题讨论】:

    标签: mongodb storage gridfs filesize


    【解决方案1】:

    GridFS 并不只将所有文件存储在 RAM 中。

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

    【讨论】:

    • 我已经编辑了我的原始问题以包含堆栈跟踪。谢谢。
    • 问题是在 32 位系统中你不能分配超过 2GB 的文件。 --smallfiles 将数据文件限制为 500mb,这样应该会有所帮助。虽然不建议在 32 位系统中运行 MongoDB。更多信息在这里mongodb.org/display/DOCS/32+bit
    • 32位版本简直就是在我的测试机上;我在我们的服务器上运行 64 位版本,但是我使用的单个文件只有 80Mb,远不及 2Gb,所以我不知道为什么 Mongo 似乎无法处理它们。
    【解决方案2】:

    好的;经过大量搜索后,似乎 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 来关闭,尽管这仅推荐用于测试机器。

    感谢您的回复!

    【讨论】:

      猜你喜欢
      • 2013-06-07
      • 2013-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      • 2018-08-18
      • 2022-11-29
      • 2012-07-22
      相关资源
      最近更新 更多