Friday, June 18, 2010

Performance tuning on Apache, PHP, MySQL, WordPress

SkyHi @ Friday, June 18, 2010

Introduction

This tutorial is covering the web server performance tunings on MySQL, PHP and Apache, WordPress and BuddyPress or general web hosting purpose, the tuning example is based on CentOS 5.

The key of the following performance tuning is focus on memory and caching, most of people host a web site or forum or blog without any tunings or even use the all out-of-box setting.

OS Tuning

/etc/sysctl.conf

Share Memory


#512MB
kernel.shmall = 536870912
kernel.shmmax = 536870912
fs.file-max = 16384



MySQL Tuning

MySQL default setting is very inefficient, here is a baseline for a web access by >200 concurrent users running with Joomla, wordpress, phpbb..etc. DB query cache is quite important for a large website, it reduce lot of disk I/O, minimize the wait time for every of same query.

/etc/my.cnf

[mysqld]
key_buffer = 64M
sort_buffer = 1M
join_buffer = 1M
max_allowed_packet = 8M
max_heap_table_size = 16M
table_cache = 1024
sort_buffer_size = 8M
read_buffer_size = 1M
read_rnd_buffer_size = 768K
myisam_sort_buffer_size = 48M
thread_cache_size = 512
query_cache_type = 1
query_cache_limit = 4M
query_cache_size = 64M
tmp_table_size = 16M
# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 4

max_write_lock_count = 1 #To force MySQL to temporarily elevate the priority of all SELECT statements that are waiting for a table after a specific number of inserts to the table occur. This allows READ locks after a certain number of WRITE locks.
low_priority_updates = 1

[isamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M

[myisamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M


Apache Web Server Tuning

Default MPM setting is prefork, which consumes a lot of memory when your web site under stress. So considering to activate worker MPM is better idea to double up your current web capacity without adding additional hardware.

Switching to worker MPM with PHP will not gain any performance boost if you don’t have proper object cache or page cache, however running PHP apache module with prefork MPM is faster then worker MPM in CGI mode.
http://www.serverwatch.com/tutorials/article.php/3436911/Optimizing-Apache-Server-Performance.htm

/etc/sysconfig/httpd

HTTPD=/usr/sbin/httpd.worker


/etc/httpd/conf/httpd.conf


StartServers 6
MaxClients 300
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 2000



Apache Prefork vs Worker
http://www.camelrichard.org/apache-prefork-vs-worker

Running PHP5 with Apache worker MPM

When you switched to worker MPM, you may immediately encountered errors on PHP module. Yes, you need to change the php from apache module to PHP CGI, it’s PHP thread safe issues on worker MPM.

Install FastCGI

wget "http://www.fastcgi.com/dist/mod_fastcgi-current.tar.gz"
cp Makefile.AP2 Makefile
make top_dir=/usr/lib64/httpd ## or make top_dir=/usr/lib/httpd ## for 32bit
make install


Add the LoadModule entry in /etc/httpd/conf/httpd.conf

LoadModule fastcgi_module modules/mod_fastcgi.so


Add a php.fcgi file in /var/www/cgi-bin/

#!/bin/bash
PHP_CGI=/usr/bin/php-cgi
PHP_FCGI_CHILDREN=16
PHP_FCGI_MAX_REQUESTS=1000
export PHP_FCGI_CHILDREN
export PHP_FCGI_MAX_REQUESTS
exec $PHP_CGI


and

chmod +x /var/www/cgi-bin/php.fcgi


Switch PHP settings to PHP CGI in /etc/httpd/conf.d/php.conf

#LoadModule php5_module modules/libphp5.so
#AddHandler php5-script .php
#AddType text/html .php
#DirectoryIndex index.php
#AddType application/x-httpd-php-source .phps

## FastCGI Handler for Apache Worker

AddHandler php5-fastcgi .php
Action php5-fastcgi /cgi-bin/php.fcgi
DirectoryIndex index.php


http://www.cyberciti.biz/tips/rhel-centos-fedora-apache2-fastcgi-php-configuration.html

PHP 5.2

If you still running php 5.0, please upgrade it.
Put the following lines into /etc/yum.repos.d/c5-testing.repos

[c5-testing]
name=CentOS-5 Testing
baseurl=http://dev.centos.org/centos/$releasever/testing/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://dev.centos.org/centos/RPM-GPG-KEY-CentOS-testing


remove all existing PHP5 and PECL rpm packages and run

yum install \
php \
php-mbstring \
php-ldap \
php-mysql \
php-mcrypt \
php-cli \
php-gd \
php-xml \
php-devel \
php-bcmath \
php-xmlrpc \
php-common \
php-soap \
php-pdo \
php-imap


Install memcached

memcached is a high-performance memory object caching system intended to speed up dynamic web applications by alleviating database load.

yum install memcached


/etc/sysconfig/memcached

PORT="11211"
USER="nobody"
MAXCONN="1024"
CACHESIZE="256"
OPTIONS=""


http://pswebsolutions.wordpress.com/2009/08/26/how-to-install-memcache-on-linux-server/

Install PHP memcache.so

cd
phpize
./configure --enable-memcache
make
cp memcache.so /usr/lib64/php/modules/


Enable it in /etc/php.ini

extension=memcache.so


http://www.howtoforge.com/php_memcache_centos5.0

Install eAccelerator

eAccelerator is a free open-source PHP accelerator, optimizer, and dynamic content cache. It increases the performance of PHP scripts by caching them in their compiled state, so that the overhead of compiling is almost completely eliminated. It also optimizes scripts to speed up their execution. eAccelerator typically reduces server load and increases the speed of your PHP code by 1-10 times.

wget "http://bart.eaccelerator.net/source/0.9.5.2/eaccelerator-0.9.5.2.tar.bz2"
tar xvfj eaccelerator-0.9.5.2.tar.bz2
cd eaccelerator-0.9.5.2
phpize
./configure
make
make install
mkdir /tmp/eaccelerator
chmod 777 /tmp/eaccelerator


/etc/php.ini

[eaccelerator]
zend_extension="/usr/lib64/php/modules/eaccelerator.so"
eaccelerator.shm_size="64"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"
eaccelerator.log_file = "/var/log/httpd/eaccelerator_log"


http://www.php.ph/2007/12/21/centos-5-eaccelerator-installation/

Compress PHP output using ob_gzhandler

/etc/php.ini

output_buffering = On
output_handler = ob_gzhandler
zlib.output_compression = Off


Apache deflate for contents compression

The mod_deflate module provides the DEFLATE output filter that allows output from your server to be compressed before being sent to the client over the network, it helps to improve contents transfer over network, it doesn’t really helps to speed up your web, but it speed up the content transfer flow and gain more user access through the same network without additional bandwidth.


# Set compression for: html,txt,xml,js,css
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/javascript text/css application/x-javascript
# Deactivate compression for buggy browsers
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.0[678] no-gzip
BrowserMatch bMSIE !no-gzip !gzip-only-text/html
# Set header information for proxies
Header append Vary User-Agent



http://httpd.apache.org/docs/2.0/mod/mod_deflate.html

Recommended WordPress Plugins

WP Super Cache
- Static HTML caching

WP Object Cache for memcached

wp-config.php

define( 'WP_CACHE', true );
define(’WP_POST_REVISIONS’, false);


Conclusion

Always measure the performance with or without tuning, the tuning parameters is just case by case. Some PHP scripts running with Fastcgi isn’t as fast as module, so you have to compared it side by side.

http://www.gnegg.ch/2006/08/mod_php-lighttpd-fastcgi-whats-fastest/