predis

A flexible and feature-complete Redis client for PHP.

MIT License

Downloads
223.4M
Stars
7.5K
Committers
101

Bot releases are hidden (Show)

predis - Predis v0.6.0

Published by nrk over 10 years ago

Predis is a flexible and feature-complete PHP client library for Redis. This release provides developers an even more stable, customizable and up-to-date client than previous versions, with just a tiny bit of overhead added when compared to the 0.5.x series. As with previous releases, Predis is also available for PHP 5.2 with an officially supported backport (PHP >= 5.2.6). What follows is an overview of the new features introduced in this new release. For a more in-depth list of changes plese see the CHANGELOG.

New features and changes

Server profiles

Predis 0.6.0 is fully compatible with Redis 2.0 (which has reached the RC stages just a few days ago at the time of writing) and its command set. The default server profile is set to 2.0. Those who are using older versions of Redis should specify the correct server profile accordingly when instantiating a new client (highly recommended):

$redis = new Predis\Client('redis://127.0.0.1/', '1.2');

For compatibility reasons, the old way of specifying which server profile to use is still valid:

$profile = Predis\RedisServerProfile::get('1.2');
$redis = new Predis\Client('redis://127.0.0.1/', $profile);

Please note that default support for Redis 1.0 has been removed and it is now provided only when including Predis_Compatibility.php as follows:

require_once('lib/Predis.php');
require_once('lib/Predis_Compatibility.php');

$redis = new Predis\Client('redis://127.0.0.1/', '1.0');

In accordance with the latest recommendations, Predis now uses the so-called new protocol (every command is serialized as a multibulk request) when connecting to Redis >= 1.2. The server profile for Redis 1.0 still uses inline and bulk requests though.

Client options

Now the second argument for Predis\Client::__construct() accepts also an array of client-level options or an instance of Predis\ClientOptions.

$options = array(
    'profile'            => '2.0',
    'key_distribution'   => 'Predis\Distribution\HashRing',
    'throw_on_error'     => true,
    'iterable_multibulk' => false,
);

