【问题标题】:How to implement parallel insert operations to MongoDB database with Nodejs如何使用 Nodejs 实现对 MongoDB 数据库的并行插入操作
【发布时间】:2017-09-11 14:47:28
【问题描述】:

我正在开发一段代码,用于将项目大量导入数据库。 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
        });

【问题讨论】:

  • 如果这些是同步活动,异步并行将无济于事
  • 也许你应该展示你的代码。如果运行 700 行需要 40 分钟,那么你就做错了。底线是你在问“我能做到吗?”没有真正向我们展示你在做什么。作为一般性问题过于宽泛。
  • @SuhailGupta 我没听懂你......
  • @NeilLunn 这可能是我的第一行陈述。此外,我提到我战略性地减少了验证步骤。我提到的时间包括验证和插入操作。为了您,我将更新问题以更好地理解上下文

标签: node.js mongodb async.js


【解决方案1】:

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

由于 Node 是单线程的,长时间运行的进程可能会阻止其他代码执行,并使最终用户认为您的应用程序运行缓慢。

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

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

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

一旦分叉的进程完成了那个长操作,它就可以使用 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之后执行

【讨论】:

  • 基本上是一次活动,但记录数量可能会有所不同,可能以十万为单位。我最关心的是时间。
  • @Shaggie 由于每个操作都是同步操作,它们永远不能并行执行。如果有某种方法可以将工作委托给不同的进程/线程,这将有助于减少总时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-18
  • 2015-05-09
  • 2020-04-15
  • 1970-01-01
  • 2020-08-14
  • 2019-04-08
  • 2011-06-06
相关资源
最近更新 更多