$this->retryWait is in milliseconds. It's setter misleadingly document it as seconds.
Fixing by renaming the argument variable name without altering the functionality.
Authentication for sentinels was implemented in v1.1.5 (commit 2e76410)
but ended up being bugged (see ISSUE #658). This is now postponed as it
requires a more thorough investigation.
Password-based authentication for sentinels has been added in Redis 5.
Predis was actively ignoring any "password" parameter for sentinels when
creating connections to them to avoid issues when this parameter is set
in the default "parameters" array passed via client options, as they are
applied to **every** connection created by Predis (see #346).
We need to find a better way to specify a common password for sentinels
to be handled in a different way than the ones for Redis nodes. For now
each sentinel node protected by password must have an explicit password
set in its parameters list even if this password, by design, is the same
for all sentinels. Since we cannot use default "parameters" as explained
above but we still need to pass a common value for all sentinels an idea
could be using a dedicated client option like we did with "service", but
we will see later.
In this commit we also explicitly reset any "username" parameter as it
would trigger an `AUTH $username $password` but sentinels do not support
ACL authentication.
Fixes#594.
ROLE was not being sent to master when still disconnected and with an
empty slaves pool preventing the client from checking the actual role
of the server upon connect().
Now we do not extend Predis\Connection\Aggregate\MasterSlaveReplication
anymore in order to obtain a more coherent implementation with the logic
of redis-sentinel and apply more optimizations by avoiding useless round
trips with sentinel servers.
Once the client discovers the address of the master or a slave instance,
it must connect to that node and issue a ROLE command to verify that its
role still matches what the client got from the sentinel server.
I think it is better to have a default limit to the number of attempts
when trying to send a command after a connection failure, I am just not
sure if 20 is a good value but we can adjust it later.
This can be optionally done automatically but is disabled by default, just use
SentinelReplication::setUpdateSentinels() accordingly to enable the automatic
fetching of an updated list of sentinels.
By default, when the current server dies while executing a command Predis asks
for a new configuration to one of the sentinels and re-issues the same command.
This behavior can be disabled calling SentinelReplication::setAutomaticRetry().
This value should be reasonably low so that the client can fallback to the next
sentinel if the connect() operation is taking too much and slowing things down.
When the connection parameters of sentinels contain a "timeout" parameter, its
value takes the precedence over the default sentinels timeout.
This is a first implementation that is based on the work of @vmattila but some
more changes and missing bits are required in order to be considered complete.
To leverage redis-sentinel the client must be configured using the "aggregate"
option instead of the usual "replication" option, thought this may change for
the release of Predis v1.1.0 (it __will__ change for Predis v2.0.0 but this is
a whole different matter). This is a configuration example:
use Predis\Connection\Aggregate\SentinelReplication;
$sentinels = [
'tcp://127.0.0.1:5381',
'tcp://127.0.0.1:5382',
'tcp://127.0.0.1:5383',
];
$client = new Predis\Client($sentinels, [
'service' => 'nrk-master',
'aggregate' => function() {
return function ($sentinels, $options) {
$service = $option->service;
$connections = $options->connections;
return new SentinelReplication($sentinels, $service, $connections);
};
},
]);
The missing bits right now are:
- A more solid handling of failures when querying sentinels.
- When the connection fails while executing a command on one of the servers,
we should query again a sentinel and then re-issue the command accordingly.