Skip to main content

Cache

Jadu caches the results of many database queries to improve performance. By default, cache files are stored on the server file system.

When deploying a site over multiple servers it is desirable to synchronise the deleting of particular parts of the cache. For example, if a Jadu Central user updates a piece of content then the cache should be cleared on all servers so that users of the web site all see the new content.

Types of cache

As well as the data cache used for storing the result of database queries, a number of other caches are used.

Application cache

Jadu Central uses Symfony, and after applying an update or changing template files or service definitons, the Symfony cache will require clearing and warming.

When deploying a package, this is handled automatically by the meteor patching tool, however this can also be carried out manually using cli.php:

php cli.php cms:clear-cache
php -d memory_limit=500M cli.php cache:warmup --kernel=frontend
php -d memory_limit=500M cli.php cache:warmup --kernel=cc

There are distinct caches for the frontend website and Control Center application, so these both need to be warmed separately.

Config cache

Although the general application cache may be stored in Redis or memcached, the config cache is always stored on the filesystem. After any change to application configuration you will therefore need to remove these cache files for the changes to take effect. This can be done from the cacheBash.php page.

Cache configuration

There are 3 supported locations for cache storage:

  • filesystem
  • memcached
  • Redis

Filesystem

Filesystem is the default storage location of the cache. Jadu can be configured to use the filesystem by editing <install_path>/config/system.xml and changing the value of CACHE_DATA_STORE to file.

<cache_data_store>file</cache_data_store> 

Redis

Redis is an in-memory data structure store that can be used as a cache. It is necessary for the redis PHP extension to be installed to take advantage of this functionality.

Redis is our recommended cache solution for clustered Windows systems.

Jadu can be configured to use memcached by editing <install_path>/config/datastore.xml.

First add details of the memcached servers as follows.

<?xml version="1.0" encoding="utf-8" ?>
<datastore xmlns:config="http://www.jadu.co.uk/schema/config">
<redis>
<servers>
<server host="localhost" port="6379"/>
</servers>
</redis>
</datastore>

It is also necessary to change the value of the CACHE_DATA_STORE (within the system.xml config) constant to redis, rather than file.

<cache_data_store>redis</cache_data_store> 

Memcached

Memcached is a distributed object caching system. It can be used to store a single copy of the Jadu cache over multiple servers rather than on each individual file system. It is necessary for the memcached PHP extension to be installed to take advantage of this functionality.

Jadu can be configured to use memcached by editing <install_path>/config/datastore.xml.

First add details of the memcached servers as follows.

<?xml version="1.0" encoding="utf-8" ?>
<datastore xmlns:config="http://www.jadu.co.uk/schema/config">
<memcached>
<servers>
<server host="memcached-1" port="11211"/>
</servers>
</memcached>
</datastore>

It is also necessary to change the value of the CACHE_DATA_STORE constant to memcached, rather than file.

<cache_data_store>memcached</cache_data_store>

Use of caching in the application

Caching is handled by the Cache class, which is located in <install_path>/jadu/JaduCache.php. The following code demonstrates how to create an instance of the Cache class and store the results of a database query in the cache.

require_once('JaduCache.php');

$params = [
'select' => ['name', 'value'],
'table' => 'my_table',
'where' => [
'id' => 1234
],
'orderBy' => [
['value', 'ASC']
]
];

$cache = new Cache('my_table', json_encode($params));
$result = null;

if ($cache->isEmpty()) {
// run the query against the database and store the data in $result
$cache->setData($result);
} else {
$result = $cache->data;
}

The following extracts from the code above demonstrates a number of features of the Cache class.

$cache = new Cache('my_table', json_encode($params));

This creates a cache object for the my_table namespace with the key of the data passed in as the second parameter. The namespace is used to group together cache items so that they can be deleted when data under the namespace is updated. The most common analogy of a namespace is the name of the database table that a query relates to.

If the database table name is used as the namespace, when a record in the table is added, updated or deleted, the items cached under the namespace are deleted so that future queries are based on the latest data.

The second parameter, the key of the data, is used to identify a particular piece of data under a namespace, such as a database query. This allows a specific piece of data to be identified as being in the cache and fetched if necessary.

if ($cache->isEmpty()) {

The isEmpty function for a Cache object returns true or false, depending on if the data for the requested key and namespace is available in the cache. This can then be used to determine whether to generate the data afresh or return the data from the cache.

$cache->setData($result);

The setData function adds data to the cache under the namespace and key set in the constructor when instantiating the Cache object. The data will remain in the cache until a request is made to delete the namespace under which the data is stored. Any serializable data type can be stored in the cache. The data need not be serialized before it is passed to the setData method; serialization is handled by the Cache class.

$result = $cache->data;

When instantiating a cache object, if data is available for the namespace and key provided in the constructor then it is retrieved and stored in the $data variable in the Cache class.

Deleting a Cache Namespace

To delete a cache namespace call the deleteTableCache function. This function resides in <install_path>/JaduCache.php, however it is not part of the Cache class. To delete all data in the cache within the “users” namespace, call the function as follows:

require_once('JaduCache.php');
deleteTableCache('my_table');

Timed Based Caching

As an alternative to caching data indefinitely (until it is deleted) it is also possible to cache data for a specific period of time. This can be achieved using the TimedCache class.

The main difference between the interface of the standard Cache class and the TimedCache class is when using the setData function. After a TimedCache instance has been created, a time (in the form of a unix timestamp) can be provided to the setData function to determine when the cache will expire, for example:

require_once('JaduCache.php');
$timedCache = new TimedCache('namespace', 'timer');
$timedCache->setData('fred', time() + 120);

The preceding code would cache the value ”fred” under the “namespace” namespace for the key “timer” for 120 seconds. If the same cache object is created after 120 seconds the cache would be classed as empty, i.e. calls to the isEmpty function would return false.

Clearing the Cache

Any Jadu files that update database table records should clear the caches of any tables that are updated. In this way the Jadu Central cache becomes self-regulating. Should a file or database table be updated manually, i.e. not through using a Jadu Central user interface, then it will be necessary to clear the cache of the respective table. This can be done by manually deleting the directory with the name associated with the database table from the file system. Jadu also provide a user interface for clearing table caches.