Я сравниваю 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/
Производительность записи MySQL в node.js
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 Person), node.js оказывается хуже.
Не только это, но и когда уровень cuncurrency равен 100, узел регистрирует тонну «Ошибка при выполнении запроса». сообщения на консоль и только 500 из 1000 запросов записываются в базу данных. Являются ли драйверы узлов mysql настолько плохими, или я делаю что-то очень не так? Я бы очень признателен за вашу помощь 🙂
спасибо
Прежде всего, вы не закончили код 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