Skip to content

Commit

Permalink
refs #23 support for Redis sentinel by using a different backend
Browse files Browse the repository at this point in the history
  • Loading branch information
tsteur committed Mar 14, 2016
1 parent 39b9498 commit 82088c8
Show file tree
Hide file tree
Showing 16 changed files with 2,209 additions and 19 deletions.
2 changes: 2 additions & 0 deletions Queue/Backend.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ public function deleteIfKeyHasValue($key, $value);
public function expireIfKeyHasValue($key, $value, $ttlInSeconds);

public function get($key);

public function getKeysMatchingPattern($pattern);
}
32 changes: 20 additions & 12 deletions Queue/Backend/Redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,22 @@
use Piwik\Log;
use Piwik\Plugins\QueuedTracking\Queue\Backend;
use Piwik\Tracker;
use Piwik\Translate;

class Redis implements Backend
{
/**
* @var \Redis
*/
private $redis;
private $host;
private $port;
private $timeout;
private $password;
protected $redis;
protected $host;
protected $port;
protected $timeout;
protected $password;

/**
* @var int
*/
private $database;
protected $database;

public function testConnection()
{
Expand Down Expand Up @@ -162,8 +161,14 @@ public function deleteIfKeyHasValue($key, $value)
else
return 0
end';

// ideally we would use evalSha to reduce bandwidth!
return (bool) $this->redis->eval($script, array($key, $value), 1);
return (bool) $this->evalScript($script, array($key), array($value));
}

protected function evalScript($script, $keys, $args)
{
return $this->redis->eval($script, array_merge($keys, $args), count($keys));
}

public function getKeysMatchingPattern($pattern)
Expand All @@ -187,7 +192,7 @@ public function expireIfKeyHasValue($key, $value, $ttlInSeconds)
return 0
end';
// ideally we would use evalSha to reduce bandwidth!
return (bool) $this->redis->eval($script, array($key, $value, (int) $ttlInSeconds), 1);
return (bool) $this->evalScript($script, array($key), array($value, (int) $ttlInSeconds));
}

public function get($key)
Expand All @@ -213,7 +218,7 @@ private function connectIfNeeded()
}
}

private function connect()
protected function connect()
{
$this->redis = new \Redis();
$success = $this->redis->connect($this->host, $this->port, $this->timeout, null, 100);
Expand All @@ -235,8 +240,11 @@ public function setConfig($host, $port, $timeout, $password)

$this->host = $host;
$this->port = $port;
$this->timeout = $timeout;
$this->password = $password;
$this->timeout = $timeout;

if (!empty($password)) {
$this->password = $password;
}
}

private function disconnect()
Expand Down
36 changes: 36 additions & 0 deletions Queue/Backend/Sentinel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\QueuedTracking\Queue\Backend;

use Piwik\Plugins\QueuedTracking\Queue\Backend;
use Piwik\Tracker;

include_once PIWIK_INCLUDE_PATH . '/plugins/QueuedTracking/libs/credis/Client.php';
include_once PIWIK_INCLUDE_PATH . '/plugins/QueuedTracking/libs/credis/Cluster.php';
include_once PIWIK_INCLUDE_PATH . '/plugins/QueuedTracking/libs/credis/Sentinel.php';

class Sentinel extends Redis
{
protected function connect()
{
$client = new \Credis_Client($this->host, $this->port, $this->timeout, $persistent = false, $this->database, $this->password);
$this->redis = new \Credis_Sentinel($client);
$client->connect();

$this->redis = $client;

return true;
}

protected function evalScript($script, $keys, $args)
{
return $this->redis->eval($script, $keys, $args);
}

}
14 changes: 13 additions & 1 deletion Queue/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Piwik\Plugins\QueuedTracking\Queue;

use Piwik\Config;
use Piwik\Container\StaticContainer;
use Piwik\Plugins\QueuedTracking\Queue;
use Piwik\Plugins\QueuedTracking\Settings;
Expand Down Expand Up @@ -48,6 +49,11 @@ public static function getSettings()
return StaticContainer::get('Piwik\Plugins\QueuedTracking\Settings');
}

private static function getConfig()
{
return Config::getInstance();
}

private static function makeBackendFromSettings(Settings $settings)
{
$host = $settings->redisHost->getValue();
Expand All @@ -56,7 +62,13 @@ private static function makeBackendFromSettings(Settings $settings)
$password = $settings->redisPassword->getValue();
$database = $settings->redisDatabase->getValue();

$redis = new Queue\Backend\Redis();
$queuedTracking = self::getConfig()->QueuedTracking;
if (!empty($queuedTracking['backend']) && $queuedTracking['backend'] === 'sentinel') {
$redis = new Queue\Backend\Sentinel();
} else {
$redis = new Queue\Backend\Redis();
}

$redis->setConfig($host, $port, $timeout, $password);
$redis->setDatabase($database);

Expand Down
3 changes: 1 addition & 2 deletions Queue/Lock.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@
use Piwik\Common;
use Piwik\Plugins\QueuedTracking\Queue\Backend;
use Piwik\Tracker;
use Piwik\Plugins\QueuedTracking\Queue\Backend\Redis;

class Lock
{
/**
* @var Redis
* @var Backend
*/
private $backend;

Expand Down
3 changes: 1 addition & 2 deletions Queue/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@
use Piwik\Plugins\QueuedTracking\Queue\Backend;
use Piwik\Tracker\RequestSet;
use Piwik\Tracker;
use Piwik\Plugins\QueuedTracking\Queue\Backend\Redis;

class Manager
{
/**
* @var Redis
* @var Backend
*/
private $backend;

Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ __How should the redis server be configured?__
Make sure to have enough memory to save all tracking requests in the queue. One tracking request in the queue takes about 2KB,
20.000 tracking requests take about 50MB. All tracking requests of all websites are stored in the same queue.
There should be only one Redis server to make sure the data will be replayed in the same order as they were recorded.
If you want to configure Redis HA (High Availability) it should be possible to use Redis Cluser, Redis Sentinel, ...
If you want to configure Redis HA (High Availability) it is possible to use Redis Sentinel see further down.
We currently write into the Redis default database by default but you can configure to use a different one.

__Why do some tests fail on my local Piwik instance?__
Expand Down Expand Up @@ -124,6 +124,17 @@ __I am using the Log Importer in combination with Queued Tracking, is there some

Yes, we recommend to set the "Number of requests to process" to `1` as the log importer usually sends multiple requests at once using bulk tracking already.

__How can I configure the QueuedTracking plugin to use Sentinel?__

Add the following configuration to your `config/config.ini.php` to enable Sentinel feature:

```
[QueuedTracking]
backend=sentinel
```

In this case the `phpredis` extension is not needed as it uses a PHP class to connect to your Redis. Please note that calls to Redis might be a little bit slower.

__Are there any known issues?__

* In case you are using bulk tracking the bulk tracking response varies compared to the regular one. We will always return
Expand All @@ -134,7 +145,12 @@ __Are there any known issues?__

## Changelog

0.3.0

- Added support to use Redis Sentinel for automatic failover

0.2.6

- When a request takes more than 2 seconds and debug tracker mode is enabled, log information about the request.

0.2.5
Expand Down
Loading

0 comments on commit 82088c8

Please sign in to comment.