使用mysql池对node.js(cluster)的性能进行基准testing:Lighttpd + PHP?
编辑(2):现在使用db-mysql和generic-pool模块。 错误率大幅下降,徘徊在13%,但吞吐量仍然在100瑞士克/秒左右。
编辑(1):有人build议ORDER BY RAND()会导致MySQL变慢,我已经从查询中删除该子句。 Node.js现在徘徊在100 req / sec左右,但服务器仍报告“连接错误:连接太多”。
Node.js或Lighttpd与PHP?
你可能看到了许多“Hello World”的node.js基准testing,但是“hello world”testing,即使是那些每个请求延迟了2秒的testing,甚至都不能接近现实世界的产品使用情况。 我还使用node.js执行了“Hello World”testing的这些变体,并且看到吞吐量约为800 req / sec,错误率为0.01%。 但是,我决定进行一些比较现实的testing。
也许我的testing没有完成,很可能是node.js或我的testing代码真的是错误的,所以如果你是一个node.js专家,请帮我写一些更好的testing。 我的结果发表如下。 我使用Apache JMeter来进行testing。
testing用例和系统规格
testing非常简单。 用户数量的mysql查询是随机排列的。 第一个用户的用户名被检索和显示。 mysql数据库连接是通过一个unix套接字。 操作系统是FreeBSD 8+。 8GB的RAM。 英特尔至强四核2.x Ghz处理器。 我甚至在我遇到node.js之前调整了Lighttpdconfiguration。
Apache JMeter设置
线程数(用户):5000 我相信这是并发连接数
加速期(以秒为单位):1
循环计数:10 这是每个用户的请求数量
Apache JMeter最终结果
标签| #Samples | 平均| Min | 最大| 标准。 开发。 | 错误%| 吞吐量| KB / sec | 平均。 字节 HTTP请求Lighttpd | 49918 | 2060ms | 29ms | 84790ms | 5524 | 19.47%| 583.3 / sec | 211.79 | 371.8 HTTP请求Node.js | 13767 | 106569ms | 295ms | 292311ms | 91764 | 78.86%| 44.6 / sec | 79.16 | 1816
结果结论
Node.js是如此糟糕,我不得不提前停止testing。 [完全固定testing]
Node.js报告服务器上的“连接错误:连接太多”。 [ 修正 ]
大多数时候,Lighttpd的吞吐量约为1200瑞克/秒。
但是,node.js的吞吐量大约是29个/秒。 [现在在100req /秒]
这是我用于node.js的代码(使用MySQL池)
var cluster = require('cluster'), http = require('http'), mysql = require('db-mysql'), generic_pool = require('generic-pool'); var pool = generic_pool.Pool({ name: 'mysql', max: 10, create: function(callback) { new mysql.Database({ socket: "/tmp/mysql.sock", user: 'root', password: 'password', database: 'v3edb2011' }).connect(function(err, server) { callback(err, this); }); }, destroy: function(db) { db.disconnect(); } }); var server = http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/html"}); pool.acquire(function(err, db) { if (err) { return response.end("CONNECTION error: " + err); } db.query('SELECT * FROM tb_users').execute(function(err, rows, columns) { pool.release(db); if (err) { return response.end("QUERY ERROR: " + err); } response.write(rows.length + ' ROWS found using node.js<br />'); response.end(rows[0]["username"]); }); }); }); cluster(server) .set('workers', 5) .listen(8080);
这是我用于PHP的代码(Lighttpd + FastCGI)
<?php $conn = new mysqli('localhost', 'root', 'password', 'v3edb2011'); if($conn) { $result = $conn->query('SELECT * FROM tb_users ORDER BY RAND()'); if($result) { echo ($result->num_rows).' ROWS found using Lighttpd + PHP (FastCGI)<br />'; $row = $result->fetch_assoc(); echo $row['username']; } else { echo 'Error : DB Query'; } } else { echo 'Error : DB Connection'; } ?>
这是一个糟糕的基准比较。 在node.js中,select整个表并将其放入一个数组中。 在PHP中,你只parsing第一行。 所以你的表越大,节点越慢。 如果你使用mysqli_fetch_all做了一个类似的比较。 虽然db-mysql应该是快速的,但它不是非常全面的function,而且缺乏使这个公平比较的能力。 使用不同的node.js模块(如node-mysql-libmysqlclient)应该只允许您处理第一行。
100个连接是MySQL最大连接数的默认设置。
所以不知何故,你的连接不会被重复用于不同的请求。 可能你已经有一个查询在每个连接上运行。
也许您使用的nodejs MySQL库不会在同一个MySQL连接上排队查询,而是尝试打开其他连接并失败。
纠正我,如果我错了,但我觉得你是忽略了一些东西:节点使用一个进程来处理每个请求(并通过事件处理它们,仍然是相同的进程),而PHP获得一个新的进程请求。
问题是从节点的一个进程到CPU的一个核心,PHP通过multithreading与所有四个核心进行扩展。 我想说的是,使用四核2.x GHz处理器,通过能够利用额外的资源,PHP肯定会比Node有更大的优势。
还有一个讨论提供了一些关于如何在多核上扩展节点的信息,但是这必须通过编码明确地完成。 再一次,纠正我,如果我错了,但我没有看到在上面的例子中的任何这样的代码。
我自己很新,但我希望这可以帮助你改善你的testing:)
你用PHP启用了APC吗?
你可以尝试启用持久连接与PHP? 例如
$conn = new mysqli('p:localhost', 'root', 'password', 'v3edb2011');
您不是在Node.js中使用10个最大的MySQL连接,而是通过PHP使用5000个最大的MySQL连接?
当你在任一系统上运行你的testing时,我会看看MySQL的“SHOW FULL PROCESSLIST”。
有一点需要考虑的是驱动程序 – 数据库的性能可以与您正在使用的特定驱动程序紧密相关。 最stream行的mysql驱动程序和最积极维护的是https://github.com/felixge/node-mysql 。 可能会得到不同的结果。
但是,如果你被困在100个连接,听起来像连接没有正确closures。 我可能会在pool destroy事件中添加一个console.log语句,以确保它确实在执行。
这是一个糟糕的基准,它应该是一个简单的“hello world”,因为成千上万的基准certificatenodejs是所有时间中速度最快的“hello world”服务器:D