Commit 56ba252e authored by Robin McCorkell's avatar Robin McCorkell Committed by Thomas Müller

Add Redis Cluster support

parent 53c0129e
......@@ -931,19 +931,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.
......
......@@ -48,8 +48,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);
......@@ -58,18 +58,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;
......@@ -77,7 +77,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)) {
......@@ -110,7 +110,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);
}
/**
......@@ -124,7 +124,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);
}
/**
......@@ -139,10 +139,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;
}
......@@ -158,10 +158,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;
}
......@@ -170,7 +170,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() {
......
......@@ -39,32 +39,47 @@ 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', []);
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']);
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment