I’ve been reading a few other blogs about how some people have implemented NginX as an accelerator for their Apache-based websites.
NginX outperforms Apache on small- to mid-range servers when it comes to static file handling, particularly because it is event driven.
The downside of NginX is that PHP can only be used with FastCGI. In general, most how-to’s explain how to implement PHP FastCGI with NginX using TCP. This is adding extra overhead and slows PHP to a crawl. A better solution is to use the UNIX sockets instead, which is explained well in Till’s blog.
But even using UNIX sockets, the PHP FastCGI and NginX combination is not as fast as Apache can handle PHP requests. For this reason, NginX can act as a great accelerator for static files while Apache deals with all the PHP requests. Even with the extra TCP overhead between NginX and Apache, this makes for quite a speedy combination.
Thinking logically, some people figured that loading static files from RAM memory instead of the harddrive must make things even faster. But that really depends…
Using Memcached
Loading static files from RAM memory is accomplished using the memcached daemon and the NginX memcached module. Various how-to’s describe the procedure along these lines:
- A script that’s run at boot time, using a CRON or other method, that loads static files from the harddrive into memcached (RAM).
- NginX is configured to load a requested file from memcached and if failed to do so, load it directly from the harddrive instead.
But unfortunately the NginX memcached module is only capable of TCP communications. If memcached is located on the same server, it would have made more sense to use UNIX sockets instead (just like PHP FastCGI over UNIX sockets).
See, in my case there was so much overhead that NginX slowed to less than 8,000 requests per second. To put this in perspective, Apache was capable of serving 18,898 static 100-byte files per second on the same server.
So using memcached is only worth it if you are caching files that are spread over several back-end servers or are dynamic of nature (ie., PHP output that changes very little). Not if these files are local to NginX, especially with NginX’s highly efficient caching methods.
Speedy NginX
Now, how much faster is NginX compared to Apache when it comes to static files anyway? Well, I’ve have some non-definitive numbers for you, obtained on a low-range server:
Server:
Intel(R) Core(TM)2 Duo CPU E6750 @ 2.66GHz, 2x750GB Seagate Barracuda 7200.11 32M RAID-1, 4GB RAM, Debian Lenny (5.0) i386 (2.6.24-7 Ubuntu-based, back-ported kernel)
Test parameters:
ab -k -c5 -t10000 http://<server>/100.html
Apache:
Server Software: Apache/2.2.9
Server Hostname: <server>
Server Port: 80
Document Path: /100.html
Document Length: 100 bytes
Concurrency Level: 5
Time taken for tests: 2.646 seconds
Complete requests: 50000
Failed requests: 0
Write errors: 0
Keep-Alive requests: 49508
Total transferred: 22577856 bytes
HTML transferred: 5000000 bytes
Requests per second: 18898.08 [#/sec] (mean)
Time per request: 0.265 [ms] (mean)
Time per request: 0.053 [ms] (mean, across all concurrent requests)
Transfer rate: 8333.56 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 0 0 0.5 0 49
Waiting: 0 0 0.5 0 49
Total: 0 0 0.5 0 49
Percentage of the requests served within a certain time (ms)
50% 0
66% 0
75% 0
80% 0
90% 0
95% 0
98% 1
99% 1
100% 49 (longest request)
NginX:
Server Software: nginx/0.7.61
Server Hostname: <server>
Server Port: 80
Document Path: /100.html
Document Length: 100 bytes
Concurrency Level: 5
Time taken for tests: 1.928 seconds
Complete requests: 50000
Failed requests: 0
Write errors: 0
Keep-Alive requests: 49502
Total transferred: 19397510 bytes
HTML transferred: 5000000 bytes
Requests per second: 25937.28 [#/sec] (mean)
Time per request: 0.193 [ms] (mean)
Time per request: 0.039 [ms] (mean, across all concurrent requests)
Transfer rate: 9826.54 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 0 0 0.1 0 5
Waiting: 0 0 0.1 0 5
Total: 0 0 0.1 0 5
Percentage of the requests served within a certain time (ms)
50% 0
66% 0
75% 0
80% 0
90% 0
95% 0
98% 0
99% 0
100% 5 (longest request)
This is the setup I’m using on all the web servers I am deploying, NginX as the front-end and a number of Apache servers at the back-end to deal with non-static files, including PHP.
Related posts:
