Separate Redis Store in Laravel

Credit to https://www.techalyst.com/

Redis is an open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets, and sorted sets.

In this article, I will show how to separate the Redis configuration for cache, session and queue. Why separate? For me, its :-

Laravel have out-of-the-box Redis configuration which give you freedom to assign your connection and storage for your application.

Here is the default connection configuration in database.php

'redis' => [

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

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

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

The problem is the default session setting all goes to default redis connection which is database 0. The moment when you run FLUSHDB in the redis for DB 0, all the data will be gone.

Great about Redis is there is a way to partition data logically. The default database is 0 but you can change that to any number from 0–15 or more depend on your setting. Each database provides a distinct keyspace, independent from the others.

Lets reconfiguring to separate the Redis connection

For example, I want to separate session, queue, cache and horizon.

'redis' => [

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

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

'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
'session' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 2),
],
'queue' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 3),
],
'horizon' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 4),
],

'app' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 10),
]
],

So, every config is the same except the database number. You can give any number from 0 to hundreds. Your choice. If you want each of it to have different Redis server, all you need is to change the host directly to the file or using .env file

Reconfigure Cache Config

If you look into the config/cache.php , there is default stores array defined for the use of Laravel cache services. By default, Laravel set the cache driver to file which its bad for multiple server because file only stored in current specific project directory and unable to be shared with other server.

'default' => env('CACHE_DRIVER', 'file'),

Change the CACHE_DRIVER in .env to redis. If you see at the stores array, Laravel already point the Redis connection to cache database (DB 1). So, we don’t need to change the connection.

'redis' => [
'driver' => 'redis',
'connection' => 'cache',
],

For me, I want to use different store for different cache for my logic. So i add another store named redis-app and the connection point to app

'redis' => [
'driver' => 'redis',
'connection' => 'cache',
],
'redis-app' => [
'driver' => 'redis',
'connection' => 'app',
],

So, i simply can access using Cache::store(‘redis-app’) or just create an helper method for easier access

Reconfigure Session Config

Look at the session.php,

'driver' => env('SESSION_DRIVER', 'file'),

Change the SESSION_DRIVER in .env to redis. By default, Laravel set the session driver to file which its bad for multiple server under load balancer lead to session loss or intermittent.

Ok now, there is 2 way either change the connection or change the store value

'store' => env('SESSION_STORE', null),
'connection' => env('SESSION_CONNECTION', null),

More easier just change the connection value to session redis connection (DB 2)

'connection' => env('SESSION_CONNECTION', 'session'),

Now when you clear the cache php artisan cache:clear your users will no longer lose their session data and be forcing them to logout.

Reconfigure Queue Config

Look at the config/queue.php

'default' => env('QUEUE_CONNECTION', 'sync'),

Change the QUEUE_CONNECTION in .env to redis and it will automatically refer to redis setting in connections arrays belows

'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
'after_commit' => false,
],

But, the connection is point to default redis connection. Change the default value to the queue .

Now you can run your queue without loosing data if you accidentally flush default redis (DB 0)

Reconfigure Horizon Config

If you are using Laravel Horizon,

'use' => 'default',

Just simply change the “use” to “horizon” connection that we assign earlier

Ok now, you can verify it by accessing the redis server

> Select 0
> Keys *
...
...
> Select 1
> Keys *
...
...

Its will show the list of your key value have been stored!

Thats it. Thank for your time guys. Just my 2 cent. Just ping me if there is a way for best to do it. See ya~~

Software Engineer at Teratotech.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store