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.