21 Comments

  1. Just in case, you were using APC right?

    The WP SuperCache plugin is another quick win for WordPress users.

  2. Hi,

    I don’t really get the MaxRequestsPerChild 3 setting here. This setting defines[1] how often the child is killed and respawned (in your case after every three request). Doesn’t killing / spawning children so often actually hurt performance here?

    [1] http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxrequestsperchild

  3. Another idea for that kind of temporary hit on one unique page that I think would save you more than memcache and that would work on any site no matter whether you have a memcache plugin ready to be installed, is to just save the html of the page into some static html file and force-serve that for the particular url that gets all the hits with a RewriteRule /url/blah /path/to.html [L]

    Cheers,
    Jordi

  4. MaxRequestsPerChild 3 …. what??

    I would set that to 1000. If you only let a child serve 3 requests before dying and reforking, you’re going to spend a lot of time in system calls making and destroying processes.

    But to tune Apache properly, you need to install a modern web server like Nginx… hah.

  5. Hi : ) nice article

    Depending on the website and what article is causing the problem you could consider even much dirtier and more efficient tuning hack : )

    To push performance to the limit you could add a temporary rewrite rule to the htaccess and place static html of that page somewhere in web root heheehhe ultimate caching performance 😉

    Sure it an useless hack for dynamic websites but still ….. if its just one article that is killing the server and it will last for a day you might get away with some banners/tags/menus etc being cached statically.

    In the mean time you can do all the above and consider real caching + ‘useless calls reductions’ but hey … your page is showing already so no pressure : )

    on the other note, setting MaxRequestsPerChild = 3 kind of kills the purpose here i guess. what it does is not process cant handle more than 3 concurrent requests but process can handle 3 requests and then dies. when it dies a new process will be spawned so efectively you get new apache spawn every 3 hits : / ouch defaut 0 means process will not die and can run forever. Or did i get something wrong here?

    Art

  6. We’ve seen quite a few of these spikes at several of our sites, and the first times around on a new vm there was one thing that killed us each time: swapping. As soon as Apache gets tired and hogs up a bit more memory than you initially planned and the traffic comes in, things will start swapping. And when things start swapping, you’re out of luck.

    I’d also suggest taking a look at varnish, which you can drop in quite quickly with the standard settings to be able to handle a very high load. The default configuration (depending on the version you install, probably) will however skip any cache handling for requests with cookies, which may come from tracking scripts such as google analytics. There’s pre-made rules to get around that problem for certain cookies, or you can just allow it to cache all content, regardless of any current cookies.

    The key to getting varnish up and running is to simply move apache to port 81, set that apache as the backend in varnish and put varnish on port 80.

  7. Author

    Nope, APC was on the “to-do list”. The problem was, this server’s my side project site, and work has been eating every waking hour for a few months so progress along the TDL has been seriously slow.

    WP SuperCache _is_ installed; but since this was a three-minute guide, several good measures weren’t mentioned. Installing WP-SuperCache or WP-TotalCache, changing out from Apache to lighttp or nginx, installing more RAM (turns out I can’t do that with this box 🙁 ) — all very good approaches which I’ve tried in the past, but you can’t get them done in three minutes 😀 The whole point of this post was to be the server version of first aid, not scheduled surgery, and if you’d ever seen or received CPR, you know exactly what I mean when I say that first aid’s not exactly clean and tidy 😀

  8. Author

    In practice here, increasing MaxRequestsPerChild in the prefork MPM drove load up, not down. It’s not supposed to do that under normal usage, you’re completely correct. I have two theories as to why it acted oddly:

    • There may be a dodgy plugin or module installed that’s causing that for me (if your child leaks memory, MaxRequestsPerChild is your control mechanism).
    • Or it could be the nature of the traffic – if you have a lot of high bounce rate traffic coming in (and if it’s slashdot or reddit or whomever, that’s what you see), then nonstandard settings may work better – KeepAlive off, for example, which is the opposite of what you want normally. You want the processes torn down rapidly instead of hanging about waiting on someone who’s hit the stumble button twenty seconds ago and is now off browsing fark while you wait on them.
  9. Author

    Yup, that works too… until someone tries to comment on that page, at which point it goes a bit sideways.
    But yes, for anything that can be made static, that’s how to do it. Here though, WP-SuperCache was doing that and the load was still passing 130 at times (I’m actually surprised the server was still responsive at the shell at all at those points).

  10. Author

    Yup, like I said to Mikko, it’s very odd. But what I saw here was that when that was increased (I had it set to 2000 at one point), load shot up much faster; turning it down to single digits improved performance. I have theories as to why; I don’t know for certain and it’s kindof bugging me a bit if I’m blunt about it.

  11. Author

    Jordi beat you to it Artur 😀
    Doesn’t work so well here, because comments were on, but at the worst point I used WP-SuperCache’s lockdown function which does almost exactly what you’re suggesting, but in an easier-to-manage way.

  12. Author

    Yup Mats, it’s the swap that kills you every time! That’s the idea behind ServerLimit – don’t let Apache run too many processes and trigger that first swap, because if it swaps once, odds are that that’s the first stumble and a few minutes later the whole server faceplants at speed.

    Varnish is something I’ve been talking about with Conor (the sysadmin for boards.ie) actually, but it’s not really a three-minute first aid thing. Even memcached is a bit of a stretch for the first aid mindset 😀





  13. Next to WP Super Cache I can recommend Semiologic Cache from the SemPro package. It has good memcache support and goes the needed bit better than WP Super Cache. But that’s the problem: Don’t blame Apache / MySql for the misuse WordPress plays on them.

    Some more information about caching on wp can be found over there @ ask apache.


  14. You want the processes torn down rapidly instead of hanging about waiting on someone who’s hit the stumble button twenty seconds ago and is now off browsing fark while you wait on them.

    I have to disagree here. The control method for that scenario is KeepAliveTimeout. I would suggest changing the default 15 to much lower, such as 2 seconds. This prevents the server from keeping a process reserved for 15 seconds.

    Forking processes can put a serious load on your server. It’s dog slow, and really bogs down your server especially if it has to fork dozens of processes fast, like when you’re slashdotted. You only want to tear down processes when they’re leaking memory, which you mentioned. Therefore, I have found the following pattern works very well.

    Set MinSpareServers to around 20 so you have enough processes started and waiting to serve. Set MaxSpareServers a bit higher, such as 30. Set MaxRequestsPerChild to 1000 or something high, so you only kill processes when they done plenty of work. MaxClients should be set to the amount of processes your apache can run without swapping, and definitely not too high. You can calculate this number by dividing the amount of RAM available to Apache by the maximum memory used by any Apache process. ServerLimit is set automatically and can be removed from the config.

    Also, do not underestimate the effect of a byte-code cache such as APC, or Zend Optimizer+. It will avoid the PHP engine having to compile your PHP application for each and every request and will speed up each request quite a lot, at the expense of some memory. It wil help a lot.

    The rest of your tips are great, so thanks for the article.


  15. GREAT! Messed up the GD apache2.conf file.

    Seems that by following your tutorial on performance tuning, I mistakenly changed the instead of the one you suggested. Now whenever I hit restart in debian squeeze for apache2 and mysql, everything seems ok.

    Except when I goto my site on the net where there is justy a blank screen.

    NOW what do I do?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.