PHP Opcode Caches, switching between

Opcode Cache

A PHP accelerator is an extension designed to boost the performance of software applications written using the PHP programming language. Most PHP accelerators work by caching the compiled bytecode of PHP scripts to avoid the overhead of parsing and compiling source code on each request (some or all of which may never even be executed). For best performance, caching is to shared memory with direct execution from the shared memory and the minimum of memory copying at runtime. A PHP accelerator typically reduces server load and increases the speed of PHP code anywhere from 2-10 times, depending on factors such as the inherent execution time of the PHP application and the percentage of source code actually executed on a given request. While a code optimizer may even slow down overall performance when used in isolation, it can provide an additional performance boost when coupled with a code cache as the optimization effort is performed just once.

Code Cache is just an extension of the basic accelerator engine, where the compiled code is cached and the updates are transparent. Most if not all, accelerators available do offer one or other way to utilize in memory cache for user defined variables, to reduce costly repetitive database calls or file system IO. More to read at wikipedia.

We at Saturn were using APC for a long time, though only on our colocated servers, not in the test server located in our lab. Then came kerala online which we built around wordpress, and was best with eaccelerator (as some one suggested). This was a turn. We had to utilize the benefits of user space caching across the three servers, without breaking the morale of our developers. End result is an opcode class which had the same methods, but different underlying engine or method. Effectively an abstraction of APC methods, Eaccelerator methods or raw ramdisk methods.

With APC

<?php
class opcache {
        function 
fetch($key) {
            return 
apc_fetch($key);
        }
        function 
store($key,$data,$ttl) {
            return 
apc_store($key,$data,$ttl);
        }
        function 
delete($key) {
            return 
apc_delete($key);
        }

With Eaccelerator

<?php
class opcache {
        function 
fetch($key) {
        
$tmp eaccelerator_get($key);
        if(!
is_null($tmp))
            return 
$tmp;
        else return 
false;
        }
        function 
store($key,$data,$ttl) {
        return 
eaccelerator_put($key$data$ttl);
        }
        function 
delete($key) {
        return 
eaccelerator_rm($key);
        }

No Cache (only on Linux)

<?php
class opcache {
    function 
fetch($key) {
    
$ksFile $this->getkeystore($key);
    
clearstatcache();
    if(!
file_exists($ksFile)) return false;
    
$store unserialize(file_get_contents($ksFile));
    if(
$store['ttl'] == 0)
        return 
$store['data'];
    
$mtime filemtime($ksFile);
    if((
$mtime $store['ttl']) > time())
       return 
$store['data'];
    else
       return 
false;
    }
    function 
store($key,$data,$ttl) {
    
$store = array('ttl' => $ttl'data' => $data);
    
file_put_contents($this->getkeystore($key), serialize($store));
    }
    function 
delete($key) {
    
unlink($this->getkeystore($key));
    }
    function 
getkeystore($key){
        return 
'/dev/shm/apcStore_' md5($key);
    }

In the last case, since the activity is on shm, which is a ram disk and more or less half the full system memory. So a disk pruning system with the help of find as below in the system cron, would be best to maintain the balance, unless the system is restarted frequently (in case of a web server or test server). This would delete any file, which was created 6 hours or more ago.

find /dev/shm -type f -cmin +360 -delete

The last piece can be used by those who do not have any kind of opcode cache. Though there seems to be a small over head with the cache ttl checks, we could ignore that when we think of the advantages of utilizing this.