This information enhances the documentation for the Drupal Memcache module. The Drupal configuration on this page is for Drupal 6, while the other information below is Drupal version agnostic. For Drupal 7 sites on Ubuntu 12.04 you may want to see this post.

Quick install of the Memcache daemon for the modern versions of some common Linux Distributions:

# Debian / Ubuntu:
sudo apt-get install memcached
# Fedora / CentOS / RHEL
sudo yum install memcached

If you have PEAR installed and up to date, you can install the PECL Memcache extension as follows:

# For the stable 2.2.x branch
sudo pecl install memcache
# For the beta, though functional, 3.0.x branch
sudo pecl install memcache-beta

PECL Memcache may also be installed with your distributions package manager, but it is usually out of date.

Memcache - Guidelines: see items 1) to 3)

1) A typical Drupal / Pressflow 6.2x use of memcache

The relevant parts of settings.php from a Drupal/Pressflow site utilizing the Memcache module.

/**
 * Memcache:
 */
$conf += array(
  'memcache_extension'           => 'memcache',
  'show_memcache_statistics'     => 0,
  'memcache_persistent'          => TRUE,
  'memcache_stampede_protection' => TRUE,
  'memcache_stampede_semaphore'  => 15,
  'memcache_stampede_wait_time'  => 5,
  'memcache_stampede_wait_limit' => 3,
  'memcache_key_prefix'          => basename(realpath(conf_path())),
);

// We don't use chained memcached caching for sites cron, php-cli and install!
if (isset($_SERVER['HTTP_USER_AGENT']) && !preg_match("/(?:cron\.php|install\.php)/", $_SERVER['REQUEST_URI'])) {
  if (isset($_SERVER['HTTP_HOST'])) {
    $conf += array(
      'cache_inc'        => './sites/all/modules/memcache/memcache.inc',
      'session_inc'      => './sites/all/modules/memcache/memcache-session.inc',
      'lock_inc'         => './sites/all/modules/memcache/memcache-lock.inc',
      'memcache_servers' => array(
         'unix:///tmp/memcached.socket0:0'  => 'default',
         'unix:///tmp/memcached.socket1:0'  => 'block',
         'unix:///tmp/memcached.socket2:0'  => 'content',
         'unix:///tmp/memcached.socket3:0'  => 'filter',
         'unix:///tmp/memcached.socket4:0'  => 'form',
         'unix:///tmp/memcached.socket5:0'  => 'menu',
         'unix:///tmp/memcached.socket6:0'  => 'page',
         'unix:///tmp/memcached.socket7:0'  => 'update',
         'unix:///tmp/memcached.socket8:0'  => 'views',
         'unix:///tmp/memcached.socket9:0'  => 'session',
         'unix:///tmp/memcached.socket10:0' => 'users'
      ),
      'memcache_bins'    => array(
         'cache'         => 'default',
         'cache_block'   => 'block',
         'cache_content' => 'content',
         'cache_filter'  => 'filter',
         'cache_form'    => 'form',
         'cache_menu'    => 'menu',
         'cache_page'    => 'page',
         'cache_update'  => 'update',
         'cache_views'   => 'views',
         'session'       => 'session',
         'users'         => 'users'
      ),
    );
  }
}

2) Sample memcache php.ini settings:

This can either be placed into the relevant php.ini file or in a file named memcache.ini in the relevant conf.d directory.

[memcache]
; Data will be transferred in chunks of this size
memcache.chunk_size = 32768
memcache.hash_strategy = consistent
memcache.default_port = 0
session.save_handler = memcache
session.save_path = "unix:///tmp/memcached.socket11:0?persistent=1&weight=1&timeout=1&retry_interval=15"

3) Sample Linux memcached daemon configuration

On some Linux distributions you can copy and rename /etc/memcache.conf to memcache_myserver.conf to create configurations for each Memcache instance which will be handled by the existing /etc/init.d/memcached script, further details on this are provided in the /etc/init.d/memcache script itself. Alternatively you can replace your /etc/init.d/memcached with the script below (Remember to backup your original init script first):

#! /bin/sh
#
# chkconfig: - 55 45
# description:  The memcached-multi daemon is a network memory cache service.
# processname: memcached-multi
# config: /etc/sysconfig/memcached
# pidfile: /var/run/memcached/memcached.*.pid


# Standard LSB functions
#. /lib/lsb/init-functions

# Source function library.
. /etc/init.d/functions

PORT=11211
UDP=0
SOCKET=/tmp/memcached.socket
VAR=0
USER=memcached
MAXCONN=300
CACHESIZE=64
OPTIONS=""

if [ -f /etc/sysconfig/memcached ];then
        . /etc/sysconfig/memcached
fi

# Check that networking is up.
. /etc/sysconfig/network

if [ "$NETWORKING" = "no" ]
then
        exit 0
