【问题标题】:node.js MySQL performancenode.js MySQL 性能
【发布时间】:2015-07-12 21:38:33
【问题描述】:

我正在比较 node.js 与 PHP 在对 MySQL 数据库的写入性能方面。我在虚拟机中使用 Apache Benchmark、linux Mint、最新的 mysql-server(5.5.43) 和带有 node.js from here 的 MySQL 驱动程序。 我使用的代码是

server.js

var http = require('http');
var mysql = require('mysql');
var server = http.createServer(function (req, res) {

var connection = mysql.createConnection({
    host     : 'localhost',
    user     : 'root',
    password : 'root',
    database : 'testDB'
});

connection.connect();
connection.query("INSERT INTO Persons (LastName, FirstName, Address, City) VALUES ('Futterkiste', 'Alfreds', 'Obere Str. 57', 'Berlin')", function(err, rows, fields) {
    if (!err)
        console.log('The solution is: ', rows);
    else
        console.log('Error while performing Query.');
});

connection.end();

res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World');
});

server.listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

index.php

$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "testDB";

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $sql = "INSERT INTO Persons (LastName, FirstName, Address, City) VALUES ('Futterkiste', 'Alfreds', 'Obere Str. 57', 'Berlin')";
    // use exec() because no results are returned
    $conn->exec($sql);
    echo "New record created successfully";
    }
catch(PDOException $e)
    {
    echo $sql . "<br>" . $e->getMessage();
    }

$conn = null;
echo "Hello world";
?>

Apache Benchmark 到带有 index.php 文件的 Apache2 服务器

ab -n 1000 -c 100 http://localhost/

PHP MySQL 写入性能

