Improved cache and sessions storage with CakePHP and Redis

CakePHP 2.3 + Redis 2.6.7

For the vast majority of applications out there the issue of cache and session store doesn’t really come into play until the application is large enough to where it needs to be scaled to multiple web servers.
At that point filesystem (default cache and session store) becomes inadequate for a couple of reasons:

  1. You need a central location for sessions because maintaining user sessions on individual servers will be extremely painful. You’d have to persist the user to the same web node.
  2. If you clear/invalidate the cache, it has to be done on all servers consistently or your application will be in a very unpredictable state.
  3. Writing to filesystem is relatively slow.

Often a simple enough solution is to use the database to keep track of sessions across all web servers. This option is nicely integrated into cake, and doesn’t require much in terms of configuration (other than changing the default value from “php” to “database” in core.php).

Today we’ll look at setting up Redis to be used as a cache and sessions storage. Although we are not going leverage some of the advanced features, the benefits of having a very fast, memory-based store with out-of-the-box persistence are great enough for any application, whether you run off of one server or twenty five.

Now that we know “why”… let’s see “how”…

First, we are going to install Redis server. For those on Ubuntu the installation process is honestly a little too easy:

apt-get install redis-server

Done.

Working with default config settings is recommended for a basic installation. (Cake will actually expect certain Redis defaults).

Now that we have our server installed and running, we need to tie PHP and Redis by using any of the available libraries.
The one I like is:
https://github.com/nicolasff/phpredis

The installation is rather simple also.
Clone the repository and run the three commands provided at the link above.

Finally, let’s configure our application to use Redis. All we have to do is modify core.php

First, change the value of $engine to Redis

$engine = 'Redis';

Next, let’s create a separate cache config for our sessions.

Cache::config('session', array(
    'engine' => $engine,
    'prefix' => $prefix . 'cake_session_',
    'duration' => $duration
));

Now we’ll tell cake to use the cache store for sessions as well. The “handler” key ties everything together.
(Ability to use cache store for sessions is an awesome addition to CakePHP and just as well you could use APC, memcached, or some other solution).

Configure::write('Session', array(
        'defaults' => 'cache',
        'timeout' => 100,
        'start' => true,
        'checkAgent' => false,
        'handler' => array(
            'config' => 'session'
        )
    ));

With all of this in place, we can now test our application to make sure everything is working as expected:

  1. CakePHP core Redis Engine tests should be passing
  2. No cache or sessions files are written to local file system
  3. We can run redis-cli and then “KEYS cake*” to see all cake-related keys in the data store. There should be cake_session_*, cake_model_*, cake_core_* keys listed. (This presumes you’ve tried to use the app by clicking around and possibly logging-in)
%d bloggers like this: