如何在mongoose/mongodb中扩展findOneAndUpdate以获得500万次更新?

2024-07-04 13:39:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个后端:nodejs、mongoose、mongodb、ironmq。还有另一个应用程序(pythonftp服务器)用作数据源。在

系统或多或少是这样工作的:

  • 用户将csv数据转储(大约300万个条目)上载到FTP服务器(这种情况定期发生,每24小时一次)

  • FTP服务器解析数据,并以批(2000个)的方式同步推送到IronMQ队列。我在这里进行批处理以优化内存

  • 另一个应用程序(nodejs)继续轮询这个队列中的数据,每10秒有100条消息(这是允许的最大数量),处理这些数据,然后更新我的数据库(每个消息使用findOneAndUpdate)。我有5个程序在运行。

现在除了完成整个操作所花费的时间外,这个设置没有任何明显的问题。将解析后的数据完全推送到MQ需要将近2个小时的时间,但这并不是什么大问题,因为它是成批完成的。实际问题来自于“保存/更新到数据库”部分。在

数据库中平均每小时更新20-24K个条目。但由于我有300万个条目,这需要超过24小时(这不起作用,因为FTP上的文件每24小时刷新一次,数据将用于在我的应用程序的其他部分执行某些操作)。在

我不太清楚该怎么办,但我有几个问题要问。在

  • 我的上述方法可以被认为是最佳/有效的吗?或者还有什么可以改进的?在
  • 如何通过数据库或更改设计来减少整个更新操作所需的时间?在
  • mongodb是否适合这种情况,或者是否有更好的替代方案?在

如果你能在这方面提供一些帮助,那就太棒了。如果你们需要更多的信息,请告诉我。在


Tags: 数据服务器数据库应用程序消息队列mongodb时间
1条回答
网友
1楼 · 发布于 2024-07-04 13:39:46

您可以通过使用bulkapi方法来优化您的更新,这些方法非常有效,因为它们允许您在单个请求(作为批处理)中向服务器发送许多更新操作。 MongoDB考虑了以下不同版本的方法:

假设您的nodejs应用程序将消息数据轮询到一个列表中,对于支持MongoDB服务器的Mongoose版本>=4.3.0,您可以使用^{}将集合更新为:

var bulkUpdateCallback = function(err, r){
        console.log(r.matchedCount);
        console.log(r.modifiedCount);
    },
    operations = []; // Initialise the bulk operations array

messages.forEach(function (msg) { 
    operations.push({
        "updateOne": {
            "filter": { "_id": msg._id } ,              
            "update": { "$set": { "value": msg.value } } // example update operation
        }
    });

    // Send once in 500 requests only
    if (operations.length % 500 === 0 ) {
        Model.collection.bulkWrite(
            operations, 
            { "ordered": true, w: 1 }, 
            bulkUpdateCallback
        ); 
        operations = [];
    }    
});

// Get the underlying collection via the native node.js driver collection object
Model.collection.bulkWrite(bulkOps, { "ordered": true, w: 1 }, bulkUpdateCallback); 

在上面,初始化update operations数组并将操作限制为500个批。选择低于默认批次限制1000的值的原因通常是可控的选择。如文档中所述,默认情况下,MongoDB将发送给server in batches of 1000 operations at a time at maximum,并且不能保证这些默认的1000个操作请求实际上适合16MB BSON limit。因此,您仍然需要站在“安全”的一边,并施加一个较低的批处理大小,这样您才能有效地管理它,以便在发送到服务器时它的总大小小于数据大小限制。在


如果您使用的是支持MongoDB服务器~3.8.8, ~3.8.22, 4.x的旧版本Mongoose>=2.6.x,那么可以使用如下的^{}API

^{pr2}$

相关问题 更多 >

    热门问题