如何用Nodejs实现对MongoDB数据库的并行插入操作
我正在开发一个大量的项目导入到数据库的代码段。 在Excel文件中的总logging是24103.而由于大规模的validation,最初的40分钟总共需要input700行logging。 现在,在减less战略步骤之后,所有logging的时间减less到24分钟。 现在有四项活动可以并行独立执行。 那些我尝试通过async.parallel
过程并行执行的活动。 但是当我看到控制台进行debugging的时候,我才知道它仍然能够以一种方式在一条logging中执行这些操作。 只是不同之处在于正在插入的logging的洗牌。 在所有的执行完成之后,与之前所执行的活动顺序进行的时间相同。 什么可能是另一种可能的方式来执行(插入)并行的方式。
我的步骤包括
flowController.on('START', function () { // Uploading and storing the binary data as excel file }); flowController.on('1', function () { // Validation to check if file contain required sheet with name and all and convert the file into JSON format }); flowController.on('2', function () { // Replacing the keys from the JSON to match the required keys }); flowController.on('3', function () { // Massive validation of records & seperating the records as per the activity }); // Activity 1 flowController.on('4', function () { // Insert records of Activity 1 }); // Activity 2 flowController.on('5', function () { // Insert records of Activity 2 }); // Activity 3 flowController.on('6', function () { // Insert records of Activity 3 }); // Activity 3 flowController.on('END', function () { // End });
显然,应用程序中的逻辑需要超过几秒钟才能执行。 你可以考虑把它从主线程中移走,特别是如果每小时或每天也会运行很多次。
因为节点是单线程的,所以长时间运行的进程可以阻止其他代码的执行,并给最终用户感觉你的应用程序变慢了。
您可以使用Node的child_process
模块来旋转subprocess ,这些subprocess可以通过消息传递系统轻松地进行通信。 你可以同时旋转多个进程并且让它们并行执行。
您首先将整个长计算函数移动到它自己的文件中,并通过来自主进程的消息进行指令调用该函数。 现在,不必在主进程事件循环中执行长操作,而是可以fork long-computation.js文件,并使用消息接口在服务器和分叉进程之间传递消息。
当上面的代码发生long-computation
的请求时,我们只需发送一个消息给分支进程开始执行长时间的操作。 主进程的事件循环不会被阻塞。
一旦分叉进程完成了这个长操作,就可以使用process.send将结果发送回父进程
参考可能会帮助你:
- https://medium.com/@snatera15/multithreading-multiprocessing-and-the-nodejs-event-loop-5b2929bd450b
- https://nodejs.org/api/cluster.html
- https://nodejs.org/api/child_process.html
更新:
这是一个示例代码,它有两个函数, for
循环可以达到一百万。 现在只要async.parallel in your case
两个包装在并行包装中( async.parallel in your case
)并不意味着他们将奇迹般地变成并行操作。 他们必须是asynchronous操作。
const Promise = require('bluebird'); function one() { return new Promise((res, rej) => { for (let i = 0; i <= 1000000; i++) { console.log('one'); if (i == 1000000) res('Done') } }); } function two() { return new Promise((res, rej) => { for (let i = 0; i <= 1000000; i++) { console.log('two'); if (i == 1000000) res('Done') } }); } let a = [one(), two()]; Promise.all(a).then(r => console.log(r));
functiontwo
将始终在one
之后执行
- 在Async瀑布中为每个具有Mysql连接池的函数
- 在JavaScript中asynchronous迭代大量数组,而不会触发超出的堆栈大小
- asynchronous队列,文件stream结束时如何知道两者何时完成
- 从一个ID数组到一个名称数组(mongo,nodejs)
- NodeJS,asynchronousforEachSeries执行顺序
- Nodejsasynchronous编程 – 为什么需要“asynchronous”模块? 什么是“回拨地狱”/“厄运金字塔”?
- 使用nodejsasynchronous和请求模块
- javascript nodejs if语句是以意外的顺序调用的
- 在节点js中的async.forEach中返回值?