|
@@ -84,6 +84,7 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
|
|
public function add(SingleConnectionInterface $connection)
|
|
public function add(SingleConnectionInterface $connection)
|
|
{
|
|
{
|
|
$this->pool[(string) $connection] = $connection;
|
|
$this->pool[(string) $connection] = $connection;
|
|
|
|
+ unset($this->slotsMap);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -93,6 +94,7 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
|
|
{
|
|
{
|
|
if (($id = array_search($connection, $this->pool, true)) !== false) {
|
|
if (($id = array_search($connection, $this->pool, true)) !== false) {
|
|
unset($this->pool[$id]);
|
|
unset($this->pool[$id]);
|
|
|
|
+ unset($this->slotsMap);
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -118,9 +120,9 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Recreates the slots map for the cluster.
|
|
|
|
|
|
+ * Builds the slots map for the cluster.
|
|
*/
|
|
*/
|
|
- public function resetSlotsMap()
|
|
|
|
|
|
+ public function buildSlotsMap()
|
|
{
|
|
{
|
|
$this->slotsMap = array();
|
|
$this->slotsMap = array();
|
|
|
|
|
|
@@ -161,10 +163,6 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
|
|
*/
|
|
*/
|
|
public function getConnection(CommandInterface $command)
|
|
public function getConnection(CommandInterface $command)
|
|
{
|
|
{
|
|
- if (!isset($this->slotsMap)) {
|
|
|
|
- $this->resetSlotsMap();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
$hash = $command->getHash();
|
|
$hash = $command->getHash();
|
|
|
|
|
|
if (!isset($hash)) {
|
|
if (!isset($hash)) {
|
|
@@ -183,12 +181,34 @@ class RedisCluster implements ClusterConnectionInterface, \IteratorAggregate, \C
|
|
return $this->slots[$slot];
|
|
return $this->slots[$slot];
|
|
}
|
|
}
|
|
|
|
|
|
- $connectionID = isset($this->slotsMap[$slot]) ? $this->slotsMap[$slot] : array_rand($this->pool);
|
|
|
|
- $this->slots[$slot] = $connection = $this->pool[$connectionID];
|
|
|
|
|
|
+ $this->slots[$slot] = $connection = $this->pool[$this->guessNode($slot)];
|
|
|
|
|
|
return $connection;
|
|
return $connection;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Tries guessing the correct node associated to the given slot using a precalculated
|
|
|
|
+ * slots map or the same logic used by redis-trib to initialize a redis cluster.
|
|
|
|
+ *
|
|
|
|
+ * @param int $slot Slot ID.
|
|
|
|
+ * @return string
|
|
|
|
+ */
|
|
|
|
+ protected function guessNode($slot)
|
|
|
|
+ {
|
|
|
|
+ if (!isset($this->slotsMap)) {
|
|
|
|
+ $this->buildSlotsMap();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (isset($this->slotsMap[$slot])) {
|
|
|
|
+ return $this->slotsMap[$slot];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $index = $slot / (int) (4096 / count($this->pool));
|
|
|
|
+ $nodes = array_keys($this->pool);
|
|
|
|
+
|
|
|
|
+ return $nodes[min($index, 4095)];
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* {@inheritdoc}
|
|
* {@inheritdoc}
|
|
*/
|
|
*/
|