Optimization of Apache webserver with Varnish installation

Comments Off on Optimization of Apache webserver with Varnish installation

Apache is a powerful, reliable and capable web server. The single biggest hardware issue affecting Apache webserver performance is RAM. In Linux by default Apache use Prefork MPM which is memory intensive module. So, server with less memory struggles if requests increase. Addressing the issue, many server experts suggest two things

  1. Replace Apache by Nginx which is light and fast webserver
  2. Use Worker MPM and install PHP-FPM module

There are many reasons you would not like to replace your favorite webserver and you are not so technical to do that. But, you can overcome the situation using Varnish as frontend caching server and Apache as backend webserver.
In this post I will show the optimization of Apache webserver with Varnish installation keeping Apache modules as it is.

  1. Check your total and average Apache process size by the command in Redhat/CentOs
    #ps -ylC httpd | awk '{x += $8;y += 1} END {print "Apache Memory Usage (MB): "x/1024; print "Average Process Size (MB): "x/((y-1)*1024)}'
    Apache Memory Usage (MB): 679.89
    Average Process Size (MB): 19.42
    Configure appropriate number of child processes.
  2. Check which MPM is working. By default in Unix/Linux it is prefork.
    #  httpd -V | grep "Server MPM"
    Server MPM:     Prefork
  3. Check prefork configuration
    Under prefork configuration() , Each process handles one connection at a time. The default configuration of Apache in Redhat/CentOs machine ( /etc/httpd/conf/httpd.conf) is

    <IfModule prefork.c>
    StartServers       8
    MinSpareServers    5
    MaxSpareServers   20
    ServerLimit      256
    MaxClients       256
    MaxRequestsPerChild  4000
    </IfModule>

    The most important parameters are MaxClients and ServerLimit. MaxClients=256 means, your sever will accept 256 request simultaneously and ServerLimit=256 means Apache is capable of processing 256 process simultaneously. The Maxcleints and ServerLimit should be kept always same in prefork settings. This is good for medium traffic webpage. But even this default configuration can make your webserver hugely loaded due to lacking of memory. As instance, your server is processing 256 simultaneous request. So 256 child processes are spawned and child process consumes on average 15MB memory(we already know it) . Then Apache needs

    15*256=3840MB memory

    10% of totals memory always should be reserved for OS. If your server hosts Database also like MySQL and it requires 1GB memory, your memory requirement goes to

    3840+1024=4864MB

    As we consider your physical server has 4GB memory , you should tune Maxclients and ServerLimit. The calculation is follows

    Memory For Database: 1024MB
    10% reserve for OS : 410MB
    Remaining: 4*1024-(1024+410)=2662MB
    MaxClients=2662/Average Process Size=2662/19.42=137
    

    So for Server with 4GB memory has the following configuration

    <IfModule prefork.c>
    StartServers       8
    MinSpareServers    5
    MaxSpareServers   20
    ServerLimit      137
    MaxClients       137
    MaxRequestsPerChild  4000
    </IfModule>

    If it is only webserver then you can allocate more memory to Apache. If you have 8GB memory then calculation will be

    Memory For Database: 1024MB
    10% reserve for OS : 819MB
    Remaining: 8*1024-(1024+819)=6349MB
    MaxClients=6349/Average Process Size=6349/19.42=327
    

    So, the more physical memory, the more value of MaxClients and ServerLimit can be configured.

Now you have Apache tuned. But along with Apache, Varnish will significantly improve your performance as it responses static pages from cache. After installation of Varnish, for same number of simultaneous requests less requests go to Apache as many of them will be served by Varnish. So, you can consider your webserver simultaneous requests handling capacity is two or three times than earlier. Here I will describe how to install Varnish in Redhat/CentOs and configure it to work with Apache.

Installation of Varnish caching server

  1. Check Server Architecture
    # uname -a
    Linux localhost.localdomain 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
    
  2. Get the latest stable RPMs repo from the page https://www.varnish-cache.org/installation/redhat and install it
    #rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el6/noarch/varnish-release/varnish-release-3.0-1.el6.noarch.rpm 
    

     

  3. Install Varnish by yum command
    # yum install varnish
  4. Edit /etc/sysconfig/varnish file
    # vi /etc/sysconfig/varnish
  5. Edit the following lines
    VARNISH_LISTEN_PORT=80
    

    This is the listing port of Varnish and it is obviously http port(80). http traffic will come first Varnish then forwarded to Apache. So Apache listening port should be changed other than 80.

    VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
    VARNISH_ADMIN_LISTEN_PORT=6082
    

    These are the listening address and port to run some administrative command.
    Save and exit out of that file.

  6. Open up the /etc/varnish/default.vcl file
    # vi /etc/varnish/default.vcl
    

    This file tells varnish where to look for the webserver content. Although Apache listens on port 80 by default, we will change the settings for it later. Within this file, we will tell varnish to look for the content on port 8080. The configuration should like this:

    backend default {
      .host = "127.0.0.1";
      .port = "8080";
    }
    
  7. Configure Apache for working with Varnish
    So far we have told varnish that Apache ports will be running on 8080. However the default settings for Apache are still on port 80. We will correct the discrepancy now.
    Open up the Apache configuration file:

    # vi /etc/httpd/conf/httpd.conf
    

    Change the port number for both the NameVirtualHost and the Listen line to port 8080, and the virtual host should only be accessible from the localhost. The configuration should look like this:

    Listen 127.0.0.1:8080
    NameVirtualHost 127.0.0.1:8080
    

    The Virtual Host should also be set to port 8080, and updated line looks like this:

     <VirtualHost 127.0.0.1:8080>
        ServerAdmin webmaster@dummy-host.example.com
        DocumentRoot /var/www/html/results
        ServerName www.example.com
        ErrorLog logs/example.com-error_log
        CustomLog logs/example.com_log common
    </VirtualHost>

    Save and exit the file.

  8. Restart Apache and Varnish to make the changes effective
    # /etc/init.d/httpd restart
    # /etc/init.d/varnish restart
    
  9. Allow port 8080 on your firewall if you have firewall enabled
  10. # iptables -I  INPUT -p tcp   --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT

The above configuration is a quick method of optimization of Apache webserver with Varnish installation; and any one can within 15 minutes complete this and enjoy the benefit.