In the past I was able to use a non-clustered redis just fine in my config like so:
'redis' => [
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => 6379,
'database' => 0,
'cluster' => true,
]
],
However due to the load on our redis servers, I have to cluster my redis, This config works fine when the only redis connection I have is clustered (figured it out after a lot of work):
'redis' => [
'client' => 'predis',
'cluster' => true,
'options' => [
'cluster' => 'redis',
'parameters' => [
'host' => env('REDIS_SHARD_1_HOST', '127.0.01'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_DEFAULT_PORT', 6379),
'database' => 0,
],
],
'clusters' => [
'default' => [
'host' => env('REDIS_SHARD_1_HOST', '127.0.01'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_SHARD_1_PORT', 6379),
'database' => 0,
],
'shard2' => [
'host' => env('REDIS_SHARD_2_HOST', '127.0.01'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_SHARD_2_PORT', 6379),
'database' => 0,
],
'shard3' => [
'host' => env('REDIS_SHARD_3_HOST', '127.0.01'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_SHARD_3_PORT', 6379),
'database' => 0,
],
'options' => [
'cluster' => 'redis'
],
]
]
any my env file looks like this (For my localhost, anyway):
QUEUE_DRIVER=redis // cluster compatible
BROADCAST_DRIVER=redis // cluster compatible
CACHE_CONNECTION=redis // cluster incompatible
REDIS_CLUSTER=true
REDIS_HOST=localhost
REDIS_DEFAULT_PORT=7000
REDIS_SHARD_1_HOST=localhost
REDIS_SHARD_2_HOST=localhost
REDIS_SHARD_3_HOST=localhost
REDIS_SHARD_1_PORT=7000
REDIS_SHARD_2_PORT=7001
REDIS_SHARD_3_PORT=7002
The fact is that currently, we use the non-clustered redis for the following:
That's why we need to have both redis connections simultaneously, so that we can use the clustered connection for caching/queues, and non-clustered connection for websockets.
But this isn't working:
'redis' => [
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => 6379,
'database' => 0,
'cluster' => true,
],
'clustered' => [
'client' => 'predis',
'cluster' => true,
'options' => [
'cluster' => 'redis',
'parameters' => [
'host' => env('REDIS_SHARD_1_HOST', '127.0.01'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_DEFAULT_PORT', 6379),
'database' => 0,
],
],
'clusters' => [
'default' => [
'host' => env('REDIS_SHARD_1_HOST', '127.0.01'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_SHARD_1_PORT', 6379),
'database' => 0,
],
'shard2' => [
'host' => env('REDIS_SHARD_2_HOST', '127.0.01'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_SHARD_2_PORT', 6379),
'database' => 0,
],
'shard3' => [
'host' => env('REDIS_SHARD_3_HOST', '127.0.01'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_SHARD_3_PORT', 6379),
'database' => 0,
],
'options' => [
'cluster' => 'redis'
],
]
further, some users state that such a task is simply impossible for redis. Is that true?
I tried this
in Cache.php
'redis' => [
'driver' => 'redis',
'connection' => 'clustered',
],
note: in the above connection i simply couldn't just copy/paste the cluster options, since it would crash if i didn't put a driver option
In database.php I was inspired by this answer and simply put different connections under the redis key: (ie `database.redis.connection-1, database.redis.connection-2 etc)
'redis' => [
'clustered' => [
// clustered settings copied from above
],
],
'default' => [
// non clustered settings
],
]
To test, I ran the following tinker
>>> use Illuminate\Support\Facades\Cache;
>>> Cache::put('foo','bar',1);
Predis/Response/ServerException with message 'MOVED 7837 127.0.0.1:7001'
The move error is a known one, it's simply saying that i'm dealing with a non-clustered redis connection.
thoughts?
If you are using a Redis Cluster, there are a few specific configurations you have to make sure you set in your config/database.php in the redis section. This option needs to be enabled so Laravel treats your Redis connection as a cluster.
A Redis (cluster mode disabled) cluster always has a single shard (API/CLI: node group) with up to 5 read replica nodes. A Redis (cluster mode enabled) cluster has up to 500 shards with 1 to 5 read replica nodes in each.
Use redis-cli --cluster check at the end to make sure your cluster is ok. Restart your clients modified to use a Redis Cluster aware client library. There is an alternative way to import data from external instances to a Redis Cluster, which is to use the redis-cli --cluster import command.
In Laravel, this can be in a few different places depending for what you are using Redis. You only need to use this approach where Redis will perform “multiple key operations”. Since, you cannot tell without digging into the internals, here’s my suggestion: Wrap your queue names. e.g. 'queue' => ' {default}' in your config/queue.php file.
I was able to fix this problem with this PR.
This is what my config looks like now:
'redis' => [
'clustered' => [
'client' => 'predis',
'cluster' => true,
'options' => [ 'cluster' => 'redis' ],
'clusters' => [
[
'host' => env('REDIS_SHARD_1_HOST', '127.0.01'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_SHARD_1_PORT', 6379),
'database' => 0,
],
[
'host' => env('REDIS_SHARD_2_HOST', '127.0.01'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_SHARD_2_PORT', 6379),
'database' => 0,
],
[
'host' => env('REDIS_SHARD_3_HOST', '127.0.01'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_SHARD_3_PORT', 6379),
'database' => 0,
],
],
],
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => 6379,
'database' => 0,
'cluster' => false,
],
]
Will be sending PR to Laravel itself shortly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With