$redis = new Predis\Client('redis://127.0.0.1/', $options);
  • profile [default: 2.0]:
    specifies which server profile to use. Accepts a version string (e.g. 1.2, 2.0, default, dev) or an instance of a class that inherits from Predis\RedisServerProfile.
  • key_distribution [cluster only - default: Predis\Distribution\HashRing]:
    specifies which distribution strategy to use to distribute keys when connecting to a cluster of Redis servers. Accepts a full class name (as a string) or an instance of a class that implements the Predis\Distribution\IDistributionStrategy interface.
  • throw_on_error [default: true]:
    specifies if server errors throw exceptions or they are returned as instances of Predis\ResponseError. Accepts boolean values.
  • iterable_multibulk [default: false]:
    specifies if multibulk replies are returned as arrays or as iterator instances (the latter enables the client to stream replies down to application's code). Accepts boolean values.

Connection parameters

The following example shows the new connection parameters that are in addition to the ones previously supported.

$connection_parameters = array(
    'alias'                 => 'cache-a',
    'weight'                => 100,
    'connection_async'      => false,
    'connection_persistent' => false,
);

$redis = new Predis\Client($connection_parameters);
  • alias [cluster only - default: not set]:
    identifies each connection by providing a mnemonic alias. Accepts string values.
  • weight [cluster only - default: not set]:
    specifies a weight used to balance the distribution of keys asymmetrically across multiple servers. Accepts integer values.
  • connection_async [default: false]:
    specifies if connections to servers are estabilished in a non-blocking way (the client is not blocked while the underlying resource performs the actual connection). Accepts boolean values.
  • connection_persistent [default: false]:
    specifies if the underlying connection resource should be left open when a script ends its lifecycle. Accepts boolean values.

Command pipelines

Command pipelines now support method chaining.

$replies = $redis->pipeline()->set('key', 'value')->get('key')->execute();

The new method Predis\Client::pipelineSafe() initializes a command pipeline that does not throw exceptions on server, protocol or connection errors. Instead, the generated exceptions are returned as values in the replies array. This new approach is useful when pipelines are used in a clustered environment since it enables the client to continue processing commands even if one or more servers in the cluster generate an error or become unavailable.

Transactions (Redis 2.0)

Predis 0.5.x already provided Redis transaction blocks via Predis\Client::multiExec(). The current implementation now supports method chaining and the ability to discard the commands issued in a transaction (see the DISCARD command in the command reference of Redis).

Publish / Subscribe (Redis 2.0)

Predis 0.6.0 supports PUBSUB contexts via PHP iterators with the new method Predis\Client::pubSubContext(). See the following example for more details.

Miscellaneous

It is now possible to get a new client instance for a single connection of a cluster by passing its alias to the method Predis\Client::getClientFor(). The new client inherits the same options of the originator client.

$cluster = new Predis\Client(array(
    'redis://127.0.0.1:6379?alias=first', 
    'redis://127.0.0.1:6379?alias=second'
));

$first = $cluster->getClientFor('first');
$first->info();

The Predis\RedisServerProfile class now allows developers to register their own server profiles or override the default ones provided by Predis.

class MyCustomProfile extends Predis\RedisServerProfile {
    public function getVersion() { return '2.2'; }
    public function getSupportedCommands() {
        // Implementation here...
    }
}

Predis\RedisServerProfile::registerProfile('MyCustomProfile', 'custom');
$redis = new Predis\Client('redis://127.0.0.1/', 'custom');

Notes

Roadmap for future releases

Since this new version of Predis already offers a multitude of new features and enhancements, the next releases in the 0.6.x series should contain only bug fixes, performance improvements and minor changes or additions. All the big new features will be reserved to the 0.7.x series, whose development cycle will be heavily influenced by the development cycle of Redis. Depending on the work needed to support future releases of Redis, 0.7.x might introduce some breaking changes. Long aliases for commands (e.g. $redis->setMultiple(), $redis->getMultiple() and such) are discouraged and should be considered obsolete as they could be removed in future major releases of Predis, depending on the feedback from the community.

Credits

I would like to especially thank Lorenzo Castelli for providing a whole lot of suggestions and reference code that hugely contributed to the final implementation of many new features shipped in this new version of Predis (see partial failures in pipelines, asynchronous connects, persistent connections, improvements in the current hashring implementation and a few minor fixes).

Thanks also to those who have reported bugs on the issue tracker and, finally, to all those who have sent me emails with words of appreciation for the work that has been made in Predis: these words are shared with anyone who contributed to make this new release possible.

Downloads

  • PHP 5.3 (mainline):
    TGZ or
    ZIP
  • PHP 5.2 (backport):
    TGZ or
    ZIP

Useful links

predis - Predis v0.8.6

Published by nrk over 10 years ago

This is a maintenance release for the 0.8 series with some improvements to existing features. What follows is an overview of the changes and bug fixes introduced in this new release, details are also available in the CHANGELOG.

New features

Redis commands

Improvements

Redis Cluster

When coupled with Redis >= 3.0.0b1 you can now use key hash tags (e.g. key:{hash:tag}) to force certain keys to be stored on the same node, just like it happens with the good old client-side sharding. See commit ba2ffb6.

Bug fixes

  • Minor tweaks to make this version of Predis compatible with HHVM >= 2.4.0.
  • Using Redis sentinel does not break the parsing of responses to INFO anymore. See issue #154 and commit f4a950b.
  • INCRBYFLOAT is now handled as expected in cluster and replication configurations. See issue #159 and commit c2ae1c6.
  • Fixed the parsing procedure for the output of CLUSTER NODES when fetching the slots map from a node and redis-cluster has slaves in its configuration. See issue #165 and commit e148dc8. NOTE: the new CLUSTER SLOTS command is the proper way to fetch the slots map now, but we'll stick with the old method for this patch release of v0.8 while v1.0.0 will rely on it by default.
  • Prevent a stack overflow when iterating over large Redis collections using our abstraction for cursor-based iterators. See issue #182 and commit b77da84.
  • Properly discards transactions when the server immediately returns an error response (e.g. -OOM or -ERR on invalid arguments for a command) instead of a +QUEUED response. See issue #187 and commit 74817b5.

Future development

Believe me, Predis v1.0.0 is on its way and will be released really soon... this time I mean it for real ;-) That said, v0.8 will still be maintaned for a while with a few more patch releases mainly targeted at improving redis-cluster support as much as possible and fixing issues.

Additional notes

Downloads

predis - Predis v0.8.5

Published by nrk almost 11 years ago

This is a maintenance release for the 0.8 series with some improvements to existing features. What follows is an overview of the changes and bug fixes introduced in this new release, details are also available in the CHANGELOG.

New features

Redis commands

  • Added a new server profile for Redis 2.8. The default value for the profile client option still targets Redis 2.6 and the dev profile now targets Redis 3.0.
  • New commands added to the 2.8 profile: SCAN, SSCAN, ZSCAN and HSCAN to the server profile for Redis 2.8.

