Saturday 24 Sep 2011

Speed up web server with MemCache

PHPSometimes some PHP pages need heavy requests ont the database, sometimes to an external source, and MemCache allow to speed up all that by setting data in a cache in RAM, so very fast.

Theses data can be pages, pieces of pages, results of requests or distant sources. For example in the sidebar of a web site, the display of other linked articles can ask a complex SQL request. You can put in cache the direct result of the request (via a serialized table for example) or even the generated HTML. Instead of printing this part of page, you set it in the cache and get it again instantly.


To gain some time on already existing pages, we can use the PHP output buffering with ob_start() then catch and print the result with ob_get_flush(). There, we put it in the cache and the next calls to this page will only call the cache.


How to install MemCache

It requires to install both the server MemCached, a daemon to receive the data, and the PHP extension, the client which will read these data.

Depending on the Linux distribution of your server, you should type some command lines close to (example for CentOS):

yum install memcached
chkconfig memcached on
service memcached start

and for the PHP extension, it needs also Zlib because MemCache can compress the data:

yum install zlib-devel
pecl install memcache


How to use MemCache

You can read the PHP documentation, it's not very difficult. Some function set and get allow to set and get our data. :-) We only need to find a good identifier for each. That may be a MD5 key for a SQL request.

$memcache_obj = new Memcache;
$memcache_obj->connect ('localhost', 11211);
$memcache_obj->set('test', 'Hello world!);
echo $memcache_obj->get ('test');


Concrete example for complete pages

I recently created a comparator Amazon eBay for the movies site Kiao. For each category, search and product, the information comes form XML feed on Amazon, then from eBay for the price comparison and a last request on Yahoo to get more information. All these external requests being slower than a local query and moreover the number of requests per hour being limited, I have decided to cache all the pages.

At the beginning of each page, I test if it's in the cache with its identifier (let's say the product reference $ref):

$memcache_obj = new Memcache;
$memcache_obj->connect ('localhost', 11211);
if (($memcache_page = $memcache_obj->get($ref)) !== false)
echo $memcache_page;
/* Else we memorize the output with ob_start. */

At the end of the page, if it wasn't in the cache, I put it and display it with ob_get_flush():

$page = ob_get_flush(); /* Affiche et retourne le contenu de la page. */
$memcache_obj->set($ref, $page, MEMCACHE_COMPRESSED, 3600*24*12); // Duration in seconds, 12 days


I hope this article would incite you to try this cache tool, very light, to speed up your site. You should ask some questions in comments and don't forget to use the Kiao store for your cultural and multimedia shopping! ;-)

cafĂ© Did this article help you? 
Buy me a coffee!

Leave a comment (all comments are moderated, don't waste time with spam)

Azure Dev