yet another node vs php

10
Yet another Node Vs PHP+Apache When they said Node JS , they said about performance. They said about concurrency. They said about non-blocking I/O. I thought of giving a try to visualizing that in comparing with other languages and see if Node is really better in some way. I will try here to explore the 2 main features of Node that make it win in certain scenarios. 1. Non-Blocking I/O: - In a typical application where we need to perform 3 tasks we simple execute them this way task1(); task2(); task3(); Now task3() will not be executed until task2() is completed and task2() may take long time depending on its operation and so execution of task3() will be blocked. So in a scenario where all these jobs / tasks are independent to each other and can run in parallel, this sequential paradigm won't fit practically. Node fits here perfectly. Node supports callbacks, that means calls are asynchronous and non-blocking. The task2() will not

Upload: anirban-bhattacharya

Post on 09-Aug-2015

84 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Yet another node vs php

Yet another Node Vs PHP+Apache

When they said Node JS , they said about performance. They said about concurrency.

They said about non-blocking I/O. I thought of giving a try to visualizing that in

comparing with other languages and see if Node is really better in some way.

I will try here to explore the 2 main features of Node that make it win in certain

scenarios.

1. Non-Blocking I/O: - In a typical application where we need to perform 3 tasks we

simple execute them this way

task1();

task2();

task3();

Now task3() will not be executed until task2() is completed and task2() may take long

time depending on its operation and so execution of task3() will be blocked. So in a

scenario where all these jobs / tasks are independent to each other and can run in

parallel, this sequential paradigm won't fit practically.

Node fits here perfectly. Node supports callbacks, that means calls are asynchronous

and non-blocking. The task2() will not block task3() or in other words "a statement in

Node will never wait for another I/O to be finished."

I created a similar scenario in Node

Page 2: Yet another node vs php

var http = require('http');

var resp = function doResp()

{

console.log("Second task executed..");

}

