123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- .. 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();
- }
|