Enterprise Drivers

Valkey Cache Driver

A Valkey caching driver for Kipchak with support for standalone, sentinel, cluster, and primary-replica topologies.

Introduction

Note: This driver is only available with Kipchak Enterprise.

The Valkey Cache Driver provides a Symfony Cache-backed client configured for Valkey deployments. It supports multiple pools and all major topologies.

Key features include:

  • Multiple Pools: Configure separate cache pools for different use cases.
  • Topology Support: Standalone, sentinel, cluster, and primary-replica modes.
  • Symfony Cache Integration: Use the adapter like any Symfony Cache client.

Installation

To install this driver, you need to access the Enterprise Composer repository at https://php.pkgs.1x.ax.

If you have an enterprise licence, please contact your account representative for access.

composer require kipchak/driver-valkey

Initialise the Driver

Add the following line to your drivers/drivers.php file:

\Kipchak\Driver\Valkey\Valkey::initialise($container);

Configuration

Create a config file named kipchak.valkey.php in your project's config directory.

Connection Settings

Define pools in the pools array. Each key (e.g., cache, sessions) is a pool name.

Common pool settings:

  • mode: standalone, sentinel, cluster, or primary-replica.
  • host / port: Single node connection.
  • hosts: List of nodes for sentinel/cluster/replica setups.
  • dsn: Optional full DSN (e.g. valkey://host:6379 or valkey://host?host[host2:6379]=).
  • database: Database index.
  • password: Password for AUTH.
  • namespace: Cache namespace.
  • default_ttl: Default cache TTL in seconds.

options supports the full Symfony Cache Redis options:

  • class, persistent, persistent_id
  • timeout, read_timeout, retry_interval, tcp_keepalive
  • lazy, cluster, cluster_command_timeout, cluster_relay_context
  • sentinel, dbindex, failover, ssl

Default options values:

  • class: null
  • persistent: false
  • persistent_id: null
  • timeout: 30
  • read_timeout: 0
  • retry_interval: 0
  • tcp_keepalive: 0
  • lazy: null
  • cluster: false
  • cluster_command_timeout: 0
  • cluster_relay_context: []
  • sentinel: null
  • dbindex: 0
  • failover: none
  • ssl: null

Topology-Specific Settings

Standalone

Use a single host/port pair, or a DSN with one host.

Required:

  • mode: standalone
  • host and port (or dsn)

Sentinel

Sentinel resolves the active primary from the listed sentinels.

Required:

  • mode: sentinel
  • hosts: sentinel nodes
  • sentinel_service: master/service name

Common options:

  • sentinel: set automatically from sentinel_service
  • timeout, read_timeout, retry_interval

Cluster

Provide seed nodes for cluster discovery.

Required:

  • mode: cluster
  • hosts: cluster nodes

Common options:

  • cluster: true
  • failover: slaves or distribute
  • cluster_command_timeout: for Relay cluster

Primary-Replica

Provide a primary and one or more replicas.

Required:

  • mode: primary-replica
  • hosts: primary first, then replicas

Common options:

  • failover: slaves or distribute
  • class: \Predis\Client::class for replica-aware reads

Example Configuration

<?php

use function Kipchak\Core\env;

return [
    'enabled' => true,
    'pools' => [
        'cache' => [
            'mode' => 'standalone',
            'host' => env('VALKEY_HOST', 'valkey'),
            'port' => env('VALKEY_PORT', 6379),
            'database' => env('VALKEY_DB', 0),
            'password' => env('VALKEY_PASSWORD'),
            'namespace' => 'cache',
            'default_ttl' => 3600,
            'options' => [
                'timeout' => 2.5,
                'read_timeout' => 0,
                'persistent' => false,
            ],
        ],
        'sentinel_cache' => [
            'mode' => 'sentinel',
            'sentinel_service' => env('VALKEY_SENTINEL_SERVICE', 'mymaster'),
            'hosts' => [
                ['host' => env('VALKEY_SENTINEL_1_HOST', 'sentinel-1'), 'port' => env('VALKEY_SENTINEL_1_PORT', 26379)],
                ['host' => env('VALKEY_SENTINEL_2_HOST', 'sentinel-2'), 'port' => env('VALKEY_SENTINEL_2_PORT', 26379)],
            ],
            'database' => env('VALKEY_DB', 0),
            'password' => env('VALKEY_PASSWORD'),
        ],
        'cluster_cache' => [
            'mode' => 'cluster',
            'hosts' => [
                ['host' => env('VALKEY_CLUSTER_1_HOST', 'valkey-1'), 'port' => env('VALKEY_CLUSTER_1_PORT', 6379)],
                ['host' => env('VALKEY_CLUSTER_2_HOST', 'valkey-2'), 'port' => env('VALKEY_CLUSTER_2_PORT', 6379)],
                ['host' => env('VALKEY_CLUSTER_3_HOST', 'valkey-3'), 'port' => env('VALKEY_CLUSTER_3_PORT', 6379)],
            ],
            'options' => [
                'cluster' => true,
                'failover' => 'slaves',
            ],
        ],
        'replica_cache' => [
            'mode' => 'primary-replica',
            'hosts' => [
                ['host' => env('VALKEY_PRIMARY_HOST', 'valkey-primary'), 'port' => env('VALKEY_PRIMARY_PORT', 6379)],
                ['host' => env('VALKEY_REPLICA_HOST', 'valkey-replica'), 'port' => env('VALKEY_REPLICA_PORT', 6379)],
            ],
            'options' => [
                'failover' => 'slaves',
            ],
        ],
    ]
];

Usage

Code Example

<?php

use Kipchak\Driver\Valkey\Valkey;

$cache = Valkey::get('cache');
$item = $cache->getItem('example.key');
$item->set('value')->expiresAfter(60);
$cache->save($item);

Raw Connection

PSR-6 cannot express atomic operations such as SET NX, INCR or Lua scripts. For those, connection() returns the pool's underlying client (\Redis, \RedisCluster, \Predis\ClientInterface or \Relay\Relay, depending on the mode). It is the same client the pool's cache adapter uses.

$valkey = \Kipchak\Driver\Valkey\Valkey::connection('cache');
$firstSeen = $valkey->set('myapi:nonce:abc', '1', ['nx', 'ex' => 300]);

Keys written through the raw connection are not namespaced by the adapter, so prefix your own keys.

Recovering After an Outage

In FrankenPHP worker mode a client lives as long as the worker. A phpredis client that fails a command while Valkey is unreachable stays broken ("Redis server ... went away") after Valkey comes back. When a command fails, call reconnect() to replace the pool's client and adapter, then retry:

try {
    $valkey->set($key, $value, ['nx', 'ex' => 60]);
} catch (\RedisException) {
    $valkey = \Kipchak\Driver\Valkey\Valkey::reconnect('cache');
    $valkey->set($key, $value, ['nx', 'ex' => 60]);
}

Later get() and connection() calls return the new objects, so fetch them from the driver per request rather than holding on to them. A connection that sat idle during the outage recovers by itself.

Notes

  • Primary-replica mode uses Predis for replica-aware reads; set options['class'] to \Predis\Client::class if you install predis/predis.
  • Use dsn when you need full control over the connection string format.

Source

The source code for this driver is hosted internally.

Previous
OAuth 2 Token