Python 如何在mongoose/mongodb中扩展findOneAndUpdate以获得500万次更新?
我正在开发一个后端:nodejs、mongoose、mongodb、ironmq。还有另一个应用程序(python FTP服务器)用作数据源 系统或多或少是这样工作的:Python 如何在mongoose/mongodb中扩展findOneAndUpdate以获得500万次更新?,python,node.js,mongodb,mongoose,Python,Node.js,Mongodb,Mongoose,我正在开发一个后端:nodejs、mongoose、mongodb、ironmq。还有另一个应用程序(python FTP服务器)用作数据源 系统或多或少是这样工作的: 用户将csv转储的数据(近300万条)上传到FTP服务器(这种情况定期发生,每24小时一次) FTP服务器解析数据,并同步批量(2000次)推送到IronMQ队列。我在这里进行批处理是为了优化内存 另一个应用程序(nodejs)不断轮询此队列中的数据,每10秒轮询100条消息(这是允许的最大数量),处理此数据,然后更新我的数据
- 用户将csv转储的数据(近300万条)上传到FTP服务器(这种情况定期发生,每24小时一次)
- FTP服务器解析数据,并同步批量(2000次)推送到IronMQ队列。我在这里进行批处理是为了优化内存
- 另一个应用程序(nodejs)不断轮询此队列中的数据,每10秒轮询100条消息(这是允许的最大数量),处理此数据,然后更新我的数据库(对每条消息使用
)。我有5个这样的应用正在运行findOneAndUpdate
- 我的上述方法是否可以被认为是最佳/有效的?或者有什么可以改进的
- 如何通过db或更改设计来减少整个更新操作所需的时间
- mongodb被认为适合这种情况,还是有更好的替代方案
如果你能在这方面提供一些帮助,那就太棒了。如果您需要更多信息,请务必告诉我。您可以使用批量API方法优化更新,这些方法非常有效,因为它们允许您在单个请求(作为一个批处理)中向服务器发送多个更新操作。 请考虑以下示例,演示不同MangoDB版本的这种方法: 假设您的nodejs应用程序将消息数据轮询到列表中,对于支持MongoDB Server的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);
在上面,您初始化了更新操作数组,并将操作限制为500个批次。选择低于默认批次限制1000的值的原因通常是受控选择。如文档中所述,MongoDB默认情况下将发送到,并且不能保证这些默认的1000个操作请求实际上符合。因此,您仍然需要站在“安全”的一边,施加一个较低的批处理大小,您只能有效地管理该批处理大小,以便在发送到服务器时,其总量小于数据限制
如果您使用的是支持MongoDB Server
=2.6.x
的Mongoose~3.8.8、~3.8.22、4.x
的旧版本,则可以使用API,如下所示
var bulk = Model.collection.initializeOrderedBulkOp(),
bulkUpdateCallback = function(err, r){
console.log(r.matchedCount);
console.log(r.modifiedCount);
},
counter = 0;
messages.forEach(function(msg) {
bulk.find({ "_id": msg._id }).updateOne({
"$set": { "value": msg.value }
});
counter++;
if (counter % 500 == 0) {
bulk.execute(function(err, r) {
// do something with the result
bulk = Model.collection.initializeOrderedBulkOp();
counter = 0;
});
}
});
// Catch any docs in the queue under or over the 500's
if (counter > 0) {
bulk.execute(bulkUpdateCallback);
}
谢谢,我会努力实现这一点。