node.js - GridFS 大 File 下载使 Node.js 服务器崩溃。 MongoServerError:排序超出了字节的内存限制

所以我用 mongoose 运行一个 Node.js 服务器,我一直在尝试使用 GridFS node 包下载一个大的 file 但我收到以下错误:

MongoServerError: 执行器错误在 find 命令 :: 中导致 :: Sort 超出了 104857600 字节的内存限制,但没有选择外部排序。

这是我用来下载 file 的代码:

// Stream a single file. 
router.get('/stream/:filename', async function(req, res, next){
    try{        
        const file = gfs.find({
            filename: req.params.filename
        }).toArray((err, files) => {
        if (!files || files.length === 0) {
            return res.status(404)
            .json({
                err: "no files exist"
            });
        }

        gfs.openDownloadStreamByName(req.params.filename)
            .pipe(res);
        });
    }catch(err){
        return res.status(400).json({
            err:'Could not fetch the file.'
        })
    }
});

鉴于https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-answer-your-own-questions/,我想记录这个问题,以便我的解决方案可以帮助其他人以后遇到它。

回答1

事实证明,当您通过使用 GridFS 流式下载 file 时,构成 file 的文档会被排序。根据 https://developerslogblog.wordpress.com/2019/11/27/mongodb-sort-how-to-fix-maximum-ram-exceeded-error/,在进行排序时,MongoDB 首先尝试使用索引中指定的顺序检索文档。当没有可用的索引时,它会尝试将文档加载到内存中并在那里对其进行排序。

问题是 Mongo 默认配置为在超过 32 MB 的使用量时中止操作。这就是我们遇到上述“排序超出内存限制”错误的原因。为了解决这个问题,您必须为包含要下载的 file 块的顺序的“n”字段创建一个索引。为此,您可以直接通过数据库界面创建索引(我使用 MongoDB Compass GUI),也可以使用 createIndex() 方法通过代码创建它:

// Create an index for the 'n' field to help sort the chunks collection.
db.collection('files.chunks').createIndex({n: 1});

相似文章

c - 无法删除C中双向链表的重复数据

我在从双向链表中删除重复数据时遇到问题。所以这个列表的data元素是一个数字数组。我想用这个delete_duplicates代码删除重复数据的节点。我使用以下print_list函数来打印列表。该函...

随机推荐

最新文章