Skip to content

Commit

Permalink
Add Redis Cluster support
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinMcCorkell authored and DeepDiver1975 committed Oct 19, 2016
1 parent 0f8bf00 commit a4c677c
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 40 deletions.
30 changes: 27 additions & 3 deletions config/config.sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -919,19 +919,43 @@
'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.
Expand Down
28 changes: 14 additions & 14 deletions lib/private/Memcache/Redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ protected function getNameSpace() {
}

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);
Expand All @@ -58,26 +58,26 @@ public function get($key) {

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;
}
}

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)) {
Expand Down Expand Up @@ -110,7 +110,7 @@ public function add($key, $value, $ttl = 0) {
* @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);
}

/**
Expand All @@ -124,7 +124,7 @@ public function dec($key, $step = 1) {
if (!$this->hasKey($key)) {
return false;
}
return self::$cache->decrBy($this->getNamespace() . $key, $step);
return self::$cache->decrBy($this->getNameSpace() . $key, $step);
}

/**
Expand All @@ -139,10 +139,10 @@ public function cas($key, $old, $new) {
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;
}
Expand All @@ -158,10 +158,10 @@ public function cas($key, $old, $new) {
* @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;
}
Expand All @@ -170,7 +170,7 @@ public function cad($key, $old) {
}

public function setTTL($key, $ttl) {
self::$cache->expire($this->getNamespace() . $key, $ttl);
self::$cache->expire($this->getNameSpace() . $key, $ttl);
}

static public function isAvailable() {
Expand Down
61 changes: 38 additions & 23 deletions lib/private/RedisFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,32 +38,47 @@ public function __construct(SystemConfig $config) {
}

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']);
}
}
}

Expand Down

0 comments on commit a4c677c

Please sign in to comment.