Sunday 12 January 2014

Apache Performance Tunning / Apache Optimization

Apache Optimization


Apache (HTPD) is  most popular and widely used web server around the globe. It comes with multiple modules. The term MPM is used for multiprocessing module. We can check for default mpm by running this command “ httpd -l ”

[kulshresht@dev server ~]#  httpd -l
Compiled in modules:
  core.c
  prefork.c
  http_core.c
  mod_so.c

There could be n number of reasons for bad performance of your website and one of the possibility can be that Apache is not able to handle load. Apache server performance can be improved/enhanced by adding additional hardware resources such as RAM, faster CPU, etc. But most of the time it's custom server configuration which will play a bigger role rather than just adding extra hardware. We will discuss here about those configuration so that we can make Apache performance better using the Apache MPM prefork module.

Apache 2 is available with following 2 MPM modules: Prefork & Worker

To check which MPM module it is running on your server, use below command:
[kulshresht@dev server~]$ /usr/sbin/httpd -l | egrep "prefork|worker"
prefork.c

The most important configuration file for Apache is httpd.conf which is located at /etc/httpd/conf [for Centos].We will try to tune this configuration file.For example:
vim /etc/httpd/conf/httpd.conf

Will write a sample configuration first and then try to explain all parameters and how to tune them one by one. 
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# ServerLimit: maximum value for MaxClients for the lifetime of the server
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves

<IfModule prefork.c>
StartServers       20
MinSpareServers    20
MaxSpareServers   50
ServerLimit      2000
MaxClients       2000
MaxRequestsPerChild  2000
</IfModule>

StartServers : StartServers directive sets how many server processes are created upon start up. Since web server dynamically kills and creates server processes based on traffic load, it is not necessary to change this parameter.

MinSpareServers and MaxSpareServers:
These values are only used with the prefork MPM. They adjust how the Apache HTTP Server dynamically adapts to the perceived load by maintaining an appropriate number of spare server processes based on the number of incoming requests. The server checks the number of servers waiting for a request and kills some if there are more than MaxSpareServers or creates some if the number of servers is less than MinSpareServers.
The default MinSpareServers value is 5; the default MaxSpareServers value is 20. These default settings should be appropriate for most situations. Be careful not to increase the MinSpareServers to a large number as doing so creates a heavy processing load on the server even when traffic is light.

MinSpareThreads and MaxSpareThreads:
These values are only used with the worker MPM. They adjust how the Apache HTTP Server dynamically adapts to the perceived load by maintaining an appropriate number of spare server threads based on the number of incoming requests. The server checks the number of server threads waiting for a request and kills some if there are more than MaxSpareThreads or creates some if the number of servers is less than MinSpareThreads.
The default MinSpareThreads value is 25; the default MaxSpareThreads value is 75. These default settings should be appropriate for most situations. The value for MaxSpareThreads must be greater than or equal to the sum of MinSpareThreads and ThreadsPerChild, else the Apache HTTP Server automatically corrects it.

ThreadsPerChild: This value is only used with the worker MPM. It sets the number of threads within each child process. The default value for this directive is 25.

MaxClients: MaxClients sets a limit on total number of concurrent connections. Will let you know in a while about how to determine that value.The server's default is set to 150 regardless of the MPM in use.There is no point in keeping this value very high until and unless you have huge traffic serving site. A high value can lead to a complete server hang in case of a DOS attack. A value too low can create timeout problems for your clients if the limit is reached.So take appropriate decision after seeing production behavior during high load by using below technique.

Use below shell script to determine an average amount of memory consumed by one Apache process. In addition to that it will show total amount of memory consumed by all Apache processes.

[kulshresht@server1 ~]$ ps -ylC httpd | awk '{x += $8;y += 1} END {print "Apache Memory Usage (MB): "x/1024; print "Average Proccess Size (MB): "x/((y-1)*1024)}'
Apache Memory Usage (MB): 821.441
Average Proccess Size (MB): 6.08475
**Use httpd for CentOS in above shell script. Use apache2 otherwise.

Execute the above script several times during high load to get optimum result.Now we know average amount of memory consumed by Apache and total amount of memory of your server, it is possible to calculate value to be used for MaxClients setting. For example, if in average one of your Apache process consumes 6MB RAM and server RAM is 16GB, and you want to leave 8GB for the rest processes, then:
MaxClients = (16GB – 8GB)/6MB = 1365

ServerLimit : This value should be same as MaxClients. But MaxClient setting can be changed on the fly without restarting Apache whereas ServerLimit new value needs Apache restart.

MaxRequestsPerChild: MaxRequestsPerChild sets the total number of requests each child server process serves before the child dies. The main reason for setting MaxRequestsPerChild is to avoid long-lived process induced memory leaks. The default MaxRequestsPerChild for the prefork MPM is 4000 and for the worker MPM is 0.We should definitely set some value for this parameter (pls do not ignore this ) to avoid memory leak by long lived process in worst case scenario.

If you still wish to switch to "worker" module, it is sufficient to uncomment this directive in the /etc/sysconfig/httpd file:
# grep HTTPD= /etc/sysconfig/httpd
#HTTPD=/usr/sbin/httpd.worker
and restart Apache:
/etc/init.d/httpd restart

References:
http://httpd.apache.org/docs/current/mod/prefork.html
http://www.centos.org/docs/4/4.5/Reference_Guide/s3-apache-minmaxsparethreads.html
http://kb.parallels.com/en/113007
https://code.google.com/p/check-httpd-limits/
http://www.zarafa.com/wiki/index.php/Apache_tuning

Friday 10 January 2014

Redis cache monitoring / Automating telnet session using bash scripts

Below is a combination of shell & expect script which helps to monitor Redis cache.

Get your shell script [redistest.sh] embedded in Nagios/Zenoss [ or whichever monitoring tool you are using ] to set up monitoring for redis cache.

redistest.sh

#!/bin/bash
set -x
var=`/tmp/redistest| awk '{print $1}'|grep PONG|cut -c2-5`
echo $var
if [ "$var"  == "PONG" ]
then
echo "Redis is now running fine |"
exit 0
else
echo "Redis is having some issue |"
exit 2
fi
echo "Unknown error|"
exit 3
redistest

#!/usr/bin/expect
set timeout 5
set serverip "10.50.16.10"
set port 6379
spawn telnet $serverip $port

send "ping\r"
expect "+PONG"
exit

Reference: