Amazon EC2 上 Node.js 的 CPU 利用率

Posted

技术标签:

【中文标题】Amazon EC2 上 Node.js 的 CPU 利用率【英文标题】:CPU utilization of Node.js on Amazon EC2 【发布时间】:2011-11-22 01:29:38 【问题描述】:

看看节点是如何单线程的,如果我有节点服务器在具有 4 个 EC2 计算单元的亚马逊 EC2 实例上运行,它会比我有 2 个 EC2 计算单元运行得更快/处理更多负载吗?

亚马逊上的 CPU 利用率是否要求程序是多线程的才能充分利用所有资源?

【问题讨论】:

我相信这就是你要找的东西:***.com/questions/2387724/… 【参考方案1】:

要充分利用 N 核的计算资源,至少需要 N 个线程准备好做有用的工作。 这与 EC2 无关;这只是计算机的工作方式。我从您的问题中假设您在 m1.mediumm1.large 实例类型之间进行选择,它们分别具有 1 个和 2 个专用内核(m1.small 是共享内核的一半,m1.xlarge 是完整的专用4芯盒)。因此,您需要至少 2 个进程做有用的工作才能利用更大的盒子(除非您只想访问更多的内存 / io)。

每个 Node.js 进程在设计上都是单线程的。这让它提供了一个没有锁定语义的干净的编程范式。这在很大程度上是设计使然。

对于使用多个内核的 Node.js 应用程序,它必须生成多个进程。然后这些进程将使用某种形式的消息传递(管道、套接字等)进行通信——而不是“共享”内存”,其中代码可以直接改变多个进程可见的内存位​​置,这需要锁定语义。

实际上,这很简单,易于设置。回到 Node.JS v0.6.X 中,“集群”模块被集成到标准发行版中,从而可以轻松设置多个节点工作程序来侦听单个端口。请注意,此“集群”模块与具有不同 API 并在 NPMjs 注册表中拥有“集群”名称的 learnboost“集群”模块不同。

http://nodejs.org/docs/latest/api/cluster.html

if (cluster.isMaster) 
  // Fork workers.
  for (var i = 0; i &lt numCPUs; i++) 
    cluster.fork();
  
 else 
  http.Server(function(req, res)  ... ).listen(8000);

【讨论】:

这可能无法使其进入“回答”状态,但它非常有用。感谢您发布它。我打算“通过”node.js 开发;你又让我对它感兴趣了。 在某些情况下,我认为像cluster mode(来自pm2)这样的东西比自己分叉进程更好。说真的,如果您正在构建具有多个工作进程的服务器,请查看pm2。今天。【参考方案2】:

对您的问题的简短回答是,如果您所做的只是编写“标准”单线程 javascript(您将受到单个 CPU 的约束),那么添加更多内核以提高节点性能是行不通的。

原因是 node.js 使用事件循环进行处理,所以如果你正在做的只是启动一个 node.js 进程而没有其他任何东西,它不会是多线程的,因此不会使用多个CPU(核心)。

但是,您可以使用 node.js 集群 API 来分叉节点进程,这样您就可以利用多个 CPU(核心):https://nodejs.org/docs/latest/api/cluster.html。如果您以这种方式编写代码,那么拥有更多的计算单元将对您有所帮助。

有一个警告,EC2 计算单元的详细信息为per instance。在某些情况下,您可以获得每个虚拟核心的更多“计算单元”。因此,如果您选择一个具有 每个虚拟核心 2 个计算单元 的实例而不是一个具有 每个核心一个 的实例,您将能够在具有更多计算的 CPU 上执行节点单位。但是,看起来在 2 个计算单元之后,计算能力被分配每个核心,这意味着您不会从多个核心中获得任何好处。

【讨论】:

【参考方案3】:

Amazon 对实例类型的总“EC2 计算单元”概念并不直接映射到 CPU 或内核。它是核心数量乘以 EC2 计算单元中每个核心的速度(它们自己的相对测量值)。

亚马逊确实列出了每种实例类型有多少虚拟核心:

http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/index.html?instance-types.html

您最好的选择是使用其他人指出的所有内核。但是,如果您最终使用单线程解决方案,那么您将需要关注单个内核的速度,而不是所有内核加在一起的总 EC2 计算单元。

【讨论】:

【参考方案4】:

在 Node.js 中,您的代码 是单线程的,但会调用它,例如访问文件系统或数据库服务器不要使用主 node.js 线程。主线程继续执行,而其他线程正在等待 4GB 从磁盘读取到 RAM 或等待 DB 服务器返回响应。操作完成后,提供的回调将放入队列中以在主线程中执行。无论如何,或多或少。

优势在于,在服务器情况下,您有一个非常快的线程,可以处理数千个并发请求,而不会完全暂停任何一个请求或为每个客户端请求-响应周期生成一个操作系统线程。

更重要的是,您应该在 EC2 上对您的特定用例进行基准测试——如果应用程序执行大量 IO,则在运行单个节点实例时,多个处理器可能会很有用。

【讨论】:

【参考方案5】:

如果我的节点服务器在具有 4 个 EC2 计算单元的亚马逊 EC2 实例上运行,它会比我有 2 个 EC2 计算单元运行得更快/处理更多负载吗?

不,如果您在服务器容量中使用 node.js,您将只能访问单个内核。

var http = require('http');
    http.createServer(function (req, res) 
    res.writeHead(200, 'Content-Type': 'text/plain');
    res.end('Hello World\n');
).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');

产生一个监听器,但这并不意味着只有一个连接。 Node.js 以这种方式打破了传统思维。除非您编码不正确,否则事件循环不会阻止连接。 This post 有助于解释事件循环以及理解它的重要性。我花了一段时间才真正“明白”其中的含义。

亚马逊上的 CPU 利用率是否要求程序是多线程的才能充分利用所有资源?

是的,正确配置的 apache/nginx 将利用多 CPU 配置。 node.js 服务器是developed,它也将利用这些配置。

【讨论】:

【参考方案6】:

只是对上述内容的快速补充,对 modern(此处为旧线程)Node.JS 的功能提出了很好的观点,Node.JS 不仅是在V8 和 LibUV,利用内部线程池,但实际上,您的 JS 代码可以是多线程的。不,我不只是指 thread_workers API。有可能,甚至很可能,您的某些依赖项正在使用 JS 的 C++/V8/NAPI 绑定,并直接使用底层线程池。

例如: 您会看到npm 上的标准bcrypt 库通过C++ 中的多线程实现了它的blowfish 实用程序。许多人没有正确阅读文档,并且对为什么在其他工作线程中从库中运行一些加密工作并不能加速他们的服务感到困惑。

【讨论】:

以上是关于Amazon EC2 上 Node.js 的 CPU 利用率的主要内容,如果未能解决你的问题,请参考以下文章

从 Amazon AWS EC2 服务器上的 Node.js 连接到 Redis 服务器时出错

如何包含适用于 Node.js 的 Amazon EC2 库?

使用NGINX在端口80上为使用虚拟主机的Amazon EC2上托管的域的node.js应用程序提供HTTP流量

如何使用 Amazon EC2 实例为生产设置 node.js process.env 变量?

如何在 AWS Lambda 中使用 Node.js 列出我的所有 Amazon EC2 实例?

将 Google 域链接到 Amazon ec2 服务器