diff --git a/config/config.sample.php b/config/config.sample.php
index 0fbd3ffce07372600ffd2e2761d7fe16e0b8b7d4..84b98550fb0e4eda88d1d696c8ee29d4b782097e 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -1042,19 +1042,43 @@ $CONFIG = array(
 'memcache.distributed' => '\OC\Memcache\Memcached',
 
 /**
- * Connection details for redis to use for memory caching.
+ * Connection details for redis to use for memory caching in a single server configuration.
  *
  * For enhanced security it is recommended to configure Redis
  * to require a password. See http://redis.io/topics/security
  * for more information.
  */
-'redis' => array(
+'redis' => [
 	'host' => 'localhost', // can also be a unix domain socket: '/tmp/redis.sock'
 	'port' => 6379,
 	'timeout' => 0.0,
 	'password' => '', // Optional, if not defined no password will be used.
 	'dbindex' => 0, // Optional, if undefined SELECT will not run and will use Redis Server's default DB Index.
-),
+],
+
+/**
+ * Connection details for a Redis Cluster
+ *
+ * Only for use with Redis Clustering, for Sentinel-based setups use the single
+ * server configuration above, and perform HA on the hostname.
+ *
+ * Redis Cluster support requires the php module phpredis in version 3.0.0 or higher.
+ *
+ * Available failover modes:
+ *  - \RedisCluster::FAILOVER_NONE - only send commands to master nodes (default)
+ *  - \RedisCluster::FAILOVER_ERROR - failover to slaves for read commands if master is unavailable
+ *  - \RedisCluster::FAILOVER_DISTRIBUTE - randomly distribute read commands across master and slaves
+ */
+'redis.cluster' => [
+	'seeds' => [ // provide some/all of the cluster servers to bootstrap discovery, port required
+		'localhost:7000',
+		'localhost:7001'
+	],
+	'timeout' => 0.0,
+	'read_timeout' => 0.0,
+	'failover_mode' => \RedisCluster::FAILOVER_DISTRIBUTE
+],
+
 
 /**
  * Server details for one or more memcached servers to use for memory caching.
diff --git a/lib/private/Memcache/Redis.php b/lib/private/Memcache/Redis.php
index c3184e458560e0dff7f76e9c75da384303462d9f..d423b134f9537029cb9914a3060390eec6a0d337 100644
--- a/lib/private/Memcache/Redis.php
+++ b/lib/private/Memcache/Redis.php
@@ -49,8 +49,8 @@ class Redis extends Cache implements IMemcacheTTL {
 	}
 
 	public function get($key) {
-		$result = self::$cache->get($this->getNamespace() . $key);
-		if ($result === false && !self::$cache->exists($this->getNamespace() . $key)) {
+		$result = self::$cache->get($this->getNameSpace() . $key);
+		if ($result === false && !self::$cache->exists($this->getNameSpace() . $key)) {
 			return null;
 		} else {
 			return json_decode($result, true);
@@ -59,18 +59,18 @@ class Redis extends Cache implements IMemcacheTTL {
 
 	public function set($key, $value, $ttl = 0) {
 		if ($ttl > 0) {
-			return self::$cache->setex($this->getNamespace() . $key, $ttl, json_encode($value));
+			return self::$cache->setex($this->getNameSpace() . $key, $ttl, json_encode($value));
 		} else {
-			return self::$cache->set($this->getNamespace() . $key, json_encode($value));
+			return self::$cache->set($this->getNameSpace() . $key, json_encode($value));
 		}
 	}
 
 	public function hasKey($key) {
-		return self::$cache->exists($this->getNamespace() . $key);
+		return self::$cache->exists($this->getNameSpace() . $key);
 	}
 
 	public function remove($key) {
-		if (self::$cache->delete($this->getNamespace() . $key)) {
+		if (self::$cache->delete($this->getNameSpace() . $key)) {
 			return true;
 		} else {
 			return false;
@@ -78,7 +78,7 @@ class Redis extends Cache implements IMemcacheTTL {
 	}
 
 	public function clear($prefix = '') {
-		$prefix = $this->getNamespace() . $prefix . '*';
+		$prefix = $this->getNameSpace() . $prefix . '*';
 		$it = null;
 		self::$cache->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY);
 		while ($keys = self::$cache->scan($it, $prefix)) {
@@ -111,7 +111,7 @@ class Redis extends Cache implements IMemcacheTTL {
 	 * @return int | bool
 	 */
 	public function inc($key, $step = 1) {
-		return self::$cache->incrBy($this->getNamespace() . $key, $step);
+		return self::$cache->incrBy($this->getNameSpace() . $key, $step);
 	}
 
 	/**
@@ -125,7 +125,7 @@ class Redis extends Cache implements IMemcacheTTL {
 		if (!$this->hasKey($key)) {
 			return false;
 		}
-		return self::$cache->decrBy($this->getNamespace() . $key, $step);
+		return self::$cache->decrBy($this->getNameSpace() . $key, $step);
 	}
 
 	/**
@@ -140,10 +140,10 @@ class Redis extends Cache implements IMemcacheTTL {
 		if (!is_int($new)) {
 			$new = json_encode($new);
 		}
-		self::$cache->watch($this->getNamespace() . $key);
+		self::$cache->watch($this->getNameSpace() . $key);
 		if ($this->get($key) === $old) {
 			$result = self::$cache->multi()
-				->set($this->getNamespace() . $key, $new)
+				->set($this->getNameSpace() . $key, $new)
 				->exec();
 			return ($result === false) ? false : true;
 		}
@@ -159,10 +159,10 @@ class Redis extends Cache implements IMemcacheTTL {
 	 * @return bool
 	 */
 	public function cad($key, $old) {
-		self::$cache->watch($this->getNamespace() . $key);
+		self::$cache->watch($this->getNameSpace() . $key);
 		if ($this->get($key) === $old) {
 			$result = self::$cache->multi()
-				->del($this->getNamespace() . $key)
+				->del($this->getNameSpace() . $key)
 				->exec();
 			return ($result === false) ? false : true;
 		}
@@ -171,7 +171,7 @@ class Redis extends Cache implements IMemcacheTTL {
 	}
 
 	public function setTTL($key, $ttl) {
-		self::$cache->expire($this->getNamespace() . $key, $ttl);
+		self::$cache->expire($this->getNameSpace() . $key, $ttl);
 	}
 
 	static public function isAvailable() {
diff --git a/lib/private/RedisFactory.php b/lib/private/RedisFactory.php
index 3ba637c414229b8c92595defcbc3a6b2ed380aab..e254d36aa062fd1586f8ff42e2b8746094096d68 100644
--- a/lib/private/RedisFactory.php
+++ b/lib/private/RedisFactory.php
@@ -39,32 +39,46 @@ class RedisFactory {
 	}
 
 	private function create() {
-		$this->instance = new \Redis();
-		// TODO allow configuring a RedisArray, see https://github.com/nicolasff/phpredis/blob/master/arrays.markdown#redis-arrays
-		$config = $this->config->getValue('redis', array());
-		if (isset($config['host'])) {
-			$host = $config['host'];
-		} else {
-			$host = '127.0.0.1';
-		}
-		if (isset($config['port'])) {
-			$port = $config['port'];
-		} else {
-			$port = 6379;
-		}
-		if (isset($config['timeout'])) {
-			$timeout = $config['timeout'];
+		if ($config = $this->config->getValue('redis.cluster', [])) {
+			if (!class_exists('RedisCluster')) {
+				throw new \Exception('Redis Cluster support is not available');
+			}
+			// cluster config
+			$timeout = isset($config['timeout']) ? $config['timeout'] : null;
+			$readTimeout = isset($config['read_timeout']) ? $config['read_timeout'] : null;
+			$this->instance = new \RedisCluster(null, $config['seeds'], $timeout, $readTimeout);
+
+			if (isset($config['failover_mode'])) {
+				$this->instance->setOption(\RedisCluster::OPT_FAILOVER, $config['failover_mode']);
+			}
 		} else {
-			$timeout = 0.0; // unlimited
-		}
 
-		$this->instance->connect($host, $port, $timeout);
-		if (isset($config['password']) && $config['password'] !== '') {
-			$this->instance->auth($config['password']);
-		}
+			$this->instance = new \Redis();
+			$config = $this->config->getValue('redis', []);
+			if (isset($config['host'])) {
+				$host = $config['host'];
+			} else {
+				$host = '127.0.0.1';
+			}
+			if (isset($config['port'])) {
+				$port = $config['port'];
+			} else {
+				$port = 6379;
+			}
+			if (isset($config['timeout'])) {
+				$timeout = $config['timeout'];
+			} else {
+				$timeout = 0.0; // unlimited
+			}
+
+			$this->instance->connect($host, $port, $timeout);
+			if (isset($config['password']) && $config['password'] !== '') {
+				$this->instance->auth($config['password']);
+			}
 
-		if (isset($config['dbindex'])) {
-			$this->instance->select($config['dbindex']);
+			if (isset($config['dbindex'])) {
+				$this->instance->select($config['dbindex']);
+			}
 		}
 	}