简体   繁体   English

NodeJS比PHP慢得多?

[英]NodeJS much slower than PHP?

I run a tiny scale web server under Apache + PHP + MySQL at the moment and would like to explore the option of using NodeJS instead. 我目前在Apache + PHP + MySQL下运行一个小规模的Web服务器,并希望探索使用NodeJS的选项。 The server literally does two things: 服务器实际上做了两件事:

  1. Serve some static files (HTML/CSS/image resources etc) 提供一些静态文件(HTML / CSS /图像资源等)
  2. Query the database (select and insert only, no update or delete) 查询数据库(仅选择和插入,不更新或删除)

However, I'm running into some performance issue and I'm trying to figure out where the problem is. 但是,我遇到了一些性能问题,我正在试图找出问题所在。 To isolate the problem, I've created a minimal NodeJS app, which runs a query against MySQL and return 50 rows of data as JSON. 为了解决问题,我创建了一个最小的NodeJS应用程序,它运行针对MySQL的查询并返回50行数据作为JSON。 Below is my code: 以下是我的代码:

var express = require('express');
var compression = require('compression');
var mysql = require('mysql');

var db = mysql.createPool({
    host: <host>,
    user: <user>,
    password: <password>,
    database: <database>,
    debug: false
});

var app = express();
app.use(compression());

app.get('/data', function(req, res) {
    var sql = 'SELECT column_1, column_2 FROM table';
    db.query(sql, function (error, rows, fields) {
        if (error) throw error;
        res.json(rows);
    });
});

app.listen(3000, function () {
  console.log("Running on port 3000.");
});

By using ApacheBench to fire 1000 requests at a concurrency level of 1 (in order not to disadvantage the single-threaded Node app), the result is as follows: 通过使用ApacheBench以并发级别1触发1000个请求(为了不使单线程Node应用程序不利),结果如下:

