clustering.rst 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. .. vim: set ts=3 sw=3 et :
  2. .. php:namespace:: Predis
  3. Clustering
  4. ----------
  5. A "cluster" is a group of Redis servers that collectively provide a shared
  6. namespace. In a cluster, data is not shared between Redis instances; instead,
  7. each server is used to serve a portion of the keys.
  8. In broad terms, this is done by identifying the key part of each Predis command
  9. to be run on the clustered connection. This key is then used to distribute
  10. commands among the underlying connections.
  11. Clustering has obvious advantages. As you add Redis instances to your
  12. cluster, your available space increases. At the same time, commands should be
  13. distributed between the nodes, meaning each individual node has to service
  14. less requests.
  15. Distribution Strategy
  16. =====================
  17. Exactly how keys are split across a cluster is specified by a
  18. :term:`distribution strategy`. There are two distribution strategy classes shipped
  19. with Predis. What they have in common is that they try to manage the task of
  20. adding and removing servers from the cluster cleverly.
  21. When a server is added or removed, the distribution strategy takes care of
  22. ensuring that as few keys as possible have to be moved between the remaining
  23. servers. When you remove a server from a clustered connection of ten servers,
  24. ideally you'd only like 10% of your keys to be newly missing.
  25. This is broadly known as "`consistent hashing`_".
  26. .. _consistent hashing: https://en.wikipedia.org/wiki/Consistent_hashing
  27. Configuring a Cluster
  28. =====================
  29. Recall that the `Client` constructor takes two types of argument: a
  30. set of connection parameters, and a set of options::
  31. $client = new Predis\Client($connection, $options);
  32. You only need to do one thing differently to set up a clustered client:
  33. identify multiple connections. You can also, optionally, configure your cluster
  34. with the ``cluster`` client option.
  35. Configuring Multiple Connections
  36. ''''''''''''''''''''''''''''''''
  37. Passing information about multiple connections is as simple as wrapping them
  38. all in an array::
  39. $client = new Predis\Client(array(
  40. array(
  41. 'host' => '127.0.0.1',
  42. 'port' => 6379,
  43. 'database' => 2,
  44. 'alias' => 'first'
  45. ),
  46. array(
  47. 'host' => '127.0.0.1',
  48. 'port' => 6379,
  49. 'database' => 3,
  50. 'alias' => 'second',
  51. )
  52. ), $options);
  53. You can still use the URI syntax to configure the connections::
  54. $client = new Predis\Client(array(
  55. 'tcp://127.0.0.1:6370?alias=first&db=0',
  56. 'tcp://127.0.0.1:6370?alias=second&db=1'
  57. ), $options);
  58. .. note::
  59. When you want to pass information about multiple connections, Predis expects
  60. you'll do so with a numeric array, indexed from 0. If you've removed
  61. connections from your array (perhaps after catching a
  62. `Predis\\CommunicationException`), you can use array_values() to reindex it.
  63. If your connection array does not have a value at [0], Predis
  64. will assume you're trying to configure a single connection with an
  65. associative array.
  66. The ``cluster`` Client Option
  67. '''''''''''''''''''''''''''''
  68. .. php:namespace:: Predis\Connection
  69. You can optionally confiugre your client's clustering by using the ``cluster``
  70. client option. This option can take a few different types of value. It can take
  71. the special strings ``"predis"`` or ``"redis"`` to switch between the two
  72. built-in cluster connection classes `PredisCluster` and
  73. `RedisCluster` respectively::
  74. $client = new Predis\Client(array(
  75. // ...
  76. ), array('cluster' => 'predis'));
  77. If the value is any other string, it's expected to be the fully qualified name
  78. of a class implementing `ClusterConnectionInterface`.
  79. Finally, you can also configure the option with a callable. This callable is
  80. expected to return an instance of `ClusterConnectionInterface`. The two
  81. built-in clustered connection types both accept a
  82. `Predis\\Cluster\\Distribution\\DistributionStrategyInterface` instance as
  83. their first argument, allowing you to configure that as well::
  84. $client = new Predis\Client(array(
  85. // ...
  86. ), array(
  87. 'cluster' => function () {
  88. $strategy = new Predis\Cluster\Distribution\KetamaPureRing();
  89. return new Predis\Connection\PredisCluster($strategy);
  90. }
  91. ));
  92. Connection Classes
  93. """"""""""""""""""
  94. .. php:class:: PredisCluster
  95. ``PredisCluster`` is a simple Predis-native clustered connection implementation.
  96. This form of clustered connection does *not* provide redundancy. If your application
  97. makes requests for 100 different keys, with the default distribution strategy
  98. these keys are likely to be spit across all the servers in your pool.
  99. .. php:class:: RedisCluster
  100. ``RedisCluster`` is a clustered connection implementation intended for use with
  101. Redis Cluster. Redis Cluster is not yet finalized, but it already includes some
  102. pretty cool features. Nodes in a Redis Cluster arrangement configure
  103. themselves to deal with changes in availability.
  104. Disallowed Commands
  105. ===================
  106. Some commands just don't make sense to run on a clustered connection. For
  107. example, the ``INFO`` command returns information about the server on which
  108. it's run, so running it on a cluster would be meaningless.
  109. If you try to run one of these commands, you'll get a
  110. ``Predis\\NotSupportedException``.
  111. Running Commands on Nodes
  112. =========================
  113. `PredisCluster` and :php:class:`RedisCluster` both
  114. implement `\\IteratorAggregate`, so you can easily run commands against the
  115. individual Redis servers in a cluster::
  116. $hosts = array();
  117. foreach ($client->getConnection() as $shard) {
  118. $hosts[] = $shard->info();
  119. }