mirror of
https://github.com/predis/predis.git
synced 2026-08-31 04:35:05 +00:00
Make it possible to pre-associate slots to a connection.
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 commit is contained in:
@@ -29,6 +29,7 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
|
||||
{
|
||||
private $pool;
|
||||
private $slots;
|
||||
private $slotsMap;
|
||||
private $connections;
|
||||
private $distributor;
|
||||
private $cmdHasher;
|
||||
@@ -40,6 +41,7 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
|
||||
{
|
||||
$this->pool = array();
|
||||
$this->slots = array();
|
||||
$this->slotsMap = array();
|
||||
$this->connections = $connections ?: new ConnectionFactory();
|
||||
$this->distributor = new CRC16HashGenerator();
|
||||
$this->cmdHasher = new RedisClusterHashStrategy();
|
||||
@@ -119,6 +121,27 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preassociate a connection to a set of slots to avoid runtime guessing.
|
||||
*
|
||||
* @todo Check type or existence of the specified connection.
|
||||
*
|
||||
* @param int $first Initial slot.
|
||||
* @param int $last Last slot.
|
||||
* @param ConnectionSingleInterface|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);
|
||||
$this->slotsMap = array_merge($this->slotsMap, $slots);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -142,7 +165,12 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
|
||||
return $this->slots[$slot];
|
||||
}
|
||||
|
||||
$this->slots[$slot] = $connection = $this->pool[array_rand($this->pool)];
|
||||
if (isset($this->slotsMap[$slot])) {
|
||||
$this->slots[$slot] = $connection = $this->pool[$this->slotsMap[$slot]];
|
||||
}
|
||||
|
||||
$connection = $this->pool[isset($this->slotsMap[$slot]) ? $this->slotsMap[$slot] : array_rand($this->pool)];
|
||||
$this->slots[$slot] = $connection;
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user