Concurrency Level:      100
Time taken for tests:   1.328 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      230000 bytes
HTML transferred:       43000 bytes
Requests per second:    752.99 [#/sec] (mean)
Time per request:       132.804 [ms] (mean)
Time per request:       1.328 [ms] (mean, across all concurrent requests)
Transfer rate:          169.13 [Kbytes/sec] received

server.js 文件中的 Apache Benchmark 到 node.js 服务器

ab -n 1000 -c 100 http://localhost:1337/

node.js MySQL 写入性能

Concurrency Level:      100
Time taken for tests:   3.896 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      113000 bytes
HTML transferred:       12000 bytes
Requests per second:    256.68 [#/sec] (mean)
Time per request:       389.585 [ms] (mean)
Time per request:       3.896 [ms] (mean, across all concurrent requests)
Transfer rate:          28.33 [Kbytes/sec] received

我的印象是 node.js 在 I/O 数据库操作方面胜过 PHP。所以令我惊讶的是,无论我尝试哪种 SQL 语句(也尝试过 SELECT * FROM Persons),node.js 的结果都更糟。

不仅如此,当并发​​级别为 100 时,节点会记录大量“执行查询时出错”。向控制台发送消息,并且 1000 个请求中只有约 500 个被写入数据库。 mysql节点驱动程序有那么糟糕还是我在这里做错了什么?非常感谢您的帮助:)

谢谢

【问题讨论】:

  • 您首先运行哪个测试?节点还是php?您应该在每次测试后重置数据库以获得一致的结果,或者只使用具有相同架构的 2 个不同的数据库
  • 尝试在每次测试后重置数据库,结果相同:(
  • 你不能测量那样的东西。您在一台机器上运行所有东西,包括基准测试程序。您刚刚测试的是每个程序处理并发连接的能力。此外,写入操作专属于 MySQL。这是将数据填充到磁盘时的主要权限。 PHP 或节点都没有什么可说的。我建议使用更好的工具进行基准测试,同时使用不同的机器,这样您就不会不必要地占用内核或硬盘 I/O 并运行程序的 CLI 版本。您基本上只是在那里测试了 http 并发性。
  • 那么,与 PHP 相比,为什么 node.js 在当前 MySQL 查询方面如此糟糕?我发现 node.js 在 cuncurrent 读取/写入硬盘上的文件时要快得多,为什么在 MySQL 数据库中看不到这种行为?
  • 当您写入磁盘上的文件时,您并没有强制驱动器真正写入数据。操作系统和硬盘缓存正在排队写入操作,并且写入发生在后期,此时在单个写入操作中有更多数据要写入。当您发出数据库更新或插入时,数据库强制磁盘和操作系统避免这种排队机制并真正写入数据 - 这是@987654329 的D @ - 耐用性。这就是 NoSQL 看起来比关系数据库更快的原因——它们延迟写入。节点的工作方式相同。

标签: php database node.js benchmarking


【解决方案1】:

首先你没有完成 server.js 代码。存在与数据库打开的连接过多的错误。为了解决这个问题,我使用了 connectionPool。其次,Apache 使用 worker 并行运行同一脚本的多个副本。

现在以 Apache + PHP + MySQL (XAMP) 的结果作为参考点:

Concurrency Level:      100
Time taken for tests:   7.476 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      230000 bytes
HTML transferred:       42000 bytes
Requests per second:    133.77 [#/sec] (mean)
Time per request:       747.557 [ms] (mean)
Time per request:       7.476 [ms] (mean, across all concurrent requests)
Transfer rate:          30.05 [Kbytes/sec] received

现在等于我修复 server.js 的机会

var http = require('http');
var mysql = require('mysql');
var connection = mysql.createPool({
    connectionLimit: 10,
    host     : 'localhost',
    user     : 'test',
    password : 'test',
    database : 'testDB'
});
var server = http.createServer(function (req, res) {
    connection.query("INSERT INTO Persons (LastName, FirstName, Address, City) VALUES ('Futterkiste', 'Alfreds', 'Obere Str. 57', 'Berlin')", function(err, rows, fields) {
        if (!err)
            console.log('The solution is: ', rows);
        else {
            console.log('Error while performing Query.');
        }
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World');
    });
});
server.listen(1337, '127.0.0.1');
server.on('close', function() {
    connection.end();
})
console.log('Server running at http://127.0.0.1:1337/');

Node + MySQL 的结果:

Concurrency Level:      100
Time taken for tests:   7.289 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      112000 bytes
HTML transferred:       11000 bytes
Requests per second:    137.19 [#/sec] (mean)
Time per request:       728.899 [ms] (mean)
Time per request:       7.289 [ms] (mean, across all concurrent requests)
Transfer rate:          15.01 [Kbytes/sec] received

如您所见,结果非常接近。但这是针对 11 个 Apache 工作人员的一个节点进程。如果我将簇添加到等式中会发生什么?这是修改后的代码:

var http = require('http');
var mysql = require('mysql');
var cluster = require('cluster');

if (cluster.isMaster) {
    cluster.fork();
    cluster.fork();
    cluster.fork();
    cluster.fork();
} else {
    var connection = mysql.createPool({
        connectionLimit: 10,
        host     : 'localhost',
        user     : 'test',
        password : 'test',
        database : 'testDB'
    });
    var server = http.createServer(function (req, res) {
        connection.query("INSERT INTO Persons (LastName, FirstName, Address, City) VALUES ('Futterkiste', 'Alfreds', 'Obere Str. 57', 'Berlin')", function(err, rows, fields) {
            if (!err)
                console.log('The solution is: ', rows);
            else {
                console.log('Error while performing Query.');
            }
            res.writeHead(200, {'Content-Type': 'text/plain'});
            res.end('Hello World');
        });
    });

    server.listen(1337, '127.0.0.1');
    server.on('close', function() {
        connection.end();
    })
    console.log('Server running at http://127.0.0.1:1337/ worker:' + cluster.worker.id);
}

四个节点工作器结果:

Concurrency Level:      100
Time taken for tests:   2.782 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      112000 bytes
HTML transferred:       11000 bytes
Requests per second:    359.48 [#/sec] (mean)
Time per request:       278.179 [ms] (mean)
Time per request:       2.782 [ms] (mean, across all concurrent requests)
Transfer rate:          39.32 [Kbytes/sec] received

出于好奇,我为具有 10 个工人的节点添加了结果:

Concurrency Level:      100
Time taken for tests:   2.647 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      112000 bytes
HTML transferred:       11000 bytes
Requests per second:    377.84 [#/sec] (mean)
Time per request:       264.665 [ms] (mean)
Time per request:       2.647 [ms] (mean, across all concurrent requests)
Transfer rate:          41.33 [Kbytes/sec] received

我的笔记本电脑是 Core2Duo T6600,Ubuntu 14.04.3,php 5.5.9,node 0.10.37,mysql 5.5.44

【讨论】:

  • 我在 FX 6300 上,仅使用一个节点进程,我得到:` 并发级别:100 测试时间:1.045 秒完成请求:1000 失败请求:0 总传输:112000字节 HTML 传输:11000 字节每秒请求:956.94 [#/sec](平均)每个请求的时间:104.500 [ms](平均)每个请求的时间:1.045 [ms](平均,跨所有并发请求传输率:104.66 [ Kbytes/sec]收到`我的innodb是innodb_flush_log_at_trx_commit=0 innodb_thread_concurrency=8 innodb_log_buffer_size = 32MB
  • 有了集群,我得到:Requests per second: 1392.73 [#/sec] (mean) Time per request: 71.801 [ms] (mean) Time per request: 0.718 [ms] (mean, across all Transfer rate: 152.33 [Kbytes/sec] received 天哪! :)
  • 我没有看到这个答案中的 PHP 参考是从哪里获取的?我在上面看到的 PHP 的性能结果是每秒 752 个请求。然而,这个答案显示的是每秒 133 个请求。为什么会出现差距?我错过了什么吗?
猜你喜欢
  • 2012-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
  • 2014-02-25
相关资源
最近更新 更多