Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Rankus's avatar

Redis & clusters : how to configure cluster for cache ?

Hello, I'm trying to setup a shared cache with Redis on a multi nodes environment. My goal is to create a pool of Redis servers to mutualize cache between the nodes.

To achieve that, I'm trying to setup the "cluster" redis database config on Laravel 8.

Documentation is very light on this topic and I can't find any relevant examples on the Web. So i'm asking Laracast.

Here is my config :

'redis' => [

        'client' => env('REDIS_CLIENT', 'phpredis'),

        'options' => [
            'cluster' => env('REDIS_CLUSTER', 'redis'),
            'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'),
        ],

        'default' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' => env('REDIS_DB', '0'),
        ],

        'cache' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' => env('REDIS_CACHE_DB', '1'),
        ],

        'clusters' => [
            'redis' => [
                [
                    'host' => 'xxx.xxx.xxx.1',
                    'password' => env('REDIS_PASSWORD', null),
                    'port' => env('REDIS_PORT', 6379),
                    'database' => 0,
                ],
                [
                    'host' => 'xxx.xxx.xxx.2',
                    'password' => env('REDIS_PASSWORD', null),
                    'port' => env('REDIS_PORT', 6379),
                    'database' => 0,
                ],
            ],
        ],
    ],

I declared a "redis" cluster containing my 2 nodes. But I can't have the cache system utilize the cluster.

0 likes
6 replies
Rankus's avatar

After many tries, I think I got a working config by moving the cache key under clusters :

'redis' => [

        'client' => env('REDIS_CLIENT', 'phpredis'),

        'options' => [
            'cluster' => env('REDIS_CLUSTER', 'redis'),
            'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'),
        ],

        'default' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' => env('REDIS_DB', '0'),
        ],

//        'cache' => [
//            'url' => env('REDIS_URL'),
//            'host' => env('REDIS_HOST', '127.0.0.1'),
//            'password' => env('REDIS_PASSWORD', null),
//            'port' => env('REDIS_PORT', '6379'),
//            'database' => env('REDIS_CACHE_DB', '1'),
//        ],

        'clusters' => [
            'cache' => [
                [
                    'host' => 'hubavocat-redis1',
                    'password' => env('REDIS_PASSWORD', null),
                    'port' => 6379,
                    'database' => 1,
                ],
                [
                    'host' => 'hubavocat-redis2',
                    'password' => env('REDIS_PASSWORD', null),
                    'port' => 6380,
                    'database' => 1,
                ],
            ],
        ],

    ],

However, I cannot write cache as I get the error :

>>> Cache::put('test4', 'test');
RedisClusterException with message 'Couldn't map cluster keyspace using any provided seed'

Something I do not understand : do my Redis needs to be setup and configured in cluster mode on server side ? Or can PHPRedis do all the job from client side ?

1 like
Rankus's avatar
Rankus
OP
Best Answer
Level 2

Ok, I finally switched to Predis client which has a simple and practical "replication mode" that allows me to use a decentralized but replicated Redis service.

Here is the database.php config :

'redis' => [
    'client' => env('REDIS_CLIENT', 'phpredis'),

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
        'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'),
        'replication' => true,
    ],

    'cache' => array_map(function ($s) {
        $parts = explode(":", $s);
        return [
            'host' => $parts[0],
            'password' => $parts[1],
            'port' => $parts[2],
            'database' => $parts[3],
        ] + (isset($parts[4]) && $parts[4] === 'master' ? [ 'alias' => 'master' ] : []);
    }, explode(",", env('REDIS_HOSTS', 'redis::6379:1:master')))


    'default' => [
        ...
    ],
],

My .env file :

CACHE_DRIVER=redis
REDIS_CLIENT=predis
REDIS_PASSWORD=my_strong_password
REDIS_HOSTS=172.10.0.1:${REDIS_PASSWORD}:6379:1:master,172.10.0.2:${REDIS_PASSWORD}:6379:1

Passing an array of connections to Predis client automatically switches it to "cluster mode". With replication => true, it operates in replication mode, sending Redis write commands to master and Redis read commands to one of the slaves.

Of course, your Redis service needs to be setup in replication mode. Predis client won't do it for you from client side. Have a look at Bitnami Redis Docker image to setup the Docker stack : https://hub.docker.com/r/bitnami/redis/

2 likes
Supremo_jm07's avatar

Do you solve it using phpredis?

for REDIS_HOSTS=172.10.0.1:${REDIS_PASSWORD}:6379:1:master,172.10.0.2:${REDIS_PASSWORD}:6379:1 is the cluster mode on in the AWS on?

Rankus's avatar

No, I keep on using predis.

Yes, my custom (not AWS) Redis installation is clustered (master/slave).

mepsd's avatar

@Rankus i am facing issue here redis is triggering 2 emails can we do anything to stop that tried shouldbe unique and ShouldBeUniqueUntilProcessing nothing worked

Rankus's avatar

Hi @mepsd , what is triggering "2 emails" ? I believe that is not Redis. Do you have 2 workers or 2 servers ?

ShouldBeUnique contract is made to avoid Laravel pushing several jobs of the same type in the queue.

The contract ShouldBeUnique requires you to define the job ID. Then if Laravel knows a job with this ID is already in the queue, it won't push another job with the same ID. Those "unique IDs" are stored in the cache.

Redis comes in this game when your app runs on several nodes that need to share the cache to know the "unique IDs".

Hope it will help

Please or to participate in this conversation.