From the official Redis website, Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker.It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.

In simpler terms, Redis is a faster, MySQL alternative that can be used as a database, cache or communication bridge between applications of the same language/framework or of different language/framework. But in this article we will mainly focus on how Redis can be used to enhance your Laravel application.


Installation

Let’s create a Laravel application then install Redis composer package.

composer create-project --prefer-dist laravel/laravel learn-redis
cd learn-redis
composer require predis/predis

Install the redis-server if you don’t have installed yet on your PC. For linux users run the command:

apt install redis-server

In your config/database.php file modify the ‘client’ value inside ‘redis’ to ‘predis’ to use the installed ‘predis/predis’ package as the default:

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

Inside the ‘options’ modify the ‘prefix’ to ‘learn_redis_database_’ this will make it easy to push messages later from other applications, by default laravel will append the prefix to keys, channel names etc.

'prefix' => env('REDIS_PREFIX', 'learn_redis_database_')

From there you will be able to easily use Redis facade inside the Laravel application.


1. As database

Take an example you build a point of sale application within which you want to implement a dashboard that shows a number of sales per day. You would use a query like:

select SUM(order_products.price), products.name
from order_products
join products on order_products.product_id = products.id
where DATE(order_products.created_at) = CURDATE()
where order_products.status = "done"

But the query is very heavy, and for example in a restaurant that does thousands of sales everyday, it is unwise to run this query for a dashboard that queries for stats every passing moment. Instead we can use Redis for exactly this purpose.

In every time an order is updated, we define a listener for whenever order is created inside Order model which will store the count in Redis database using the booted method of Eloquent Model.

And then in your controller once you want to fetch the sales count you just write:

That gives you the all the sales for each product on a certain day, and at the same time you don’t have to run that long query every time you want to see the stats, they can be fetched very fast from the Redis server.

2. As Cache

In the config/cache.php file modify the ‘default’ key from file to ‘redis’, you can also do this in the .env file by modifying the key ‘CACHE_DRIVER’. This sets the default cache method for the Laravel application as Redis.

Now take an example, in your application you display the file-system stats, you want to display the number of files inside a directory, and the directory has thousands of files, that rarely change, maybe once a day. Normally you can use Laravel storage facade if the directory is inside the storage.

$count = array_count_values(Storage::files('some-directory'));

Now instead of running the command every time and checking the file system to retrieve the number of files you can simply use the Cache facade that will remember the count for a certain amount of specified time by storing the value inside the redis-server and retrieve the value again from redis-server the next time you want the count if the cache has not expired. In this example cache expires in an hour (3600 seconds) and the closure will be called once an hour has passed.

$count = Cache::remember('file_count',3600,function(){
   return array_count_values(Storage::files('some-directory');
});

3. Communication with other applications

Using Redis messages can be published to channels, then the messages will be forwarded by Redis to all the subscribers of that channel, this can be a very efficient communication bridge between two applications, for example NodeJS application and PHP Laravel application. Published messages are characterized into channels without knowledge of if any subscribers, and subscribers subscribe to channels where they will receive messages without knowledge of publishers. This decoupling allows for very efficient communication with the only requirement being the Redis implementation of the respective framework without any compliance with or to another application’s requirements.

A quick simple use case would be web-sockets. PHP lacks an out of the box solution for establishing socket connection to the client. There are implementations such as pusher and laravel-websockets. Depending on application you may find yourself in need of using NodeJS socket.io to send sockets to the client. So we will create an example that allows a Laravel app communicate with client side socket.io via NodeJs application.

For this we will use Laravel Broadcasting. First create an event by first defining it in the app/Providers/EventServiceProvider.php $listen property

'App\Events\RedisTest'=>[
]

For this the listeners wont be necessary as we will only be using the event. Run the event generate command to create the event.

php artisan event:generate

Then in the app/Events/RedisTest.php make it implement interface ‘ShouldBroadcast’ and on the method ‘broadcastOn’ in the same file create the channel ‘test_channel’ through which we will send the message.

Then change the BROADCAST_DRIVER value in .env to ‘redis’, or change it inside config/broadcasting.php to ‘redis’, this will make all the broadcasts use redis publisher.

Then create a simple NodeJs express http socket server in any directory.

npm init -y
npm install express socket.io ioredis
touch index.js

For creating a simple NodeJS express http socket server with Redis subscriber, the contents for index.js can be as simple as:

Start your NodeJs server which will start listening for http and socket connections on port 1610:

node index.js

Lastly we have to create a listener for any socket messages from the server in client side, for this also we have this simple html and JavaScript, that will log whatever message received from the socket server on the console, using socket.io client.

To test the socket, open the index.html file on your browser and press Ctrl+Shift+J to open the console, then open terminal and change directory to the Laravel learn-redis directory then open tinker by running:

php artisan tinker

When tinker launches test the event by invoking the event using event helper.

On your browser console you should see the message from Laravel Event class appear right there, and if you keep running the event on tinker the message will keep appearing on the console as many times.


The importance and uses of Redis in Laravel are limitless, however you should take great care when deciding to use it on your application. Redis is mainly best for applications which have heavy queries, intense need for caching, or having features that require multiple applications written in multiple languages to cover specific needs.

“Software has two types of value: the value of its behavior and the value of its structure. The second of these is the greater of the two because it is this value that makes software soft.” ― Robert C. Martin, Clean Architecture

If you find this article useful give it a clap, will appreciate, very much!

The article https://laracasts.com/discuss/channels/general-discussion/step-by-step-guide-to-installing-socketio-and-broadcasting-events-with-laravel-51 and https://divinglaravel.com/introduction-to-redis where very helpful in creating this article.

Should I think of software architecture every time I start a project?
In the past two years, working in a small company, software services company, and also doing freelance on the side, I…medium.com

Creating a Laravel 7.4.0 and Angular 9.2.1 web application
Recently I decided to create a laravel-angular application or pet project. The reasoffn being that I have been writing…medium.com

Angular 9: The magic of @ngrx/data (Angular state management on steroids)
In angular design there is no out of the box quick go to solution for data persistence through routing actions…medium.com