http.createServer(function (req, res) {

console.log("Task One exeuted.."); // This is task 1

setTimeout(resp,2000); //This is actually how callback is utilized

/* Below statements are task3*//

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

res.end("Page content is loaded but request is yet processing task 2 in back

ground...");

console.log("Task three executed..");

}).listen(9999);

The above simple node code has main 3 tasks to do as we planned.

Task one will print a message on console.

Task two is a Time consuming task takes 2 seconds and at the end it will display

message on console.

Task three writes the response to user and also displays a message on console.

This line " setTimeout(resp,2000);" is where actually callback is used. So the actual

function is being passed as parameter to setTimeout function , that means after 2000

millisecond the function doResp() will be invoked. Which is stored in a variable resp. But

the beaut is the whole statement " setTimeout(resp,2000);" gets executed immediately

and next statements start getting executed. Though in parallel sets a timer to execute

the callback function after 2 seconds, it doesn't stop next tasks.

I started the app and hit from browser, and saw on Browser screen the message "

In console I could see the below 2 messages

Page 3: Yet another node vs php

"Task One exeuted.."

"Task three executed.."

and after 2 seconds I did see the another message came up "Second task executed.."

I am happy with the Non-Blocking I/O (or to me asynchronous) of Node.

2. Concurrency: I am done with verifying nonblocking IO feature. Now I have to see

and test concurrency and an overall load test. As suggested by others I used siege for

load test simulation.

Wrote a simple Node which reads from a Mysql table and emmits JSON. Wrote another

PHP file which does the same thing.

Here to make the response content length similar , I purposefully avoided Chunked

transfer Encoding in PHP+Apache.

The table has around 53 records. I did test with few different parameters.

Complete code and database structure is available on Git link provided at the end.

Below are my complete test results. The upper ones are Node and Below are PHP

500 Concurrent users for 5 Minutes with 1 second delay

anirbanb2004@Anisoft-Corporation:~/www/loadTest/siegeLog$ siege -c500 -d1 -t5M -

lnode1.log http://localhost:9615

** SIEGE 3.0.5

** Preparing 500 concurrent users for battle.

The server is now under siege...

Lifting the server siege... done.

Transactions: 296509 hits

Availability: 100.00 %

Elapsed time: 299.75 secs

Data transferred: 830.79 MB

Response time: 0.00 secs

Transaction rate: 989.19 trans/sec

Page 4: Yet another node vs php

Throughput: 2.77 MB/sec

Concurrency: 4.20

Successful transactions: 296509

Failed transactions: 0

Longest transaction: 0.20

Shortest transaction: 0.00

FILE: node1.log

anirbanb2004@Anisoft-Corporation:~/www/loadTest/siegeLog$ siege -c500 -d1 -t5M -

lnphp1.log http://localhost/loadTest/PHP/

** SIEGE 3.0.5

** Preparing 500 concurrent users for battle.

The server is now under siege...

Lifting the server siege... done.

Transactions: 298656 hits

Availability: 100.00 %

Elapsed time: 299.92 secs

Data transferred: 836.80 MB

Response time: 0.00 secs

Transaction rate: 995.79 trans/sec

Throughput: 2.79 MB/sec

Concurrency: 2.27

Successful transactions: 298656

Failed transactions: 0

Longest transaction: 0.24

Shortest transaction: 0.00

FILE: nphp1.log

Summary : Not much difference. Concurrency is little higher and Longest transaction is

also slightly better but nothing real impressive.

500 Concurrent users for 10 minutes with 1 second delay

Page 5: Yet another node vs php

anirbanb2004@Anisoft-Corporation:~/www/loadTest/siegeLog$ siege -c500 -d1 -t10M -

lnode1.log http://localhost:9615

** SIEGE 3.0.5

** Preparing 500 concurrent users for battle.

The server is now under siege...

Lifting the server siege... done.

Transactions: 594697 hits

Availability: 100.00 %

Elapsed time: 599.95 secs

Data transferred: 1666.28 MB

Response time: 0.00 secs

Transaction rate: 991.24 trans/sec

Throughput: 2.78 MB/sec

Concurrency: 3.84

Successful transactions: 594697

Failed transactions: 0

Longest transaction: 0.20

Shortest transaction: 0.00

FILE: node1.log

anirbanb2004@Anisoft-Corporation:~/www/loadTest/siegeLog$ siege -c500 -d1 -t10M -

lnphp1.log http://localhost/loadTest/PHP/

** SIEGE 3.0.5

** Preparing 500 concurrent users for battle.

The server is now under siege...

Lifting the server siege... done.

Transactions: 597276 hits

Availability: 100.00 %

Elapsed time: 599.97 secs

Data transferred: 1673.50 MB

Response time: 0.00 secs

Transaction rate: 995.51 trans/sec

Throughput: 2.79 MB/sec

Page 6: Yet another node vs php

Concurrency: 1.94

Successful transactions: 597276

Failed transactions: 0

Longest transaction: 0.20

Shortest transaction: 0.00

FILE: nphp1.log

Summary: Node is still better at concurrency but yet nothing so impressive so far. I am

still in love with my PHP+Apache

500 Concurrent Users for 15 minutes with 1 second delay

anirbanb2004@Anisoft-Corporation:~/www/loadTest/siegeLog$ siege -c500 -d1 -t15M -

lnode1.log http://localhost:9615

** SIEGE 3.0.5

** Preparing 500 concurrent users for battle.

The server is now under siege...

Lifting the server siege... done.

Transactions: 892874 hits

Availability: 100.00 %

Elapsed time: 899.25 secs

Data transferred: 2501.74 MB

Response time: 0.00 secs

Transaction rate: 992.91 trans/sec

Throughput: 2.78 MB/sec

Concurrency: 3.74

Successful transactions: 892874

Failed transactions: 0

Longest transaction: 0.25

Shortest transaction: 0.00

FILE: node1.log

anirbanb2004@Anisoft-Corporation:~/www/loadTest/siegeLog$ siege -c500 -d1 -t15M -

Page 7: Yet another node vs php

lnphp1.log http://localhost/loadTest/PHP/

** SIEGE 3.0.5

** Preparing 500 concurrent users for battle.

The server is now under siege...

[error] socket: 1011885824 address is unavailable.: Cannot assign requested address

[error] socket: -213448960 address is unavailable.: Cannot assign requested address

[error] socket: -3631360 address is unavailable.: Cannot assign requested address

Lifting the server siege... done.

Transactions: 893948 hits

Availability: 99.96 %

Elapsed time: 899.70 secs

Data transferred: 2504.75 MB

Response time: 0.00 secs

Transaction rate: 993.61 trans/sec

Throughput: 2.78 MB/sec

Concurrency: 2.25

Successful transactions: 893948

Failed transactions: 335

Longest transaction: 1.01

Shortest transaction: 0.00

FILE: nphp1.log

Summary: PHP breaks for these long running large number of concurrent

requests.Server stopped creating threads when it created enough before max outing

server's RAM. But node is standing straight here. Node looks even steady in terms of

the parameters.

1K Concurrent users for 10 minutes with 1 Second delay

anirbanb2004@Anisoft-Corporation:~/www/loadTest/siegeLog$ siege -c1000 -d1 -t10M

-lnode1.log http://localhost:9615

** SIEGE 3.0.5

** Preparing 1000 concurrent users for battle.

Page 8: Yet another node vs php

The server is now under siege...

Lifting the server siege... done.

Transactions: 862079 hits

Availability: 100.00 %

Elapsed time: 599.92 secs

Data transferred: 2415.46 MB

Response time: 0.20 secs

Transaction rate: 1436.99 trans/sec

Throughput: 4.03 MB/sec

Concurrency: 281.62

Successful transactions: 862079

Failed transactions: 0

Longest transaction: 0.55

Shortest transaction: 0.00

FILE: node1.log

anirbanb2004@Anisoft-Corporation:~/www/loadTest/siegeLog$ siege -c1000 -d1 -t10M

-lnphp1.log http://localhost/loadTest/PHP/

** SIEGE 3.0.5

** Preparing 1000 concurrent users for battle.

The server is now under siege...

Lifting the server siege... done.

Transactions: 1193412 hits

Availability: 100.00 %

Elapsed time: 599.82 secs

Data transferred: 3343.82 MB

Response time: 0.00 secs

Transaction rate: 1989.62 trans/sec

Throughput: 5.57 MB/sec

Concurrency: 5.58

Successful transactions: 1193412

Failed transactions: 0

Page 9: Yet another node vs php

Longest transaction: 0.54

Shortest transaction: 0.00

FILE: nphp1.log

Summary: This shows the real advantage of node in terms of concurrency. See here

with increase in number of concurrent users how the concurrency level increased for

Node(281.62) where as for PHP+Apache it is 5.58 still.

Conclusion: So I am convinced from the above test that Node is good at when high

very high concurrency is demanded. Also saw in first part that the nonblocking IO gives

Node an edge for event based application.

At the same time realized that until unless a real huge concurrency is required no need

for Node. The cost at-least at this moment will be higher for the below reason

1. Getting Node experienced people or training your developer to Pro level is

costlier

2. PHP+Apache stack will consume more swap memory (RAM) when

concurrency is more, but Node will be expensive on Processor (CPU) when

performing CPU intensive jobs. Scaling up a server is cheaper when only dealing

with memory or RAM (obviously within thresold) but if we need processor upgrade

(on physical servers) that will be real tough and expensive job.

3. If you are not owning dedicated server hosting Node on cloud is costlier

than any other options

Someone in some forum wrote " You no need to bother and think about the concurrency

of Node until you are managing sites like Google,Facebook or Amazon.

So it is upto Webmasters , depending on their load and traffic and also budget what

they want to use and implement.

GIT link for source codes and Database table

Complete discussion on Node JS forum during this whole test

*Please note:i used mysql_() functions for ease of writing instead of using pdo or

mysqli_() functions.