Concurrency Level:      1
Time taken for tests:   10.377 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      3057000 bytes
HTML transferred:       2829000 bytes
Requests per second:    96.37 [#/sec] (mean)
Time per request:       10.377 [ms] (mean)
Time per request:       10.377 [ms] (mean, across all concurrent requests)
Transfer rate:          287.69 [Kbytes/sec] received

As a comparison, below is my code in PHP: 作为比较,下面是我在PHP中的代码:

<?php

    $hostname = <host>;
    $username = <user>;
    $password = <password>;
    $database = <database>;

    try {
        $db_handler = new PDO('mysql:host=' . $hostname . ';dbname=' . $database, $username, $password);
    } catch (PDOException $e) {
        throw new Exception('[ERROR] Unable to connect to the database.');
    }

    $sql = 'SELECT column_1, column_2 FROM table';
    $statement = $db_handler->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
    $statement->execute();
    $rows = array();
    while ($row = $statement->fetch(PDO::FETCH_ASSOC)){
        $rows[] = $row;
    }
    print json_encode($rows);

    $db_handler = null;

?>

And the result from ApacheBench: 而ApacheBench的结果是:

Concurrency Level:      1
Time taken for tests:   6.726 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      3023000 bytes
HTML transferred:       2829000 bytes
Requests per second:    148.68 [#/sec] (mean)
Time per request:       6.726 [ms] (mean)
Time per request:       6.726 [ms] (mean, across all concurrent requests)
Transfer rate:          438.92 [Kbytes/sec] received

From the above result, it is observed that PHP is much faster than NodeJS. 从上面的结果可以看出,PHP比NodeJS快得多。 The discrepancy is even wider if a more complex query is fired (the difference could be 20 times, like 20ms vs 400ms), or if the concurrency level is increased. 如果触发更复杂的查询(差异可能是20次,如20ms vs 400ms),或者并发级别增加,则差异甚至更大。

I've tried to add up to 4 workers (I'm running the server on Raspberry Pi 2 which has 4 cores) to the Node app and see if it helps, unfortunately it is still not close to the result in PHP. 我试图在Node应用程序中添加最多4个工作者(我在Raspberry Pi 2上运行服务器,它有4个核心),看看它是否有帮助,不幸的是它仍然不接近PHP的结果。 Could you please advise what I might have done wrong? 你能告诉我可能做错了什么吗? Or NodeJS is just not a good pick for what I'm trying to achieve? 或者NodeJS不是我想要实现的目标的好选择?

[EDITED] [EDITED]

Thanks a lot for all your comments. 非常感谢你的所有评论。 Seems like most people suspect that the problem is caused by the NodeJS MySQL driver. 似乎大多数人怀疑这个问题是由NodeJS MySQL驱动程序引起的。 I've also done a bit more testing to make sure if that's the case, and I accidentally found something really interesting. 我还做了一些测试,以确定是否是这种情况,我不小心发现了一些非常有趣的东西。

By running the same Node app in another PC (Core 2 Duo E7200), but connecting to the same MySQL on Raspberry Pi, the result is in fact quite decent: 通过在另一台PC(Core 2 Duo E7200)中运行相同的Node应用程序,但在Raspberry Pi上连接到相同的MySQL,结果实际上相当不错:

Concurrency Level:      1
Time taken for tests:   2.705 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      3057000 bytes
HTML transferred:       2829000 bytes
Requests per second:    369.71 [#/sec] (mean)
Time per request:       2.705 [ms] (mean)
Time per request:       2.705 [ms] (mean, across all concurrent requests)
Transfer rate:          1103.72 [Kbytes/sec] received

And as a comparison, I've also run an Apache server on that PC, connecting to the same MySQL on Raspberry Pi, and below is the result: 作为比较,我还在该PC上运行Apache服务器,连接到Raspberry Pi上的相同MySQL,结果如下:

Concurrency Level:      1
Time taken for tests:   6.297 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      3034000 bytes
HTML transferred:       2829000 bytes
Requests per second:    158.80 [#/sec] (mean)
Time per request:       6.297 [ms] (mean)
Time per request:       6.297 [ms] (mean, across all concurrent requests)
Transfer rate:          470.50 [Kbytes/sec] received

As a summary, below is the result I've gotten so far. 总结一下,下面是我到目前为止的结果。 Only the web server part is different, while the database is always MySQL on Raspberry Pi: 只有Web服务器部分不同,而数据库在Raspberry Pi上始终是MySQL:

Server      Time Taken
Node (Pi)   10.337s
PHP (Pi)    6.726s
Node (PC)   2.705s
PHP (PC)    6.297s

The result for PHP appears to be more or less the same on both server, while that of NodeJS varies a lot. PHP的结果在两台服务器上看起来差不多,而NodeJS的结果差异很大。 Based on the result above, it appears to me that NodeJS is more sensitive to CPU performance, or in another words CPU intensive? 基于上面的结果,我觉得NodeJS对CPU性能更敏感,换句话说就是CPU密集型? (The NodeJS version I'm using is v6.9.4, just FYI) (我正在使用的NodeJS版本是v6.9.4,仅供参考)

By using ApacheBench to fire 1000 requests at a concurrency level of 1 (in order not to disadvantage the single-threaded Node app) 通过使用ApacheBench以并发级别1发出1000个请求(为了不使单线程Node应用程序不利)

By limiting concurrency to 1, you're actually taking away node's biggest advantage, which is asynchronous IO. 通过将并发性限制为1,您实际上取消了节点的最大优势,即异步IO。 Even though node.js is single-threaded, it will handle other requests while waiting on the db.query call. 即使node.js是单线程的,它也会在等待db.query调用时处理其他请求。

Because node is not using system threads for this, but its own lightweight scheduler, it can execute concurrent requests much cheaper than Apache. 因为节点没有使用系统线程,而是它自己的轻量级调度程序,它可以比Apache便宜得多的并发请求。 Apache can be configured in different ways to handle multiple requests (eg pre-forking a fixed number of processes or event-driven forking), but once you have a certain number of concurrent requests, things will slow down as requests might have to wait for others to complete, even if those others are doing nothing but waiting for the DB. Apache可以以不同的方式配置来处理多个请求(例如,预先分配固定数量的进程或事件驱动的分叉),但是一旦你有一定数量的并发请求,事情就会变慢,因为请求可能需要等待其他人要完成,即使其他人除了等待数据库之外什么都不做。

So, to conclude, for synchronously executing a single request, yes PHP might be faster; 因此,总而言之,对于同步执行单个请求,是的PHP可能会更快; but once you have enough requests which exceed the limit set by Apache's configuration and which is affected also by the size of your machine, you should see node.js being faster overall. 但是一旦你有足够的请求超过了Apache配置设置的限制,并且受到机器大小的影响,你应该看到node.js整体上更快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM