These parameters are applied only to connections being created on the
fly when not part of the current pool. This condition usually happens
upon -MOVE or -ASK responses returned by Redis to redirect client to
different nodes.
List of changes:
- The cluster connection can be initialized with a partial list of
nodes, the full slots map will be fetched from Redis itself using
the CLUSTER NODES command.
- The slots map can be optionally retrieved from Redis if the server
returns a -MOVE response, otherwise only the interested slot will
be permanently reassigned to the new target node.
- $cluster->connect() connects to a random connection in the pool
instead of forcing the connect operation on all the connections.
We must always execute ASKING on the connection identified by the -ASK
response before executing the actual command because not doing so will
break the cluster specifications while redis-cluster is performing a
resharding operation.
This commit reflects the recent change from the redis unstable branch
in which the number of hash slots was increased from 4096 to 16384.
See https://github.com/antirez/redis/commit/ebd666d for reference.
We extract the keys from commands using the second argument of EVAL /
EVALSHA which specifies the number of arguments that must be treated
as keys (used to populate the KEYS table in the Lua script) and then
we check if there is only one key since redis-cluster right now does
not support multi-keys requests.
Our scripted command abstraction is also supported.
This should make things a tiny bit faster (we are speaking about micro
optimizations anyway) but more importantly it results in a better
encapsulation.
This makes it possible to easily assign a connection to a slot range
using the key "slots" in connection parameters like in the following
example:
$parameters = array(
'tcp://127.0.0.1:6379?slots=0-1364',
'tcp://127.0.0.1:6380?slots=1365-2729',
'tcp://127.0.0.1:6381?slots=2730-4095',
);
$options = array('cluster' => 'redis');
$client = new Predis\Client($parameters, $options);
It is possible to get the full list of slot ranges for each node of
the cluster using redis-cli connected to one of the nodes:
./redis-cli -h 127.0.0.1 -p 6379 CLUSTER NODES
The last column in the resulting output contains the slots assigned
to each instance participating to the redis cluster.
This is useful to avoid guessing the correct server instance at runtime
thus reducing the overhead of a guess-and-try approach since relying on
-ASK or -MOVED responses returned by a node is a costly operation.
For now, you can pre-associate slots using the "cluster" client option:
$parameters = array(
'tcp://127.0.0.1:6379',
'tcp://127.0.0.1:6380',
'tcp://127.0.0.1:6381',
);
$options = array(
'cluster' => function ($options) {
$cluster = new Predis\Connection\RedisCluster();
$cluster->setSlots(0, 1364, '127.0.0.1:6379');
$cluster->setSlots(1365, 2729, '127.0.0.1:6380');
$cluster->setSlots(2730, 4095, '127.0.0.1:6381');
return $cluster;
},
);
$client = new Predis\Client($parameters, $options);
In the future we will make the slots configuration easier by fetching
the configuration from a node using the command "CLUSTER NODES" or by
pre-computing the slices of slots associated to a node when adding it
to the cluster connection object.
This is needed because redis-cluster does not support the same commands
or operations that can be performed with our client-side managed predis
cluster.
For example redis-cluster does not support key tagging (that is, parts
of a key enclosed by {...} to hash only that specific part of a key)
and multiple-key operations suchs as MGET, MSET, SDIFF, SUNION or SINTER.
Some multiple-key operations can be performed anyway if the command has
only one key (e.g. "MGET foo" and "MSET foo bar" will not fail).
This implementation is capable of handling "ASK" and "MOVED" replies
returned by Redis when one of the nodes asks the client for temporary
or permanent redirects of a slot to a different node.
Performances look almost on par with our client-side sharding solution
and everything looks already relatively stable.
Tests are still missing.