Documentación de Laravel 10.x
Aquí encontrarás fragmentos de código de Laravel y consejos útiles sobre desarrollo web.
Redis es un almacén avanzado de clave y valor de código abierto. A menudo se le llama servidor de estructura de datos ya que las claves pueden contener cadenas, hashes, listas, conjuntos y conjuntos ordenados.
Antes de usar Redis con Laravel, le recomendamos que instale y use la extensión phpredis a través de PECL. La extensión es más compleja de instalar en comparación con los paquetes PHP "de usuario", pero puede ofrecer un mejor rendimiento para aplicaciones que hacen un uso intensivo de Redis. Si está utilizando Laravel Sail, esta extensión ya está instalada en el contenedor Docker de su aplicación.
Si no puede instalar la extensión phpredis, puede instalar el paquete predis/predis
a través de Composer. Predis es un cliente de Redis escrito completamente en PHP y no requiere extensiones adicionales:
composer require predis/predis
Puede configurar los ajustes de Redis de su aplicación a través del archivo de configuración config/database.php
. En este archivo, verá una matriz redis
que contiene los servidores Redis utilizados por su aplicación:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'default' => [ 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_DB', 0), ], 'cache' => [ 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_CACHE_DB', 1), ], ],
Cada servidor Redis definido en su archivo de configuración debe tener un nombre, host y un puerto a menos que defina una sola URL para representar la conexión Redis:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'default' => [ 'url' => 'tcp://127.0.0.1:6379?database=0', ], 'cache' => [ ], ],
De forma predeterminada, los clientes de Redis utilizarán el esquema tcp
al conectarse a sus servidores Redis; sin embargo, puede utilizar cifrado TLS / SSL especificando una opción de configuración scheme
en la matriz de configuración de su servidor Redis:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'default' => [ 'scheme' => 'tls', 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_DB', 0), ], ],
Si su aplicación utiliza un clúster de servidores Redis, debe definir estos clústeres dentro de una clave clusters
de su configuración de Redis. Esta clave de configuración no existe por defecto, así que deberá crearla dentro del archivo de configuración config/database.php
de su aplicación:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'clusters' => [ 'default' => [ [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => 0, ], ], ], ],
De forma predeterminada, los clústeres realizarán fragmentación en el lado del cliente entre sus nodos, lo que le permite agrupar nodos y crear una gran cantidad de RAM disponible. Sin embargo, la fragmentación en el lado del cliente no maneja el cambio automático; por lo tanto, es adecuada principalmente para datos en caché transitorios que están disponibles desde otro almacenamiento de datos primario.
Si desea utilizar el clúster nativo de Redis en lugar de la fragmentación en el lado del cliente, puede especificarlo configurando el valor options.cluster
en redis
dentro del archivo de configuración config/database.php
de su aplicación:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), ], 'clusters' => [ // ... ], ],
Si desea que su aplicación interactúe con Redis a través del paquete Predis, asegúrese de que el valor de la variable de entorno REDIS_CLIENT
sea predis
:
'redis' => [ 'client' => env('REDIS_CLIENT', 'predis'), // ...],
Además de las opciones de configuración del servidor predeterminadas host
, port
, database
y password
, Predis admite parámetros de conexión adicionales que se pueden definir para cada uno de sus servidores Redis. Para utilizar estas opciones de configuración adicionales, agréguelas a la configuración de su servidor Redis en el archivo de configuración config/database.php
de su aplicación:
'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => 0, 'read_write_timeout' => 60,],
El archivo de configuración config/app.php
de Laravel contiene una matriz aliases
que define todos los alias de clase que registrará el marco. Por defecto, no se incluye ningún alias Redis
porque entraría en conflicto con el nombre de clase Redis
proporcionado por la extensión phpredis. Si está utilizando el cliente Predis y desea agregar un alias Redis
, puede agregarlo a la matriz aliases
en el archivo de configuración config/app.php
de su aplicación:
'aliases' => Facade::defaultAliases()->merge([ 'Redis' => Illuminate\Support\Facades\Redis::class,])->toArray(),
De forma predeterminada, Laravel utilizará la extensión phpredis para comunicarse con Redis. El cliente que Laravel utilizará para comunicarse con Redis está dictado por el valor de la opción de configuración redis.client
, que refleja típicamente el valor de la variable de entorno REDIS_CLIENT
:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), // Resto de la configuración de Redis...],
Además de las opciones de configuración del servidor predeterminadas scheme
, host
, port
, database
y password
, phpredis admite los siguientes parámetros de conexión adicionales: name
, persistent
, persistent_id
, prefix
, read_timeout
, retry_interval
, timeout
y context
. Puede agregar cualquiera de estas opciones a la configuración de su servidor Redis en el archivo de configuración config/database.php
de su aplicación:
'default' => [ 'host' => env('REDIS_HOST', 'localhost'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => 0, 'read_timeout' => 60, 'context' => [ // 'auth' => ['username', 'secret'], // 'stream' => ['verify_peer' => false], ],],
La extensión phpredis también se puede configurar para utilizar una variedad de algoritmos de serialización y compresión. Estos algoritmos se pueden configurar a través del array options
en su configuración de Redis:
'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ 'serializer' => Redis::SERIALIZER_MSGPACK, 'compression' => Redis::COMPRESSION_LZ4, ], // Resto de la configuración de Redis...],
Los algoritmos de serialización admitidos actualmente incluyen: Redis::SERIALIZER_NONE
(predeterminado), Redis::SERIALIZER_PHP
, Redis::SERIALIZER_JSON
, Redis::SERIALIZER_IGBINARY
y Redis::SERIALIZER_MSGPACK
.
Los algoritmos de compresión admitidos incluyen: Redis::COMPRESSION_NONE
(predeterminado), Redis::COMPRESSION_LZF
, Redis::COMPRESSION_ZSTD
, y Redis::COMPRESSION_LZ4
.
Puede interactuar con Redis llamando a varios métodos en la fachada Redis
. La fachada Redis
admite métodos dinámicos, lo que significa que puede llamar a cualquier comando Redis en la fachada y el comando se enviará directamente a Redis. En este ejemplo, llamaremos al comando GET
de Redis llamando al método get
en la fachada Redis
:
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller;use Illuminate\Support\Facades\Redis;use Illuminate\View\View; class UserController extends Controller{ /** * Muestra el perfil del usuario dado. */ public function show(string $id): View { return view('user.profile', [ 'user' => Redis::get('user:profile:'.$id) ]); }}
Como se mencionó anteriormente, puede llamar a cualquiera de los comandos de Redis en la fachada Redis
. Laravel utiliza métodos mágicos para pasar los comandos al servidor Redis. Si un comando Redis espera argumentos, debe pasarlos al método correspondiente de la fachada:
use Illuminate\Support\Facades\Redis; Redis::set('name', 'Taylor'); $values = Redis::lrange('names', 5, 10);
Alternativamente, puede pasar comandos al servidor utilizando el método command
de la fachada Redis
, que acepta el nombre del comando como su primer argumento y un array de valores como su segundo argumento:
$values = Redis::command('lrange', ['name', 5, 10]);
El archivo de configuración config/database.php
de su aplicación le permite definir múltiples conexiones / servidores Redis. Puede obtener una conexión a un servidor Redis específico utilizando el método connection
de la fachada Redis
:
$redis = Redis::connection('connection-name');
Para obtener una instancia de la conexión Redis predeterminada, puede llamar al método connection
sin argumentos adicionales:
$redis = Redis::connection();
El método transaction
de la fachada Redis
proporciona un envoltorio conveniente alrededor de los comandos nativos MULTI
y EXEC
de Redis. El método transaction
acepta un cierre como su único argumento. Este cierre recibirá una instancia de conexión Redis y podrá emitir cualquier comando que desee a esta instancia. Todos los comandos Redis emitidos dentro del cierre se ejecutarán en una única transacción atómica:
use Redis;use Illuminate\Support\Facades; Facades\Redis::transaction(function (Redis $redis) { $redis->incr('user_visits', 1); $redis->incr('total_visits', 1);});
Advertencia Al definir una transacción de Redis, no puede recuperar ningún valor de la conexión de Redis. Recuerde, su transacción se ejecuta como una operación única y atómica, y esa operación no se ejecuta hasta que su cierre completo haya terminado de ejecutar sus comandos.
El método eval
proporciona otra forma de ejecutar múltiples comandos Redis en una sola operación atómica. Sin embargo, el método eval
tiene la ventaja de poder interactuar y inspeccionar los valores de las claves Redis durante esa operación. Los scripts Redis están escritos en el lenguaje de programación Lua.
El método eval
puede ser un poco intimidante al principio, pero exploraremos un ejemplo básico para romper el hielo. El método eval
espera varios argumentos. Primero, debe pasar el script Lua (como una cadena) al método. En segundo lugar, debe pasar el número de claves (como un entero) con las que el script interactúa. En tercer lugar, debe pasar los nombres de esas claves. Finalmente, puede pasar cualquier otro argumento adicional que necesite acceder dentro de su script.
En este ejemplo, incrementaremos un contador, inspeccionaremos su nuevo valor e incrementaremos un segundo contador si el valor del primer contador es mayor que cinco. Finalmente, devolveremos el valor del primer contador:
$value = Redis::eval(<<<'LUA' local counter = redis.call("incr", KEYS[1]) if counter > 5 then redis.call("incr", KEYS[2]) end return counterLUA, 2, 'first-counter', 'second-counter');
Advertencia Consulte la documentación de Redis para obtener más información sobre la escritura de scripts en Redis.
En ocasiones, puede ser necesario ejecutar docenas de comandos de Redis. En lugar de realizar un viaje de red a su servidor Redis para cada comando, puede utilizar el método pipeline
. El método pipeline
acepta un argumento: un cierre que recibe una instancia de Redis. Puede emitir todos sus comandos a esta instancia de Redis y se enviarán todos al servidor Redis al mismo tiempo para reducir los viajes de red al servidor. Los comandos aún se ejecutarán en el orden en que se emitieron:
use Redis;use Illuminate\Support\Facades; Facades\Redis::pipeline(function (Redis $pipe) { for ($i = 0; $i < 1000; $i++) { $pipe->set("key:$i", $i); }});
Laravel proporciona una interfaz conveniente para los comandos publish
y subscribe
de Redis. Estos comandos de Redis le permiten escuchar mensajes en un "canal" dado. Puede publicar mensajes en el canal desde otra aplicación, o incluso usando otro lenguaje de programación, lo que permite una comunicación fácil entre aplicaciones y procesos.
Primero, configuremos un escucha de canal utilizando el método subscribe
. Colocaremos esta llamada al método dentro de un comando Artisan ya que llamar al método subscribe
inicia un proceso que se ejecuta durante mucho tiempo:
<?php namespace App\Console\Commands; use Illuminate\Console\Command;use Illuminate\Support\Facades\Redis; class RedisSubscribe extends Command{ /** * El nombre y la firma del comando de consola. * * @var string */ protected $signature = 'redis:subscribe'; /** * La descripción del comando de consola. * * @var string */ protected $description = 'Subscribe to a Redis channel'; /** * Ejecuta el comando de consola. */ public function handle(): void { Redis::subscribe(['test-channel'], function (string $message) { echo $message; }); }}
Ahora podemos publicar mensajes en el canal utilizando el método publish
:
use Illuminate\Support\Facades\Redis; Route::get('/publish', function () { // ... Redis::publish('test-channel', json_encode([ 'name' => 'Adam Wathan' ]));});
Utilizando el método psubscribe
, puede suscribirse a un canal comodín, lo que puede ser útil para capturar todos los mensajes en todos los canales. El nombre del canal se pasará como segundo argumento al cierre proporcionado:
Redis::psubscribe(['*'], function (string $message, string $channel) { echo $message;}); Redis::psubscribe(['users.*'], function (string $message, string $channel) { echo $message;});