diff --git a/README.txt b/README.txt
index d6b2f4b..8df993c 100644
--- a/README.txt
+++ b/README.txt
@@ -102,6 +102,15 @@ to $conf; memcache_servers and memcache_bins. The arrays follow this pattern:
    binS => clusterS
 )
 
+You can optionally assign a weight to each server, favoring one server more than
+another. For example, to make it 10 times more likely to store an item on
+server1 versus server2:
+
+'memcache_servers' => array(
+  server1:port => array('cluster' => cluster1, 'weight' => 10),
+  server2:port => array('cluster' => cluster2, 'weight' => 1'),
+)
+
 The bin/cluster/server model can be described as follows:
 
 - Servers are memcached instances identified by host:port.
diff --git a/dmemcache.inc b/dmemcache.inc
index d55cb6f..f42fa8a 100644
--- a/dmemcache.inc
+++ b/dmemcache.inc
@@ -576,7 +576,17 @@ function dmemcache_stats($stats_bin = 'cache', $stats_type = 'default', $aggrega
         // passed to the Memcache memcache_get_extended_stats() function.
         elseif ($mc instanceof Memcache) {
           if ($stats_type == 'default' || $stats_type == '') {
-            $stats[$bin] = $mc->getExtendedStats();
+            $rc = $mc->getExtendedStats();
+            if (is_array($rc)) {
+              foreach ($rc as $server => $data) {
+                if (empty($data)) {
+                  unset($rc[$server]);
+                }
+              }
+              if (!empty($rc)) {
+                $stats[$bin] = $rc;
+              }
+            }
           }
           // If $slab isn't zero, then we are dumping the contents of a
           // specific cache slab.
@@ -774,14 +784,13 @@ function dmemcache_instance($bin = 'cache') {
  * @param string $server
  *   A server string of the format "localhost:11211" or
  *   "unix:///path/to/socket".
- * @param bool $connection
- *   TRUE or FALSE, whether the $memcache instance already has at least one
- *   open connection.
+ * @param integer $weight
+ *   Weighted probability of talking to this server.
  *
  * @return bool
  *   TRUE or FALSE if connection was successful.
  */
-function dmemcache_connect($memcache, $server, $connection) {
+function dmemcache_connect($memcache, $server, $weight) {
   static $memcache_persistent = NULL;
 
   $extension = dmemcache_extension();
@@ -795,8 +804,8 @@ function dmemcache_connect($memcache, $server, $connection) {
     $memcache_persistent = variable_get('memcache_persistent', TRUE);
   }
 
+  $port_error = FALSE;
   if ($extension == 'Memcache') {
-
     // Support unix sockets of the format 'unix:///path/to/socket'.
     if ($host == 'unix') {
       // Use full protocol and path as expected by Memcache extension.
@@ -804,31 +813,7 @@ function dmemcache_connect($memcache, $server, $connection) {
       $port = 0;
     }
     else if (!isset($port)) {
-      register_shutdown_function('watchdog', 'memcache', 'You have specified an invalid address of "!server" in settings.php which does not include a port. Please review README.txt for proper configuration. You must specify both a server address and port such as "!ip" or "!host", or a unix socket such as "!socket".', array('!server' => $server, '!ip' => t('127.0.0.1:11211'), '!host' => t('localhost:11211'), '!socket' => t('unix:///path/to/socket')), WATCHDOG_WARNING);
-    }
-
-    // When using the PECL memcache extension, we must use ->(p)connect
-    // for the first connection.
-    if (!$connection) {
-      $track_errors = ini_set('track_errors', '1');
-      $php_errormsg = '';
-
-      // The Memcache extension requires us to use (p)connect for the first
-      // server we connect to.
-      if ($memcache_persistent) {
-        $rc = @$memcache->pconnect($host, $port);
-      }
-      else {
-        $rc = @$memcache->connect($host, $port);
-      }
-      if (!empty($php_errormsg)) {
-        register_shutdown_function('watchdog', 'memcache', 'Exception caught in dmemcache_connect while connecting to !host:!port: !msg', array('!host' => $host, '!port' => $port, '!msg' => $php_errormsg), WATCHDOG_WARNING);
-        $php_errormsg = '';
-      }
-      ini_set('track_errors', $track_errors);
-    }
-    else {
-      $rc = $memcache->addServer($host, $port, $memcache_persistent);
+      $port_error = TRUE;
     }
   }
   elseif ($extension == 'Memcached') {
@@ -839,8 +824,18 @@ function dmemcache_connect($memcache, $server, $connection) {
       $port = 0;
     }
     else if (!isset($port)) {
-      register_shutdown_function('watchdog', 'memcache', 'You have specified an invalid address of "!server" in settings.php which does not include a port. Please review README.txt for proper configuration. You must specify both a server address and port such as "!ip" or "!host", or a unix socket such as "!socket".', array('!server' => $server, '!ip' => t('127.0.0.1:11211'), '!host' => t('localhost:11211'), '!socket' => t('unix:///path/to/socket')), WATCHDOG_WARNING);
+      $port_error = TRUE;
     }
+  }
+
+  if ($port_error) {
+    register_shutdown_function('watchdog', 'memcache', 'You have specified an invalid address of "!server" in settings.php which does not include a port. Please review README.txt for proper configuration. You must specify both a server address and port such as "!ip" or "!host", or a unix socket such as "!socket".', array('!server' => $server, '!ip' => t('127.0.0.1:11211'), '!host' => t('localhost:11211'), '!socket' => t('unix:///path/to/socket')), WATCHDOG_WARNING);
+  }
+
+  if ($extension == 'Memcache') {
+    $rc = $memcache->addServer($host, $port, $memcache_persistent, $weight);
+  }
+  elseif ($extension == 'Memcached') {
     if ($memcache_persistent) {
       $servers = $memcache->getServerList();
       $match = FALSE;
@@ -943,22 +938,23 @@ function dmemcache_object($bin = NULL, $flush = FALSE) {
 
       // Track whether or not we've opened any memcache connections.
       $connection = FALSE;
-
       // Link all the servers to this cluster.
-      foreach ($memcache_servers as $server => $c) {
-        if ($c == $cluster && !isset($failed_connections[$server])) {
-          $rc = dmemcache_connect($memcache, $server, $connection);
-          if ($rc !== FALSE) {
-            // We've made at least one successful connection.
-            $connection = TRUE;
-          }
-          else {
-            // Memcache connection failure. We can't log to watchdog directly
-            // because we're in an early Drupal bootstrap phase where watchdog
-            // is non-functional. Instead, register a shutdown handler so it
-            // gets recorded at the end of the page load.
-            register_shutdown_function('watchdog', 'memcache', 'Failed to connect to memcache server: !server', array('!server' => $server), WATCHDOG_ERROR);
-            $failed_connections[$server] = FALSE;
+      foreach ($memcache_servers as $server => $b) {
+        if ($c = dmemcache_object_cluster($b)) {
+          if ($c['cluster'] == $cluster && !isset($failed_connections[$server])) {
+            $rc = dmemcache_connect($memcache, $server, $c['weight'], $connection);
+            if ($rc) {
+              // We've made at least one connection.
+              $connection = TRUE;
+            }
+            else {
+              // Memcache connection failure. We can't log to watchdog directly
+              // because we're in an early Drupal bootstrap phase where watchdog
+              // is non-functional. Instead, register a shutdown handler so it
+              // gets recorded at the end of the page load.
+              register_shutdown_function('watchdog', 'memcache', 'Failed to connect to memcache server: !server', array('!server' => $server), WATCHDOG_ERROR);
+              $failed_connections[$server] = FALSE;
+            }
           }
         }
       }
@@ -982,6 +978,29 @@ function dmemcache_object($bin = NULL, $flush = FALSE) {
 }
 
 /**
+ * Ensure that we're working with a proper cluster array.
+ */
+function dmemcache_object_cluster($cluster) {
+  if (!is_array($cluster)) {
+    // Set defaults.
+    $cluster = array(
+      'cluster' => $cluster,
+      'weight' => 1,
+    );
+  }
+  if (!isset($cluster['cluster']) || !is_string($cluster['cluster'])) {
+    // Cluster is required, complain if it's missing or invalid.
+    register_shutdown_function('watchdog', 'memcache', 'Ignoring invalid or missing cluster definition, review your memcache_servers configuration.', array(), WATCHDOG_ERROR);
+    return FALSE;
+  }
+  if (!isset($cluster['weight']) || !is_int($cluster['weight']) || $cluster['weight'] < 1) {
+    // Weight is optional.
+    $cluster['weight'] = 1;
+  }
+  return $cluster;
+}
+
+/**
  * Prefixes a key and ensures it is url safe.
  *
  * @param string $key
diff --git a/memcache-lock-code.inc b/memcache-lock-code.inc
index 5ebdb27..165e506 100644
--- a/memcache-lock-code.inc
+++ b/memcache-lock-code.inc
@@ -32,6 +32,17 @@ function lock_initialize() {
 function lock_acquire($name, $timeout = 30) {
   global $locks;
 
+  // Special case variable_init, as on memcache errors we can get stuck in an
+  // infinite loop.
+  static $variable_init = 0;
+  if ($name == 'variable_init') {
+    if ($variable_init > 25) {
+      register_shutdown_function('watchdog', 'memcache', 'Broke out of loop trying to grab lock for variable_init.');
+      return TRUE;
+    }
+    $variable_init++;
+  }
+
   // Ensure that the timeout is at least 1 sec. This is a limitation
   // imposed by memcached.
   $timeout = (int) max($timeout, 1);
diff --git a/memcache-lock.inc b/memcache-lock.inc
index ef176df..7e3b3b6 100644
--- a/memcache-lock.inc
+++ b/memcache-lock.inc
@@ -12,7 +12,11 @@ require_once dirname(__FILE__) . '/dmemcache.inc';
 // @todo get rid of this conditional include as soon as this is done:
 // http://drupal.org/node/1225404
 $lock_file = dirname(__FILE__) . '/memcache-lock-code.inc';
-if (!dmemcache_object('semaphore')) {
+$mc = dmemcache_object('semaphore');
+// dmemcache_object always returns TRUE, we don't need these stats but it forces
+// us to try and connect to memcache. If this fails, we can't store locks in
+// memcache.
+if (!$mc->getStats()) {
   $lock_file = DRUPAL_ROOT . '/includes/lock.inc';
 }
 require_once $lock_file;
diff --git a/memcache.install b/memcache.install
index 91b7a68..aee97dc 100644
--- a/memcache.install
+++ b/memcache.install
@@ -31,13 +31,15 @@ function memcache_enable() {
     // Make a test connection to all configured memcache servers.
     $memcache_servers = variable_get('memcache_servers', array('127.0.0.1:11211' => 'default'));
     foreach ($memcache_servers as $server => $bin) {
-      $memcache = dmemcache_instance($bin);
-      if (dmemcache_connect($memcache, $server, FALSE) === FALSE) {
-        $error = TRUE;
-      }
-      else {
-        if (!variable_get('memcache_persistent', TRUE)) {
-          dmemcache_close($memcache);
+      if ($cluster = dmemcache_object_cluster($bin)) {
+        $memcache = dmemcache_instance($cluster['cluster']);
+        if (dmemcache_connect($memcache, $server, $cluster['weight']) === FALSE) {
+          $error = TRUE;
+        }
+        else {
+          if (!variable_get('memcache_persistent', TRUE)) {
+            dmemcache_close($memcache);
+          }
         }
       }
     }
@@ -114,13 +116,15 @@ function memcache_requirements($phase) {
       // Make a test connection to all configured memcache servers.
       $memcache_servers = variable_get('memcache_servers', array('127.0.0.1:11211' => 'default'));
       foreach ($memcache_servers as $server => $bin) {
-        $memcache = dmemcache_instance($bin);
-        if (dmemcache_connect($memcache, $server, FALSE) === FALSE) {
-          $errors[] = $t('Failed to connect to memcached server instance at %server.', array('%server' => $server));
-        }
-        else {
-          if (!variable_get('memcache_persistent', TRUE)) {
-            dmemcache_close($memcache);
+        if ($cluster = dmemcache_object_cluster($bin)) {
+          $memcache = dmemcache_instance($cluster['cluster']);
+          if (dmemcache_connect($memcache, $server, $cluster['weight']) === FALSE) {
+            $errors[] = $t('Failed to connect to memcached server instance at %server.', array('%server' => $server));
+          }
+          else {
+            if (!variable_get('memcache_persistent', TRUE)) {
+              dmemcache_close($memcache);
+            }
           }
         }
       }
diff --git a/memcache_admin/memcache_admin.module b/memcache_admin/memcache_admin.module
index 5ac5bc8..b4c12ac 100644
--- a/memcache_admin/memcache_admin.module
+++ b/memcache_admin/memcache_admin.module
@@ -59,9 +59,11 @@ function memcache_admin_menu() {
   );
   $memcache_servers = variable_get('memcache_servers', array('127.0.0.1:11211' => 'default'));
   $clusters = array();
-  foreach ($memcache_servers as $server => $cluster) {
-    $clusters[$cluster]['servers'][] = $server;
-    $clusters[$cluster]['bin'] = _memcache_admin_get_bin_for_cluster($cluster);
+  foreach ($memcache_servers as $server => $bin) {
+    if ($cluster = dmemcache_object_cluster($bin)) {
+      $clusters[$cluster]['servers'][] = $server;
+      $clusters[$cluster]['bin'] = _memcache_admin_get_bin_for_cluster($cluster['cluster']);
+    }
   }
 
   $count = 0;
@@ -272,47 +274,45 @@ function memcache_admin_stats($bin = 'default') {
   $output = '';
   $server = array();
   $stats = dmemcache_stats($bin, 'default', TRUE);
-  if (empty($stats)) {
+  if (empty($stats[$bin])) {
     // Failed to load statistics. Provide a useful error about where to get
     // more information and help.
-    drupal_set_message(t('There may be a problem with your Memcache configuration. Please review %readme and !more for more information.', array('%readme' => 'README.txt', 'admin/reports/status', '!more' => module_exists('memcache') ? t('visit the Drupal admin !status page', array('!status' => l(t('status report'), 'admin/reports/status'))) : t('!enable the memcache module', array('!enable' => l(t('enable'), 'admin/modules', array('fragment' => 'edit-modules-performance-and-scalability')))))), 'error');
+    drupal_set_message(t('Failed to retreive statistics. There may be a problem with your Memcache configuration. Please review %readme and !more for more information.', array('%readme' => 'README.txt', 'admin/reports/status', '!more' => module_exists('memcache') ? t('visit the Drupal admin !status page', array('!status' => l(t('status report'), 'admin/reports/status'))) : t('!enable the memcache module', array('!enable' => l(t('enable'), 'admin/modules', array('fragment' => 'edit-modules-performance-and-scalability')))))), 'error');
   }
   else {
-    if (count($stats[$bin])) {
-      $stats = $stats[$bin];
-      $aggregate = array_pop($stats);
-      $mc = dmemcache_object($bin);
-      if ($mc instanceof Memcached) {
-        $version = t('Memcached v!version', array('!version' => phpversion('Memcached')));
-      }
-      elseif ($mc instanceof Memcache) {
-        $version = t('Memcache v!version', array('!version' => phpversion('Memcache')));
+    $stats = $stats[$bin];
+    $aggregate = array_pop($stats);
+    $mc = dmemcache_object($bin);
+    if ($mc instanceof Memcached) {
+      $version = t('Memcached v!version', array('!version' => phpversion('Memcached')));
+    }
+    elseif ($mc instanceof Memcache) {
+      $version = t('Memcache v!version', array('!version' => phpversion('Memcache')));
+    }
+    else {
+      $version = t('Unknown');
+      drupal_set_message(t('Failed to detect the memcache PECL extension.'), 'error');
+    }
+    $memcache_servers = variable_get('memcache_servers', array('127.0.0.1:11211' => 'default'));
+
+    foreach ($stats as $server => $statistics) {
+      if (empty($statistics['uptime'])) {
+        drupal_set_message(t('Failed to connect to server at %address.', array('%address' => $server)), 'error');
       }
       else {
-        $version = t('Unknown');
-        drupal_set_message(t('Failed to detect the memcache PECL extension.'), 'error');
-      }
-      $memcache_servers = variable_get('memcache_servers', array('127.0.0.1:11211' => 'default'));
-
-      foreach ($stats as $server => $statistics) {
-        if (empty($statistics['uptime'])) {
-          drupal_set_message(t('Failed to connect to server at %address.', array('%address' => $server)), 'error');
-        }
-        else {
-          $servers[] = $server;
-          $data['server_overview'][$server] = t('v!version running !uptime', array('!version' => check_plain($statistics['version']), '!uptime' => format_interval($statistics['uptime'])));
-          $data['server_pecl'][$server] = t('n/a');
-          $data['server_serialize'][$server] = t('n/a');
-          $data['server_time'][$server] = format_date($statistics['time']);
-          $data['server_connections'][$server] = _memcache_admin_stats_connections($statistics);
-          $data['cache_sets'][$server] = _memcache_admin_stats_sets($statistics);
-          $data['cache_gets'][$server] = _memcache_admin_stats_gets($statistics);
-          $data['cache_counters'][$server] = _memcache_admin_stats_counters($statistics);
-          $data['cache_transfer'][$server] = _memcache_admin_stats_transfer($statistics);
-          $data['cache_average'][$server] = _memcache_admin_stats_average($statistics);
-          $data['memory_available'][$server] = _memcache_admin_stats_memory($statistics);
-          $data['memory_evictions'][$server] = number_format($statistics['evictions']);
-        }
+        $servers[] = $server;
+        $data['server_overview'][$server] = t('v!version running !uptime', array('!version' => check_plain($statistics['version']), '!uptime' => format_interval($statistics['uptime'])));
+        $data['server_pecl'][$server] = t('n/a');
+        $data['server_serialize'][$server] = t('n/a');
+        $data['server_time'][$server] = format_date($statistics['time']);
+        $data['server_connections'][$server] = _memcache_admin_stats_connections($statistics);
+        $data['cache_sets'][$server] = _memcache_admin_stats_sets($statistics);
+        $data['cache_gets'][$server] = _memcache_admin_stats_gets($statistics);
+        $data['cache_counters'][$server] = _memcache_admin_stats_counters($statistics);
+        $data['cache_transfer'][$server] = _memcache_admin_stats_transfer($statistics);
+        $data['cache_average'][$server] = _memcache_admin_stats_average($statistics);
+        $data['memory_available'][$server] = _memcache_admin_stats_memory($statistics);
+        $data['memory_evictions'][$server] = number_format($statistics['evictions']);
       }
     }
 
