Introducción

Redis es un almacenamiento avanzado de pares clave-valor y de código abierto. A menudo se le denomina como un servidor de estructura de datos ya que las claves pueden contener cadenas, hashes, listas, sets y sets ordenados.

Antes de utilizar Redis con Laravel, te recomendamos que instales y uses la extensión de PHP PhpRedis mediante PECL. La extensión es más difícil de instalar, pero contribuirá a un mejor rendimiento en aplicaciones que hacen un uso intensivo de Redis.

Alternativamente, puedes instalar el paquete predis/predis mediante Composer:

composer require predis/predis

El mantenimiento de Predis se ha abandonado por su autor original y puede que sea eliminado de Laravel en futuras versiones.

Configuración

La configuración de Redis para tu aplicación está ubicada en el archivo de configuración config/database. Dentro de este archivo, podrás ver el arreglo redis que contiene los servidores de Redis utilizados por tu aplicación:

'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),
    ],

],

La configuración del servidor por defecto deberá ser suficiente para el entorno de desarrollo. Sin embargo, puedes modificar este arreglo según tu entorno. Cada servidor de Redis definido en tu archivo de configuración debe contener un nombre, host y puerto.

Configuración de clusters

Si tu aplicación está utilizando un cluster de servidores Redis, debes definir esos clusters en la clave clusters de tu configuración de Redis:

'redis' => [

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

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

],

Por defecto, los clusters realizarán el sharding del lado del cliente a través de sus nodos, permitiéndote agrupar nodos y crear una gran cantidad de RAM disponible. Sin embargo, ten en cuenta que el sharding del lado del cliente no gestiona failover; por lo tanto, es principalmente adecuado para datos en caché que estén disponibles desde otro almacenamiento de datos primario. Si deseas utilizar el agrupamiento nativo de Redis, debes especificarlo en la clave options de tu configuración de Redis:

'redis' => [

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

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
    ],

    'clusters' => [
        // ...
    ],

],

Predis

Para utilizar la extensión Predis, debes cambiar la variable de entorno REDIS_CLIENT de phpredis a predis:

'redis' => [

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

    // Rest of Redis configuration...
],

Además de las opciones predeterminadas de la configuración del servidor host, port, database y password, Predis admite parámetros de conexión adicionales que pueden ser definidos para cada uno de tus servidores de Redis. Para utilizar estas opciones de configuración adicionales, agrégalos a la configuración del servidor de Redis en el archivo de configuración config/database.php:

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

PhpRedis

La extensión PhpRedis está configurada por defecto en el fichero env como REDIS_CLIENT y en tu archivo de configuración config/database.php:

'redis' => [

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

    // Rest of Redis configuration...
],

Si planeas usar la extensión PhpRedis junto con el alias del Facade Redis, deberías renombrarlo a otra cosa, como RedisManager, para evitar una colisión con la clase Redis. Puedes hacerlo en la sección de alias de tu archivo de configuración app.php.

'RedisManager' => Illuminate\Support\Facades\Redis::class,

Además de las opciones predeterminadas de configuración del servidor host, port, database y password, PhpRedis admite los siguientes parámetros de conexión adicionales: persistent, prefix, read_timeout y timeout. Puedes agregar cualquiera de estas opciones a tu configuración del servidor de Redis en el archivo de configuración config/database.php:

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

Facade Redis

Para evitar colisiones de nombres de clases con la propia extensión PHP de Redis, necesitarás eliminar o renombrar el alias del Facade Illuminate\Support\Facades\Redis del arreglo aliases de tu archivo de configuración app. Generalmente, deberás eliminar este alias por completo y sólo referenciar el Facade por su nombre de clase completo mientras que uses la extensión Redis PHP.

Interactuar con redis

Puedes interactuar con Redis llamando varios métodos en el facade Redis. El facade Redis admite métodos dinámicos, lo que significa que puedes llamar a cualquier comando de Redis en el facade y el comando será pasado directamente a Redis. En este ejemplo, vamos a llamar al comando GET de Redis llamando al método get en el facade Redis:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Redis;

class UserController extends Controller
{
    /**
    * Show the profile for the given user.
    *
    * @param  int  $id
    * @return Response
    */
    public function showProfile($id)
    {
        $user = Redis::get('user:profile:'.$id);

        return view('user.profile', ['user' => $user]);
    }
}

Como lo mencionamos anteriormente, puedes llamar a cualquier comando de Redis en el facade Redis. Laravel utiliza métodos mágicos para pasar los comandos al servidor de Redis, para que pases los argumentos que espera el comando de Redis:

Redis::set('name', 'Taylor');

$values = Redis::lrange('names', 5, 10);

Alternativamente, también puedes pasar comandos al servidor usando el método command, el cual acepta el nombre del comando como primer argumento, y un arreglo de valores como segundo argumento:

$values = Redis::command('lrange', ['name', 5, 10]);

Utilizar múltiples conexiones de Redis

Puedes obtener una instancia de Redis llamando al método Redis::connection:

$redis = Redis::connection();

Esto te dará una instancia del servidor de Redis predeterminado. También puedes pasar la conexión o nombre del cluster al método connection para obtener un servidor o cluster en específico según lo definido en tu configuración de Redis:

$redis = Redis::connection('my-connection');

Canalizar comandos

La canalización debe ser utilizada cuando necesites enviar muchos comandos al servidor. El método pipeline acepta un argumento: una Closure que recibe una instancia de Redis. Puedes emitir todos tus comandos a esta instancia de Redis y después éstos serán enviados al servidor proporcionando mejor rendimiento:

Redis::pipeline(function ($pipe) {
    for ($i = 0; $i < 1000; $i++) {
        $pipe->set("key:$i", $i);
    }
});

Pub / Sub

Laravel proporciona una interfaz conveniente para los comandos publish y subscribe de Redis. Estos comandos de Redis te permiten escuchar mensajes en un «canal» dado. Puedes publicar mensajes en el canal desde otra aplicación, o incluso utilizando otro lenguaje de programación, lo que permite una comunicación sencilla entre aplicaciones y procesos.

Primero, configuremos un listener para el canal usando el método subscribe. Vamos a colocar una llamada a este método en un comando de Artisan ya que llamar al método subscribe comienza un proceso de larga ejecución:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;

class RedisSubscribe extends Command
{
    /**
    * The name and signature of the console command.
    *
    * @var string
    */
    protected $signature = 'redis:subscribe';

    /**
    * The console command description.
    *
    * @var string
    */
    protected $description = 'Subscribe to a Redis channel';

    /**
    * Execute the console command.
    *
    * @return mixed
    */
    public function handle()
    {
        Redis::subscribe(['test-channel'], function ($message) {
            echo $message;
        });
    }
}

Ahora podemos publicar mensajes en el canal usando el método publish:

Route::get('publish', function () {
    // Route logic...

    Redis::publish('test-channel', json_encode(['foo' => 'bar']));
});

Suscripciones de comodines

Usando el método psubscribe, puedes suscribirte a un canal comodín, el cual puede ser útil para capturar todos los mensajes en todos los canales. El nombre del canal $channel será pasado como segundo argumento al callback Closure proporcionado:

Redis::psubscribe(['*'], function ($message, $channel) {
    echo $message;
});

Redis::psubscribe(['users.*'], function ($message, $channel) {
    echo $message;
});

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.

Lección anterior Base de datos: Seeding - Documentación de Laravel 6 Lección siguiente Eloquent: Primeros Pasos - Documentación de Laravel 6