Collection iterators

The new cursor-based iterator commands available starting from Redis 2.8 make it possible to iterate Redis collections without blocking the server but developers still need to implement some logic in their applications to fully leverage them. To ease the usage of such commands we added some abstractions in the Predis\Collection namespace in the form of plain old PHP iterators, making it possible to fully iterate Redis collections in your PHP code with something as simple as foreach.

Redis do not have a cursor-based iterator for lists but we added an abstraction with Predis\Collection\Iterator\ListKey based on LRANGE that tries to mimic a similar behavior while not being exactly the same thing.

You can find some examples here.

Raw commands

It is possible to execute raw commands using Predis\Command\RawCommand and a variable list of command arguments. The main difference with the usual approach is that input arguments are not filtered and complex responses are not parsed, which also means arguments must follow the exact same signature of the command as defined by Redis. Obviously there is no need to create and register a new class to use them:

$command = Predis\Command\RawCommand::create('SET', 'foo', 'bar');
$response = $client->executeCommand($command);

Executing commands in this way can be useful to implement internal features, when the user-specified server profile is not accessible or when you need to make sure that your code will not be affected by different argument filtering or response parsing implementations.

This feature will be further improved in the next major release.

Improvements

Redis Cluster

Some aspects of our abstraction for Redis Cluster have been dramatically improved or fixed while others (such as silent handling of connection failures) will be addressed in later patch releases.

  • The ASKING command is now correctly sent automatically upon -ASK redirections.
  • Updated slots maps can be fetched from nodes thanks to the CLUSTER NODES command. By default this is a manual operation but it can be enabled to get automatically done upon -MOVED redirections.
  • It is possible to specify a common set of connection parameters that are applied to connections created on the fly upon redirections to nodes that are not part of the initial pool.

Query string parsing for connection parameters

URI parsing now relies on parse_str for the query string part which has a slightly smaller overhead when the number of fields in the querystring grows. Furthermore:

  • Parsing does not break when value of a field contains one or more =.
  • Repeated fieldnames using [] produce an array of values.
  • Empty or incomplete key=value pairs result in an empty string for key.

Deprecations

A couple of methods of Predis\Client are now marked as deprecated and will be removed in the next major release:

  • Predis\Client::multiExec(): superseded by Predis\Client::transaction().
  • Predis\Client::pubSub(): superseded by Predis\Client::pubSubLoop(). This change was needed due to the recently introduced PUBSUB command in Redis 2.8.

Future development

Aside from a few more tweaks aimed at improving support for the upcoming Redis Cluster there is not much to add or change in the current v0.8 branch. The library is very stable judging by the history of issues opened during the last months so you can expect a couple of patch releases for v0.8 until Redis 3.0 but nothing more. The good news is that the release of the next major version is imminent and Predis will finally hit v1.0! The transition from v0.8 to v1.0 will bring a lot of breaking changes required to polish the API of the library and its internals, but the actual impact on your code (that is, if you plan to upgrade) may vary depending on your kind of usage: in simple scenarios where Predis is used as a mere client without relying on its extensibility, it is pretty much possible that nothing will change for you.

You can already start playing with it by requiring "predis/predis": "dev-master" in composer.json. Predis v1.0.0 is planned to be released on the same day of the first beta of Redis Cluster, 10th February 2014.

Additional notes

Downloads

predis - Predis v0.8.4

Published by nrk about 11 years ago

This is a maintenance release for the 0.8 series shipping mostly bug fixes. What follows is an overview of the changes and bug fixes introduced in this new release, details are also available in the CHANGELOG.

Bug fixes and changes

Redis commands

Scripted commands and key prefixing

Predis failed to handle falling back from EVALSHA to EVAL using scripted commands with no arguments defined for KEYS[] when the client was configured to use key prefixing. (see related pull request)

Failing host reported in exception messages

When a connection error occurs, such as when Predis is not able to connect to a server, the exception message now includes the incriminated Redis server: Connection refused [tcp://127.0.0.1:3322]. This can be handy to debug or log errors especially when using multiple nodes in a replication or cluster configuration. (see related pull request)

DispatcherLoop

The pub/sub-based DispatcherLoop class has been fixed to properly work when using a prefixed client instance. (see related pull request)

PhpiredisConnection

This connection backend now uses gethostbynamel to handle hostnames with multiple IP addresses associated and randomly choses one of them. This is mostly useful to distribute the load on multiple Redis instances configured as read-only slaves sitting behind one single hostname. (see related pull request)

Additional notes

Downloads