Skip to content

Using Relay

Till Krüss edited this page May 9, 2023 · 24 revisions

Predis v2.2 comes with a native integration for the Relay extension for PHP, which brings major performance gains by:

  1. caching a partial replica of the Redis dataset in PHP's shared runtime memory, which reduces reads by >90%
  2. allowing fast data compression to reduce network and Redis memory usage by ~75%

Using Relay

Using Relay is as simple as installing the extension and telling Predis to use it:

$client = new Predis\Client('tcp://127.0.0.1', [
    'connections' => 'relay',
]);

Compatibility

Relay is a drop-in replacement for PhpRedis with an identical API. When using Relay with Predis there are some caveats and in no way is 1:1 API compatibility guaranteed.

  • Relay will ignore the exceptions option and always throw an exception when an error occurs
  • Relay will ignore the persistent option, because it treats all connections as persistent
  • Predis' Relay integration has not been tested with aggregate connections such as Sentinel or Cluster
  • Pub/Sub consumers use callbacks and are not iterables
  • Some commands are currently unsupported, notably: COMMAND, MONITOR and QUIT

For a detailed list of unsupported operations, search for the relay-incompatible group in the test suite.

Please open an issue if you discover any incompatibilities.

Events

Relay supports powerful event listeners that can be useful for long-running processes or highly concurrent applications. Event listeners can be used to avoid race conditions and stale caches.

$client = new Predis\Client('tcp://127.0.0.1', [
    'connections' => 'relay',
]);

$client->getConnection()->listen(function (\Relay\Event $event) {
    match ($event->type) {
        $event::Flushed => flushLocalCache(),
        $event::Invalidated => deleteKeyFromCache($event->key),
    };
});

See the relay_events.php example.

Pub/Sub

Using Pub/Sub consumers with Relay-powered connections works slightly differently. Instead of a loop, a callback must be used:

$client = new Predis\Client('tcp://127.0.0.1?read_write_timeout=0', [
    'connections' => 'relay',
]);

$pubsub = $client->pubSubLoop();

$pubsub->subscribe('control_channel', function ($message, \Relay\Relay $client) {
    // 
});

See the relay_pubsub_consumer.php example.

Serialization + Data compression

Relay supports various serializers (php, json, msgpack, igbinary), however only php and igbinary will store PHP types such as serialized class instances. The serializer connection parameter works in combination with compression.

Relay additionally supports various compression algorithms (lzf, lz4, zstd) to reduce the amount of bytes sent over the network. The compression connection parameter works in combination with serializer.

Serializers and compression algorithms can be used together.

$client = new Predis\Client([
    'host' => '127.0.0.1',
    'serializer' => 'php',
    'compression' => 'lz4',
], [
    'connections' => 'relay',
]);

The initial Predis implementation requires the data passed to Predis to be mutated manually, in Predis v3.x this will be automated.

$value = (object) ['hello' => 'world'];

// set the value
$client->set('sup?', $client->pack($value));

// get the value
$client->unpack($client->get('sup?'));