Merge pull request #4061 from nextcloud/downstream-26407
Redis cluster support
This commit is contained in:
commit
752b219970
3 changed files with 87 additions and 41 deletions
|
@ -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.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -39,32 +39,54 @@ 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'];
|
||||
} else {
|
||||
$timeout = 0.0; // unlimited
|
||||
}
|
||||
if ($config = $this->config->getValue('redis.cluster', [])) {
|
||||
if (!class_exists('RedisCluster')) {
|
||||
throw new \Exception('Redis Cluster support is not available');
|
||||
}
|
||||
// cluster config
|
||||
if (isset($config['timeout'])) {
|
||||
$timeout = $config['timeout'];
|
||||
} else {
|
||||
$timeout = null;
|
||||
}
|
||||
if (isset($config['read_timeout'])) {
|
||||
$readTimeout = $config['read_timeout'];
|
||||
} else {
|
||||
$readTimeout = null;
|
||||
}
|
||||
$this->instance = new \RedisCluster(null, $config['seeds'], $timeout, $readTimeout);
|
||||
|
||||
$this->instance->connect($host, $port, $timeout);
|
||||
if (isset($config['password']) && $config['password'] !== '') {
|
||||
$this->instance->auth($config['password']);
|
||||
}
|
||||
if (isset($config['failover_mode'])) {
|
||||
$this->instance->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, $config['failover_mode']);
|
||||
}
|
||||
} else {
|
||||
|
||||
if (isset($config['dbindex'])) {
|
||||
$this->instance->select($config['dbindex']);
|
||||
$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']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue