Using PECL/Memcached to store sessions

This post is the second part of my earlier article about installing and setting up the Memcached server and PECL/Memcached PHP client on CentOS 5.5.

Let’s assume you have PECL/Memcached up and running and want to use it as a session handler. I’ll talk below about why you’d want to do this (and why not) and how to get there.

Is storing sessions with Memcached a good idea?

As usual: it depends.
Regular file-based session storage is reliable and reasonably fast. It has its drawbacks though, especially when you want to scale: First of all, if you have several servers behind a load balancer, you need to make sure that a visitor always gets the same session if he is assigned to another server in-between. This is difficult if sessions are stored locally on each server. Also, a LOT of these tiny session files can pile up fast on your server, which makes server backups more difficult. Also, when you’re on a cheap cloud server, file I/O speed might not be optimal. So you start thinking about a RAM-based solution. One way to do this would be a tmpfs partition to store session files in memory. But remember, you still need a central place to store sessions. In comes Memcached.
Memcached operates in-memory only, and can be run on one or more central servers. Great, right? Yes and no. Memcached is not a database, but an LRU (“least-recently-used”) cache with a fixed size. If there is not enough room, the oldest items will be removed. If we use it for session storage, some people might be logged out randomly. Duh. So, if you want to use Memcached, you have to weigh its advantages and drawbacks. It’s certainly not a good option if you have important sessions (like shopping carts) that you cannot afford to lose. On the other hand, if it’s OK to lose a session once in a while, Memcached might be a good solution for you. It’s very fast and easy to set up, and it is supported as a session handler by PHP out of the box. You can mitigate the risk by assigning enough RAM, and by adding a “remember me” feature (if it’s not a security concern, depending on the type of your site). If you use a custom session handler, you can even use Memcached purely as a caching front-end for a database session store and get the best of both worlds.

How to set up Memcached as PHP session handler

There are two ways to use Memcached as your session handler: if you have no special needs, you can simply set some PHP ini options and you’re done. This was good enough in my situation and I’ll describe this solution here. If you want to use advanced options, like using persistent connections or using a combined Memcached/MySQL solution, you will need to use a custom session handler (not described here).

The easy way: set PHP ini options

As PHP comes with support for Memcached as session storage baked in, you only need to set two options and you’re good to go. You can either set these in your php.ini file, or at run-time in your application.
; either put this in php.ini
; replace or comment out the existing two options
session.save_handler = memcached
; change server:port to fit your needs
session.save_path="127.0.0.1:11211"

# or, include this in your application startup code
ini_set('session.save_handler', 'memcached');
ini_set('session.save_path', '127.0.0.1:11211');

Note: There are a few gotchas here, and this is actually what made me write this post. Most other blog posts about this topic use PECL/Memcache, not PECL/Memcached. Both have a different API and different options. If you’re using PECL/Memcached (like me), make sure to include the “d” in the handler name (“memcached”). Also, the save path must NOT include the protocol (just server IP and port). You CAN specify a comma-separated list of servers, but you CANNOT specify options here, like you can with PECL/Memcache. If you need special options, you must use a custom session handler, as mentioned above.

That’s it, we’re done! Now go ahead, restart Apache, and test your shiny new Memcached sessions.

3 thoughts on “Using PECL/Memcached to store sessions

  1. Danish Javed

    Nice tutorial,

    I have a similar setup with two servers, both replicating to each other. Works fine when using telnet, but having a problem when using php which is that when i kill the server i am on (127.0.0.1), i expect php to not care about the memcached instance (127.0.0.1:11211) and allow the failover to the other server (192.168.100.1:11211)

    At this point i get an error

    PHP Warning: Unknown: Failed to write session data (memcached). Please verify that the current setting of session.save_path is correct (127.0.0.1:11211,191.168.100.1:11211) in Unknown on line 0,

    Did you ever get this issue?

  2. Benny

    If you want to share sessions and have transparent failover support at the same time, try
    memcache.session_redundancy=2

    nice tut, gj!

Comments are closed.