Browse Source

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.
Daniele Alessandri 13 năm trước cách đây
mục cha
commit
febd99421f
1 tập tin đã thay đổi với 22 bổ sung7 xóa
  1. 22 7
      lib/Predis/Connection/RedisCluster.php

+ 22 - 7
lib/Predis/Connection/RedisCluster.php

@@ -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.