Getting the most performance out of PHP Shindig

If your using or planning to use php-shindig in production, your probably wondering what knobs can be twiddled to get the highest possible performance out of it; So here’s some tips on how to make it go just that bit faster.

The first thing to look at is the general PHP performance on your server. Out of the box PHP is very poorly equipped for high traffic websites, and chances are you already have a few of these optimizations in place, combined these tricks will more then double the performance of your shindig deployment.

To be able to give some semi-meaningful measurements I’ll be using the QPS (queries per second) of how fast php-shindig can render the OpenSocial Dev App (OSDA) on my workstation, which has a single Quad Core 2 Duo @ 3Ghz and a single SATA II disk, so a standard of the rack server should be able to do a bit better then the results I’m getting here. The base line of a plain outo-of-the-box php and shindig configuration is ~ 210 QPS.

Opcode Cache

Perhaps the most important tip for php performance is to install an opcode cache.. PHP is still an interpreted language, and that means that in it’s default configuration, on every page hit, it will read your PHP code and interpret it into opcodes. An op(eration)code is the instruction that the Zend engine actually performs, and this constantly interpreting will take most of your server’s resources! The solution is to install an opcode cache that caches these compiled instructions in memory, so that your webserver can focus on actually executing the code. My personal favorite is the Alternative PHP Cache (APC)

Using APC the QPS on my workstation goes from 210 to 385, a pretty impressive performance increase!

PHP FatMM

The next tip is to use the php-fatmm patch, the fat memory manager patch changes the way that the PHP engine allocates memory, instead of (de/)allocating memory on the fly it will pre-allocate a configured amount of memory, and only if that runs out will it allocate more; The end result is that it can save PHP having to do thousands of alloc()’s, which means it can spend more time doing useful stuff :) This does mean your server process will use more memory, and I wouldn’t advice to use this on a server that also serves static content or very simple php scripts, but for a server that is dedicated to php-shindig, this is just what the doctor ordered.

Re-benchmarking our OSDA rendering using both APC and php-fatmm brings us to 410 QPS, while not as earth-shattering as APC, still a very nice improvement!

Disk IO – Caching back-ends to use

Now with the basic PHP bottle-necks out of the way, lets focus on the other thing that will bring a server to it’s knees: Disk IO. Harddisks are the slowest component in your server and having a lot of reads and writes happening will cause your CPU’s just just spin idly in their sockets waiting for data to appear.

The highest impact change here is to go from a disk based cache in php-shindig (the CacheFile class which is the default configured cache back-end since it works on every platform/configuration) to a memory based caching class. Now there’s two distinct types of cached information in php-shindig, the one is the ‘feature_cache’, where it stores the processed (and if configured, minimized) feature information.. parsing hundreds of little xml and javascript files is a very expensive operation so caching this adds a lot to the efficiency of php-shindig. The other cache type is the general ‘data_cache’, which is used to cache all remote resources such as the gadget xml files, message bundles, all proxied files, etc.

The features information doesn’t take so much space to store, and as such using a close-to-home cache for the feature_cache like the CacheApc class is the best solution, The data cache on the other hand will hold  many thousands of files, so will be considerably larger to store.. as such using a shared cache between your shindig servers is much more efficient, so using CacheMemcache is the optimum solutions there. So by changing the following bits:

'data_cache' => 'CacheMemcache',
'feature_cache' => 'CacheApc',

and rerunning the benchmark brings the total QPS to 435.

Disk IO – PHP Shindig configuration

The last bit of tweaking we can do is to disable the file checking, php-shindig has been coded to fail gracefully and check everything rigorously however that does cause some extra disk IO, however as long you feel certain you won’t go and delete files from your production systems, it’s pretty safe to turn this off, this is done by setting ‘check_file_exists’ to false in the configuration. We can also save some disk IO by changing the relative-path-resolution in the configuration to absolute paths, so change any paths like “realpath(dirname(__FILE__) . ‘/..’) . ‘/’” to their actual locations (like “/var/www/html/shindig/”). And setting ‘debug’ to false removes the last few of these checks. So in the configuration we set:

'debug' => false,
'check_file_exists' => false,
'base_path' => '/var/www/html/shindig/',
'features_path' => '/var/www/html/shindig/features',
'container_path' => '/var/www/html/shindig/config',
'javascript_path' => '/var/www/html/shindig/javascript',
'private_key_file' => '/var/www/html/shindig/php/certs/private.key',
'public_key_file' => '/var/www/html/shindig/certs/public.crt',

Conclusion

With all these measures in place, the benchmark now shows us doing some 450 QPS, more then doubling the 210 QPS we started out with, quite a satisfying result if you consider this means we end up transferring more then 45 megabyte/sec over the network at that point.

Now for the real speed freaks, all these results are based on the 1.0.x release tree from the svn repo, which is what you should be using since the trunk is seeing heavy development for the upcoming 0.9 changes, however the trunk has a re-factored gadget renderer that is a ~ 20-30% faster then the current release, so more performance goodness will be coming your way once the trunk stabilizes and becomes release ready.

FriendConnect, Linux, OpenSocial, shindig 0 comments,

Leave a Reply