Pre-associate connections to slot ranges using connection parameters.

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 commit is contained in:
Daniele Alessandri
2012-07-29 19:38:58 +02:00
parent 8559c2cb30
commit febd99421f
+22 -7
View File
@@ -87,7 +87,12 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
public function add(SingleConnectionInterface $connection)
{
$parameters = $connection->getParameters();
$this->pool["{$parameters->host}:{$parameters->port}"] = $connection;
$this->pool[$connectionID = "{$parameters->host}:{$parameters->port}"] = $connection;
if (isset($parameters->slots)) {
@list($first, $last) = explode('-', $parameters->slots, 2);
$this->setSlots($first, $last, $connectionID);
}
}
/**
@@ -128,17 +133,15 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
*
* @param int $first Initial slot.
* @param int $last Last slot.
* @param ConnectionSingleInterface|string $connection ID or connection instance.
* @param SingleConnectionInterface|string $connection ID or connection instance.
*/
public function setSlots($first, $last, $connection)
{
$connection = (string) $connection;
if ($first < 0 || $first > 4095 || $last < 0 || $last > 4095 || $last < $first) {
throw new \OutOfBoundsException("Invalid slot values for $connection: [$first-$last]");
}
$slots = array_fill($first, $last - $first + 1, $connection);
$slots = array_fill($first, $last - $first + 1, (string) $connection);
$this->slotsMap = array_merge($this->slotsMap, $slots);
}
@@ -209,8 +212,7 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
switch ($request) {
case 'MOVED':
$this->add($connection);
$this->slots[(int) $slot] = $connection;
$this->move($connection, $slot);
return $this->executeCommand($command);
case 'ASK':
@@ -221,6 +223,19 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
}
}
/**
* Assign the connection instance to a new slot and adds it to the
* pool if the connection was not already part of the pool.
*
* @param SingleConnectionInterface $connection Connection instance
* @param int $slot Target slot.
*/
protected function move(SingleConnectionInterface $connection, $slot)
{
$this->pool[(string) $connection] = $connection;
$this->slots[(int) $slot] = $connection;
}
/**
* Returns the underlying command hash strategy used to hash
* commands by their keys.