Dirty Wordpress APC caching
February 13, 2010 — Florent ClairambaultOne or two weeks ago, I made a simple AB benchmarking test on a PHP site I built, it was ok. Then I did the same test on this blog and well… It was freaking slow… On 100 pages with 10 concurrent access, it took 3.5 to 10s to render. Well, I thought I should remove all these plugins I installed to make me and my blog famous (they didn’t perform well). It reduced the generation time by something like 100 ms.
So I had the brilliant idea to put everything in an APC cache, someone had the same idea.
So I approximatively did the same thing :
In the beginning of the index.php file :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | if ( $_SERVER['REQUEST_METHOD'] == 'GET' ) { // This key will identify the page used $cacheKey = 'WP_'.$_SERVER['HTTP_HOST'].md5( $_SERVER['REQUEST_URI'] ); // We try to get this page $cacheData = apc_fetch($cacheKey); // If we got something if (is_array( $cacheData )) { // We give each header foreach( $cacheData[0] as $h ) header( $h ); // And the content die($cacheData[1]); } // If we're still here, we have no cache, so we'll start caching right now ob_start(); } |
In the end of the index.php file :
1 2 3 | // We have a cache key, it means we have something to cache if ( $cacheKey ) apc_store( $cacheKey, array( headers_list(), ob_get_contents() ), 900 ); |
And once it’s cached it performs well, to make it short it can serve in mean time of 1 ms and gives a general bandwidth of 200 MB/s. As you can guess, these tests are made locally and this is normal.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | [root@s15342968 ~]# ab -n 100 "http://florent.clairambault.fr/"
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking florent.clairambault.fr (be patient).....done
Server Software: Apache/2.2.8
Server Hostname: florent.clairambault.fr
Server Port: 80
Document Path: /
Document Length: 161165 bytes
Concurrency Level: 1
Time taken for tests: 0.119899 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 16156100 bytes
HTML transferred: 16116500 bytes
Requests per second: 834.04 [#/sec] (mean)
Time per request: 1.199 [ms] (mean)
Time per request: 1.199 [ms] (mean, across all concurrent requests)
Transfer rate: 131585.75 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 1 1 0.0 1 1
Waiting: 0 0 0.1 0 1
Total: 1 1 0.0 1 1
Percentage of the requests served within a certain time (ms)
50% 1
66% 1
75% 1
80% 1
90% 1
95% 1
98% 1
99% 1
100% 1 (longest request) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | [root@s15342968 ~]# ab -n 100 -c 10 "http://florent.clairambault.fr/"
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking florent.clairambault.fr (be patient).....done
Server Software: Apache/2.2.8
Server Hostname: florent.clairambault.fr
Server Port: 80
Document Path: /
Document Length: 161165 bytes
Concurrency Level: 10
Time taken for tests: 0.47897 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 16156100 bytes
HTML transferred: 16116500 bytes
Requests per second: 2087.81 [#/sec] (mean)
Time per request: 4.790 [ms] (mean)
Time per request: 0.479 [ms] (mean, across all concurrent requests)
Transfer rate: 329394.31 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 1 4 1.3 4 10
Waiting: 0 1 1.0 1 4
Total: 1 4 1.3 4 10
Percentage of the requests served within a certain time (ms)
50% 4
66% 4
75% 5
80% 5
90% 6
95% 6
98% 8
99% 10
100% 10 (longest request) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | [root@s15342968 ~]# ab -n 10000 -c 10 "http://florent.clairambault.fr/" This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking florent.clairambault.fr (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Finished 10000 requests Server Software: Apache/2.2.8 Server Hostname: florent.clairambault.fr Server Port: 80 Document Path: / Document Length: 161165 bytes Concurrency Level: 10 Time taken for tests: 7.898135 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 1616094683 bytes HTML transferred: 1612133495 bytes Requests per second: 1266.12 [#/sec] (mean) Time per request: 7.898 [ms] (mean) Time per request: 0.790 [ms] (mean, across all concurrent requests) Transfer rate: 199821.47 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.9 0 7 Processing: 2 6 1.6 7 13 Waiting: 0 1 1.4 1 8 Total: 2 7 1.5 7 16 Percentage of the requests served within a certain time (ms) 50% 7 66% 8 75% 8 80% 8 90% 9 95% 10 98% 11 99% 11 100% 16 (longest request) |
By the way, APC 3.0.x really has a deadlock bug. It totally crashes Apache making it accept but never reply connections. Everyone should update to APC 3.1.