Can't find bottleneck on LAMP stack with APC and Varnish
I'm having some performance issues on my 1024 Linode. I'm running Apache, MariaDB and PHP (as mod-php5 with the Prefork-MPM). The Linode serves about 15 sites, 90% of them WordPress blogs and traffic is light, just that load times were pretty low.
I was trying to get some more juice out of it and read a lot of tutorials and articles. In the end I installed Varnish and moved Apache to port 8080. I also installed APC. The most relevant site (the one I've done all the testing on) has also W3Total Cache installed.
The issue is that I see no improvement. Whatsoever. I expected a huge gain with Varnish, and yet I get no improvement. I monitored varnishstats and varnishhist and I know for sure that Varnish is serving cache, it's just taking the exact same time Apache does.
These are my results with ab so far after several tests (non scientifically averaged):
- without
+ with
Test Requests per second
---- -------------------
-Varnish: 8.02
+V -APC -W3TC : 8.38
+V -APC +W3TC : 7.70
+V +APC -W3TC : 8.21
+V +APC +W3TC : 7.91
No significant differences, just a bit of variability. Normal output with everything on (connection times very similar across the different tests):
Connection Times (ms)
min mean[+/-sd] median max
Connect: 173 336 115.1 337 1322
Processing: 400 827 733.0 578 5973
Waiting: 181 376 326.0 318 2274
Total: 638 1162 726.0 923 6274
Percentage of the requests served within a certain time (ms)
50% 923
66% 984
75% 1137
80% 1219
90% 1927
95% 2761
98% 3317
99% 6274
100% 6274 (longest request)
All these tests are run at a concurrency of 10, way below my MaxClients, so the server shouldn't even sweat. My apache conf:
StartServers 2
MinSpareServers 5
MaxSpareServers 10
MaxClients 25
MaxRequestsPerChild 5000
Other relevant info:
$ free -m
total used free shared buffers cached
Mem: 1000 900 100 0 41 500
-/+ buffers/cache: 357 643
Swap: 511 6 505
During the tests with ab the system isn't stressing much at all:
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 6940 101600 42864 514068 0 0 1 7 12 16 1 0 99 0
0 0 6940 101716 42864 514068 0 0 0 4 223 339 0 0 100 0
0 0 6940 101576 42864 514068 0 0 0 0 399 389 0 0 100 0
0 0 6940 101188 42864 514068 0 0 0 0 426 361 0 0 100 0
0 0 6940 101220 42864 514068 0 0 0 0 426 377 0 0 100 0
0 0 6940 101180 42864 514068 0 0 0 0 422 357 0 0 100 0
0 0 6940 101120 42864 514068 0 0 0 56 516 386 0 0 100 0
0 0 6940 101216 42864 514068 0 0 0 0 498 382 0 0 100 0
0 0 6940 101024 42872 514060 0 0 0 12 506 386 0 0 100 0
0 0 6940 101120 42872 514196 0 0 128 0 530 392 0 0 100 0
1 0 6940 101152 42872 514196 0 0 0 0 546 402 0 0 100 0
0 0 6940 101120 42872 514196 0 0 0 0 504 375 0 0 100 0
0 0 6940 101088 42872 514196 0 0 0 0 484 377 0 0 100 0
0 0 6940 101152 42872 514196 0 0 0 0 546 398 0 0 100 0
0 0 6940 101184 42880 514196 0 0 0 12 380 347 0 0 100 0
0 0 6940 101248 42880 514196 0 0 0 0 231 526 0 0 100 0
0 0 6940 101248 42880 514196 0 0 0 4 188 327 0 0 100 0
0 0 6940 101248 42880 514196 0 0 0 0 179 316 0 0 100 0
Varnish is using a bit of swap as calculated with the swapusage script. Should there be two instances there?
PID=22369 swapped 320 KB (varnishd)
PID=22370 swapped 300 KB (varnishd)
Varnish conf:
DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,128m"
And the vcl definition is pasted here
I've also pasted my mysql config on pastebin: http://pastebin.com/cKeDFRaA
I really don't understand what's going on. If I saw some improvement with varnish and the caches I would've been happy, even if the load times still weren't great. But what really confuses me is that Apache is able to serve the same number of requests than Varnish. I hope someone can point out anything that seems strange or at least tell me what to try or where to keep on looking. Thanks.
2 Replies
Also if you pop this
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
into your varnish config then it'll add a header into all page requests saying if the cache has been used or not which is very helpful for debugging.
After much searching and prodding, I've been playing around with my APC settings and monitoring PHP very closely. Some tweaking has got the requests per second up to 15 (peaking at 20 in some tests). I tried raising the concurrency of the tests and even at 100 I get a mean time per request of 488.151 [ms]. Much more reasonable.
I was seeing very high "Cache full count" in APC and a lot of "Unable to allocate memory for pool" errors in the PHP error log. I've pushed up APCs cache size to 190M from 128M, cutting some room from MySQL buffers that were too high. I haven't got a lot of room to work there, free memory is really low and MySQL is swapping a bit…
Should I further decrease MySQL memory usage? Where is the best place to cut in the MySQL config?