如何使用Nodejs对MongoDB数据库实现并行插入操作

时间:2017-09-11 06:09:36

标签: node.js mongodb async.js

我正在开发一段代码,用于将项目大量导入数据库。 Excel文件中的总记录数为24103.由于大量验证,最初导入700行记录的总时间为40分钟。现在,在减少战略步骤后,所有记录的时间减少到24分钟。现在有4个活动可以相互独立地执行。我尝试通过async.parallel进程并行执行的那些活动。但是当我看到控制台进行调试时,我才知道它仍然会一次性执行所有记录。差别在于对插入的记录进行改组。在执行所有操作之后,它花费了相同的时间,以前的活动顺序执行。什么是以并行方式执行(插入)的另一种可能方式。

我的步骤包括

        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
        });

1 个答案:

答案 0 :(得分:1)

显然,应用程序中的逻辑执行时间超过几秒钟。您可以考虑将其从主线程移开,特别是如果它也将每小时或每天运行多次。

由于Node是单线程的,因此长时间运行的进程可以阻止其他代码执行,并让最终用户感觉您的应用程序运行缓慢。

您可以使用Node的child_process模块旋转child process,这些子进程可以通过消息传递系统轻松地相互通信。您可以同时旋转多个进程并使它们并行执行。

您首先将整个长计算函数移动到其自己的文件中,并在通过主进程的消息指示时调用该函数。现在,您可以派生 long-computation.js 文件并使用messages接口在服务器和分叉进程之间传递消息,而不是在主进程事件循环中执行长操作。

当使用上面的代码向long-computation发出请求时,我们只是向分叉进程发送一条消息以开始执行long操作。主进程的事件循环不会被阻止。

使用该长操作完成分叉进程后,它可以使用process.send将其结果发送回父进程

可能对您有帮助的参考资料:

<强>更新

这是一个示例代码,它有两个带for循环的函数,可以达到一百万。现在只需将两者包装在并行包装器中(async.parallel in your case)并不意味着它们将神奇地成为并行操作。它们必须是异步操作。

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));

函数two将始终在one

之后执行