node.js MySQL производительность

Я сравниваю node.js и PHP с точки зрения производительности записи в базу данных MySQL. Я использую Apache Benchmark, Linux Mint в виртуальной машине, новейший MySQL-сервер (5.5.43) и драйвер для MySQL с node.js отсюда.
Код, который я использовал

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 для сервера Apache2 с файлом index.php

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

Apache Benchmark для сервера node.js в файле server.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 превосходит PHP в операциях с базой данных ввода / вывода. Поэтому меня удивляет, что независимо от того, какой оператор SQL я пробую (также пробовал SELECT * FROM Persons), node.js оказывается хуже.

Не только это, но и когда уровень cuncurrency равен 100, узел записывает тонну «Ошибка при выполнении запроса». сообщения на консоль и только ~ 500 из 1000 запросов записываются в базу данных. Драйверы узлов mysql настолько плохи, или я делаю что-то здесь очень неправильно? Буду очень признателен за вашу помощь 🙂

Спасибо

12

Решение

Прежде всего, вы не закончили код server.js. Существует ошибка с слишком большим количеством открытых соединений с БД. Чтобы исправить это, я использовал connectionPool. И во-вторых, Apache использует рабочих для параллельного запуска множества копий одного и того же скрипта.

Теперь результат для 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, узел 0.10.37, mysql 5.5.44

18

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]