|
@@ -1,2 +1,161 @@
|
|
|
+.. vim: set ts=3 sw=3 et :
|
|
|
+
|
|
|
+.. php:namespace:: Predis
|
|
|
+
|
|
|
Clustering
|
|
|
----------
|
|
|
+
|
|
|
+A "cluster" is a group of Redis servers that collectively provide a shared
|
|
|
+namespace. In a cluster, data is not shared between Redis instances; instead,
|
|
|
+each server is used to serve a portion of the keys.
|
|
|
+
|
|
|
+In broad terms, this is done by identifying the key part of each Predis command
|
|
|
+to be run on the clustered connection. This key is then used to distribute
|
|
|
+commands among the underlying connections.
|
|
|
+
|
|
|
+Clustering has obvious advantages. As you add Redis instances to your
|
|
|
+cluster, your available space increases. At the same time, commands should be
|
|
|
+distributed between the nodes, meaning each individual node has to service
|
|
|
+less requests.
|
|
|
+
|
|
|
+
|
|
|
+Distribution Strategy
|
|
|
+=====================
|
|
|
+
|
|
|
+Exactly how keys are split across a cluster is specified by a
|
|
|
+:term:`distribution strategy`. There are two distribution strategy classes shipped
|
|
|
+with Predis. What they have in common is that they try to manage the task of
|
|
|
+adding and removing servers from the cluster cleverly.
|
|
|
+
|
|
|
+When a server is added or removed, the distribution strategy takes care of
|
|
|
+ensuring that as few keys as possible have to be moved between the remaining
|
|
|
+servers. When you remove a server from a clustered connection of ten servers,
|
|
|
+ideally you'd only like 10% of your keys to be newly missing.
|
|
|
+
|
|
|
+This is broadly known as "`consistent hashing`_".
|
|
|
+
|
|
|
+.. _consistent hashing: https://en.wikipedia.org/wiki/Consistent_hashing
|
|
|
+
|
|
|
+Configuring a Cluster
|
|
|
+=====================
|
|
|
+
|
|
|
+Recall that the `Client` constructor takes two types of argument: a
|
|
|
+set of connection parameters, and a set of options::
|
|
|
+
|
|
|
+ $client = new Predis\Client($connection, $options);
|
|
|
+
|
|
|
+You only need to do one thing differently to set up a clustered client:
|
|
|
+identify multiple connections. You can also, optionally, configure your cluster
|
|
|
+with the ``cluster`` client option.
|
|
|
+
|
|
|
+Configuring Multiple Connections
|
|
|
+''''''''''''''''''''''''''''''''
|
|
|
+
|
|
|
+Passing information about multiple connections is as simple as wrapping them
|
|
|
+all in an array::
|
|
|
+
|
|
|
+ $client = new Predis\Client(array(
|
|
|
+ array(
|
|
|
+ 'host' => '127.0.0.1',
|
|
|
+ 'port' => 6379,
|
|
|
+ 'database' => 2,
|
|
|
+ 'alias' => 'first'
|
|
|
+ ),
|
|
|
+ array(
|
|
|
+ 'host' => '127.0.0.1',
|
|
|
+ 'port' => 6379,
|
|
|
+ 'database' => 3,
|
|
|
+ 'alias' => 'second',
|
|
|
+ )
|
|
|
+ ), $options);
|
|
|
+
|
|
|
+You can still use the URI syntax to configure the connections::
|
|
|
+
|
|
|
+ $client = new Predis\Client(array(
|
|
|
+ 'tcp://127.0.0.1:6370?alias=first&db=0',
|
|
|
+ 'tcp://127.0.0.1:6370?alias=second&db=1'
|
|
|
+ ), $options);
|
|
|
+
|
|
|
+.. note::
|
|
|
+
|
|
|
+ When you want to pass information about multiple connections, Predis expects
|
|
|
+ you'll do so with a numeric array, indexed from 0. If you've removed
|
|
|
+ connections from your array (perhaps after catching a
|
|
|
+ `Predis\\CommunicationException`), you can use array_values() to reindex it.
|
|
|
+
|
|
|
+ If your connection array does not have a value at [0], Predis
|
|
|
+ will assume you're trying to configure a single connection with an
|
|
|
+ associative array.
|
|
|
+
|
|
|
+The ``cluster`` Client Option
|
|
|
+'''''''''''''''''''''''''''''
|
|
|
+.. php:namespace:: Predis\Connection
|
|
|
+
|
|
|
+You can optionally confiugre your client's clustering by using the ``cluster``
|
|
|
+client option. This option can take a few different types of value. It can take
|
|
|
+the special strings ``"predis"`` or ``"redis"`` to switch between the two
|
|
|
+built-in cluster connection classes `PredisCluster` and
|
|
|
+`RedisCluster` respectively::
|
|
|
+
|
|
|
+ $client = new Predis\Client(array(
|
|
|
+ // ...
|
|
|
+ ), array('cluster' => 'predis'));
|
|
|
+
|
|
|
+If the value is any other string, it's expected to be the fully qualified name
|
|
|
+of a class implementing `ClusterConnectionInterface`.
|
|
|
+
|
|
|
+Finally, you can also configure the option with a callable. This callable is
|
|
|
+expected to return an instance of `ClusterConnectionInterface`. The two
|
|
|
+built-in clustered connection types both accept a
|
|
|
+`Predis\\Cluster\\Distribution\\DistributionStrategyInterface` instance as
|
|
|
+their first argument, allowing you to configure that as well::
|
|
|
+
|
|
|
+ $client = new Predis\Client(array(
|
|
|
+ // ...
|
|
|
+ ), array(
|
|
|
+ 'cluster' => function () {
|
|
|
+ $strategy = new Predis\Cluster\Distribution\KetamaPureRing();
|
|
|
+ return new Predis\Connection\PredisCluster($strategy);
|
|
|
+ }
|
|
|
+ ));
|
|
|
+
|
|
|
+Connection Classes
|
|
|
+""""""""""""""""""
|
|
|
+
|
|
|
+.. php:class:: PredisCluster
|
|
|
+
|
|
|
+ ``PredisCluster`` is a simple Predis-native clustered connection implementation.
|
|
|
+
|
|
|
+ This form of clustered connection does *not* provide redundancy. If your application
|
|
|
+ makes requests for 100 different keys, with the default distribution strategy
|
|
|
+ these keys are likely to be spit across all the servers in your pool.
|
|
|
+
|
|
|
+.. php:class:: RedisCluster
|
|
|
+
|
|
|
+ ``RedisCluster`` is a clustered connection implementation intended for use with
|
|
|
+ Redis Cluster. Redis Cluster is not yet finalized, but it already includes some
|
|
|
+ pretty cool features. Nodes in a Redis Cluster arrangement configure
|
|
|
+ themselves to deal with changes in availability.
|
|
|
+
|
|
|
+Disallowed Commands
|
|
|
+===================
|
|
|
+
|
|
|
+Some commands just don't make sense to run on a clustered connection. For
|
|
|
+example, the ``INFO`` command returns information about the server on which
|
|
|
+it's run, so running it on a cluster would be meaningless.
|
|
|
+
|
|
|
+If you try to run one of these commands, you'll get a
|
|
|
+``Predis\\NotSupportedException``.
|
|
|
+
|
|
|
+Running Commands on Nodes
|
|
|
+=========================
|
|
|
+
|
|
|
+`PredisCluster` and :php:class:`RedisCluster` both
|
|
|
+implement `\\IteratorAggregate`, so you can easily run commands against the
|
|
|
+individual Redis servers in a cluster::
|
|
|
+
|
|
|
+ $hosts = array();
|
|
|
+ foreach ($client->getConnection() as $shard) {
|
|
|
+ $hosts[] = $shard->info();
|
|
|
+ }
|
|
|
+
|