Node.js | cluster 集群 多进程读写的简单使用

550 阅读2分钟

概述

在其他语言中,实现多进程或多线程是非常容易的事情,而对于一个node实例,它是单线程进行工作,不过,node仍能实现多进程工作,在读写方面会比单进程效率会提升很多。 在我自己的测试中,读写20000多个文件,共计2G 的数据,不使用多进程的话,需要3分钟左右的时间,而使用了cluster,40秒左右便完成了读写。

cluster简介

cluster模块可以创建共享服务器端口的子进程,主要是利用处理器多核系统,让子进程处理负载任务,简单来说,主进程通过cluster将任务分发给子进程,让多个任务并发执行,这在读写过程中非常适用。 cluster其底层是通过child_process实现的,详细的参考这篇文章

代码简单结构

代码逻辑:

  1. 主进程循环创建子进程,并向每一个子进程发送变量
  2. 子进程收到变量进行相关操作,执行完成后,向主进程发送信息,表示完成
  3. 主进程收到子进程的信息,执行关闭子进程操作,并输出 进程xx结束
  4. 所有子进程关闭,代码执行完毕。
var cluster = require("cluster");
// 获取当前处理器的核数
var numCPUs = require("os").cpus().length;
// 判断是否是主进程
if (cluster.isMaster) {
    // 初始化代码,如获取一个文件夹下的目录结构
      let primes = [];
      for (let i = 0; i < numCPUs; i++) {
        // 启动子进程
        const worker = cluster.fork(); 
        //  在主进程中,这会发送消息给子进程
        // 分配写入工作
        worker.send({
            // 发送变量
        });
      }
    
  // 当任何一个工作进程关闭的时候,cluster 模块都将会触发 'exit' 事件
  cluster.on("exit", function (worker, code, signal) {
    console.log("进程" + worker.process.pid + "结束");
  });
  // 当主进程收到信息时,执行一些操作,这里是主进程收到子进程消息便将子进程关闭   
  cluster.on("message", function (worker, message, handle) {
    worker.kill();
  });
} else {
  // 监听主进程发来的变量信息,并执行相关操作
  process.on("message", (msg) => {
    // 做些什么   
    // 子进程中,发送消息给主进程
    process.send({ data: "结束" });
  });
}

注意事项

  1. 当你想初始化一些内容时,一定要写到这里面,如果你判断外面,每一个子进程都将执行这些代码,导致重复初始化
if (cluster.isMaster) {
// 初始化代码
}
  1. 关于子进程的数量,我默认是根据核数开启等数量的子进程,网上有其他人测试,开启12个速度最快,但我实测是等核数比开12个快一点,在这个问题上看个人实测结果做选择
  2. 子进程中变量传递是一个问题,公共变量往往在子进程中无法使用,可以使用子进程向主进程通信解决该问题。

参考资料

Node.js Api

欢迎来到我的个人博客