fi

RETVAL=0
prog="memcached"

start_instance() {
        echo -n $"Starting $prog ($1): "
#       daemon --pidfile /var/run/memcached/memcached.$1.pid memcached -d -p $PORT           -u $USER -m $2 -c $MAXCONN -P /var/run/memcached/memcached.$1.pid $OPTIONS
        daemon --pidfile /var/run/memcached/memcached.$1.pid memcached -d -s $3 -a 766 -L -t 8 -u $USER -m $2 -c $MAXCONN -P /var/run/memcached/memcached.$1.pid $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/memcached.$1
}

stop_instance() {
        echo -n $"Stopping $prog ($1): "
        killproc -p /var/run/memcached/memcached.$1.pid /usr/bin/memcached
        RETVAL=$?
        echo
        if [ $RETVAL -eq 0 ] ; then
            rm -f /var/lock/subsys/memcached.$1
            rm -f /var/run/memcached.$1.pid
        fi
}


start() {
    # insure that /var/run/memcached has proper permissions
    if [ "`stat -c %U /var/run/memcached`" != "$USER" ]; then
        chown $USER /var/run/memcached
    fi
    # we start 12 socket streams for memcached
    start_instance default 64 /tmp/memcached.socket0;
    start_instance block 64 /tmp/memcached.socket1;
    start_instance content 64 /tmp/memcached.socket2;
    start_instance filter 64 /tmp/memcached.socket3;
    start_instance form 64 /tmp/memcached.socket4;
    start_instance menu 64 /tmp/memcached.socket5;
    start_instance page 64 /tmp/memcached.socket6;
    start_instance update 64 /tmp/memcached.socket7;
    start_instance views 64 /tmp/memcached.socket8;
    start_instance session 64 /tmp/memcached.socket9;
    start_instance users 64 /tmp/memcached.socket10;
    start_instance pbold 64 /tmp/memcached.socket11;
}

stop () {
    stop_instance default;
    stop_instance block;
    stop_instance content;
    stop_instance filter;
    stop_instance form;
    stop_instance menu;
    stop_instance page;
    stop_instance update;
    stop_instance views;
    stop_instance session;
    stop_instance users;
    stop_instance pbold;
}

restart () {
        stop
        start
}


# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        status memcached
        ;;
  restart|reload|force-reload)
        restart
        ;;
  *)
        echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"
        exit 1
esac

exit $?

Additional Notes:

The PHP Memcache PECL can also be compiled fully 'static' into the php-5.3.x binary-by moving the [memcache - PECL] source into the php /ext folder and rebuilding the PHP 'buildconf' - then compile PHP 5.3.x with --enable-memcache (it is *not* essential to use PECL if you are after the best speed - and understand *static* PHP compile builds).

PHP 5.3.x Static Compile guidelines:

In the PHP source root folder, issue the following (Linux);

rm configure
PHP_AUTOCONF=autoconf-2.13 PHP_AUTOHEADER=autoheader-2.13 ./buildconf --force

Then compile PHP manually (or use rpmbuild or similar). If you usually work directly with Fedora RPM sources you can build PHP with:

rpmbuild -bb php.spec >> php.checklist 2>&1

Comments

thedavidmeister’s picture

So, according to http://drupal.org/node/57150#comment-108379 it looks like setting the session.save_handler to anything other than "user" and session.save_path to '' is incorrect for Drupal.

When the save_handler is "user" ./includes/bootstrap.inc includes the memcache-session.inc file (if you've configured that part right) and that in turn handles saving Drupal sessions with memcache.

When I configured something like this I could see that there was data being written and read in both 11213 and 11214 using session.save_handler = 'user':

      'memcache_servers' => array(
         '127.0.0.1:11212'  => 'default',
         '127.0.0.1:11213'  => 'session',
         '127.0.0.1:11214'  => 'user',
      ),
      'memcache_bins'    => array(
         'cache'         => 'default',
         'session'       => 'session',
         'users'         => 'user'
      ),
ximo’s picture

As far as I can tell, it doesn't change session.save_handler anywhere in its code, and neither does the Memcache module.

Joakim Stai – Kollegorna

thedavidmeister’s picture

Session handling hasn't been ported to D7 completely yet according to the status of this issue http://drupal.org/node/656838

The instructions on this page, like step 2, and some of the comments in this thread say to change the session save handler to memcache. I'm saying maybe that's not a good idea because it bypasses the pluggable Drupal implementation of sessions.

Ken Hawkins’s picture

After editing the memcached config on Ubuntu 12.04, memcached refused to start, throwing the error:

Can't use string ("") as a subroutine ref while "strict refs" in use at /usr/share/memcached/scripts/start-memcached line 74, <$etchandle> line 121.

It seems that the config file doesn't agree with memcached amd64 1.4.13-0ubuntu2