Multiple web servers and memcache

Events happening in the community are now at Drupal community events on www.drupal.org.
rotis23's picture

Hi All,

Fairly new to drupal and its caches. Been hunting around for the answers to my questions but not found anything exact.

I wanted to ask what the accepted best practice is for configuring memcache (MC) across multiple web servers.

By default the Drupal caches are shared in a single database. MC seems to offer a number of options:

1 - A single remote MC instance that emulates the default database configuration (either with single or multi-bin config).

2 - Local single-bin MC instances per web server - presumably this will result in stale caches [for as long as MC ttl (or size limit)] - this may not be a problem if short term stale data is acceptable. Faster as no remote MC connection required?

3 - Multiple-bin MC instances spread across the web servers. Web server A MC has half the bins and web server B has the other half. No stale data but remote calls - presumably some caches are more active than others and one host will be at a disadvantage. What happens when you have n servers?

I just wondered what others have done. I'm leaning towards 2 with a 3-5 min TTL. However, I can't see us having more than 2 or 3 web servers so maybe the disadvatages of 3 are outweighed?

Cheers.

Comments

What we do

mikeytown2's picture

We run memcache on every web head. We haven't looked to see if this is optimal.

<?php
$conf
['cache_inc'] = './sites/all/modules/memcache/memcache.inc';
$conf['lock_inc'] = './sites/all/modules/memcache/memcache-lock.inc';
$conf['session_inc'] = './sites/all/modules/memcache/memcache-session.inc';

$memcache_servers = array(
 
'10.1.1.1:11211' => 'default',
 
'10.1.1.2:11211' => 'default',
 
'10.1.1.3:11211' => 'default',
 
'10.1.1.4:11211' => 'default',
 
'10.1.1.5:11211' => 'default',
 
'10.1.1.6:11211' => 'default',
 
'10.1.1.7:11211' => 'default',
 
'10.1.1.8:11211' => 'default',
 
'10.1.1.9:11211' => 'default',
);

$conf['memcache_servers'] = array();
// Connect to the local memcache server first.
$key = $_SERVER['SERVER_ADDR'] . ':11211';
if (isset(
$memcache_servers[$key])) {
 
$conf['memcache_servers'] += array(
   
$key => $memcache_servers[$key],
  );
}
// Add the rest of the servers into the mix.
$conf['memcache_servers'] += $memcache_servers;

$conf['memcache_bins'] = array(
 
'cache'  => 'default',
 
'cache_form' => 'database',
);
$conf['memcache_key_prefix'] = settings_get_pathname();
$conf['memcache_persistent'] = TRUE;

function
settings_get_pathname() {
 
// Get path name
 
$path = conf_path();
  if (
is_link($path)) {
   
$path = readlink($path);
  }
 
$path = str_replace("\\", '/', $path);
 
$path = explode('/', $path);
 
$path = array_pop($path);
  return
$path;
}
?>

You only need to specify the bins that are not default, see dmemcache_object().

    // If there is no cluster for this bin in $memcache_bins, cluster is 'default'.
    $cluster = empty($memcache_bins[$bin]) ? 'default' : $memcache_bins[$bin];

@mikeytown2 this looks really

dalin's picture

@mikeytown2 this looks really great. What are you trying to work around with settings_get_pathname() ?

--


Dave Hansen-Lange
Director of Technical Strategy, Advomatic.com
Pronouns: he/him/his

Management of settings.php

mikeytown2's picture

We effectively have one settings.php file & we use that function to select the database to connect to as well as prefix memcache bins. One less thing to worry about when you have 80 different multi-sites.

Our Configuration

vaibhavjain's picture

We have 4 servers and a Load balancer sits over it.
Every server runs it own memcache.
In every settings.php, define memcache for its own memcache and to make sure all the 4 servers memcache are in sync, use memcache hash strategy - http://www.php.net/manual/en/memcache.ini.php#ini.memcache.hash-strategy

This, till now, works all good for us.

Vaibhav Jain

My typical approach is to run

craigmc's picture

My typical approach is to run memcache on the DB server. That way you're sharing the cache contents across multiple web-heads. Since it's basically an either/or hit to memcache or your DB, it makes sense that way too.

Also wondering why you're not using memcache for session caching. Totally helps performance. Although for that, you'd definitely want to use a central location for memcache.

Los Angeles, CA

Saving sessions to memcache

exlin's picture

Saving sessions to memcache helps in performance, sure.

Issue is that memcache isn't persistent so after memcache/server restart sessions are gone. That might not be wanted in all sites...

Sessions wouldn't be

craigmc's picture

Sessions wouldn't be persistent if the Apache Server was restarted either, so I don't think you're really losing anything. and the side-benefit of using memcache-session in Drupal 6 (soon to be 7 as well) is that it has a look-aside table for cached $user objects, which saves on the heavy user_load when a user logs in as well.

Los Angeles, CA

Last time i checked, default

exlin's picture

Last time i checked, default behavior is to save sessions into db.

You're right, exlin.

craigmc's picture

You're right, exlin. Momentary mind-fog on that one.

Yes, if you want persistent sessions after your memcache server goes down you'd want to either bypass using memcache-session, or modify memcache-session to add an extra layer of logic to lazy-write sessions to the DB when created, and to check against the DB if the session was not found in memory. This would be pretty easy to implement and would address this issue while still giving people the ability to get the speed bump from using memcache for sessions.

Los Angeles, CA