How to config redis replication in laravel?
Asked Answered
F

1

0

I use redis replication(one master with port 6379, two slave with port 6380, 6381), I've not found anything in the laravel doc for config redis replication.

I use below config(from gpt's answer), but the replication config not works. When I use Redis::get('key'), every redis connection is on the master instance.

Is it possible to config redis replication like the mysql database read write configuration. Laravele will select the master instance for write, and load balance read among all the slaves? What's more laravel can stick to the same instance like mysql database, The sticky option is an optional value that can be used to allow the immediate reading of records that have been written to the database during the current request cycle.

// config/database.php
    'redis' => [
        'client' => 'predis',
        'options' => [
            'cluster' => 'redis',
            'replication' => true,
        ],
        'default' => [
            'host' => '127.0.0.1',
            'password' => env('REDIS_PASSWORD', null),
            'port' => 6379,
            'database' => 0,
        ],
        'replicas' => [
            [
                'host' => '127.0.0.1',
                'password' => env('REDIS_PASSWORD', null),
                'port' => 6380,
                'database' => 0,
            ],
            [
                'host' => '127.0.0.1',
                'password' => env('REDIS_PASSWORD', null),
                'port' => 6381,
                'database' => 0,
            ],
        ],
    ]

master redis connection log

[10280] 28 May 15:19:11.426 - Accepted 127.0.0.1:55759
[10280] 28 May 15:19:11.472 - Client closed connection
[10280] 28 May 15:19:13.721 - Accepted 127.0.0.1:55768
[10280] 28 May 15:19:13.754 - Client closed connection

Franfranc answered 28/5 at 7:32 Comment(8)
Did you check redis connection? laravel.com/docs/11.x/redis#using-multiple-redis-connectionsBecka
Have not personally tried this but it should be the same logic when using Laravel's log channel Log::channel('channel-name')->info then with redis: Redis::connection('replica1'). Though instead of replica being an array of connections, separate them by replica 1 and 2Becka
In your case maybe Redis::connection('replica1')->get('key'), Redis::connection('replica2')->get('key') for your read while Redis::get('key') for write/masterBecka
Yes, when specific the connection it works. I mean is is possible to make laravel auto select the connection. Just like Redis::set(), Redis::get()Franfranc
Is it possible to config like the database, laravel.com/docs/11.x/database#read-and-write-connections. Laravel will auto select the right connection, without to select in my code.Franfranc
Does this answer your question? Laravel separate read/write operations for Redis?Becka
Yeah it's what I'm asking. But the answer it not. The answer need the select the connection in the code. For now it may not have a easy way to separate redis write read just like the database way.Franfranc
I make it. @Mr. KennethFranfranc
F
0

Without any progress by searching or read the laravel doc.

Then I read the source code and debug the redis connection initialization process. I found below code works well for separate read and write operation, read load balancing, and write read sticky.

    'redis' => [
        'client' => 'predis',
        'options' => [
            'cluster' => 'redis',
            'replication' => true,
        ],
        'default' => [
            'tcp://127.0.0.1:6379?alias=master',// this is the master role
            'tcp://127.0.0.1:6379',// I also make the master instance to process the read action, you also can remove it to make the master only respond to the write action.
            'tcp://127.0.0.1:6380'
        ]
    ],

Then in your code you can use it like below:

// There is a little flaw, without connection() it cannot auto complete.
// But this has no relation to the redis config. Maybe it need to resolve to laravel-ide-helper.
Redis::get('test');  // this will select any one of the slave instance
Redis::connection()->set('test',2);  // this will use the master
Redis::connection()->get('test');  // for sticky this will also use the master.
Franfranc answered 29/5 at 10:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.