Redis è un key-value store in memoria usato come backend per molte funzionalità di Laravel.
Qui vediamo configurazione, operazioni e Pub/Sub in Laravel.
Cache Redis come driver di cache
Code Redis come driver di coda
Broadcasting Pub/Sub per il real-time
Cos’è Redis
Redis è un key-value store veloce open source.
Supporta stringhe, hash, list, set e sorted set: è un data structure server.
Utilizzi in Laravel:
Scelta del client
Laravel supporta PhpRedis (estensione PHP) e Predis (pacchetto PHP).
Voce PhpRedis Predis Implementazione Estensione PHP in C Pacchetto PHP puro Installazione PECL composer requirePrestazioni Alte Leggermente inferiori Laravel Sail Già presente Da installare Ambienti consigliati Produzione Sviluppo o ambienti in cui l’installazione dell’estensione è complessa
Il default in Laravel 13 è PhpRedis. Consigliato in produzione.
In Laravel Sail è già installato.
Configurazione
config/database.php
'redis' => [
'client' => env ( 'REDIS_CLIENT' , 'phpredis' ),
'options' => [
'cluster' => env ( 'REDIS_CLUSTER' , 'redis' ),
'prefix' => env ( 'REDIS_PREFIX' , Str :: slug ( env ( 'APP_NAME' , 'laravel' ), '_' ) . '_database_' ),
],
'default' => [
'url' => env ( 'REDIS_URL' ),
'host' => env ( 'REDIS_HOST' , '127.0.0.1' ),
'username' => env ( 'REDIS_USERNAME' ),
'password' => env ( 'REDIS_PASSWORD' ),
'port' => env ( 'REDIS_PORT' , '6379' ),
'database' => env ( 'REDIS_DB' , '0' ),
],
'cache' => [
'url' => env ( 'REDIS_URL' ),
'host' => env ( 'REDIS_HOST' , '127.0.0.1' ),
'username' => env ( 'REDIS_USERNAME' ),
'password' => env ( 'REDIS_PASSWORD' ),
'port' => env ( 'REDIS_PORT' , '6379' ),
'database' => env ( 'REDIS_CACHE_DB' , '1' ),
],
],
Variabili d’ambiente
REDIS_CLIENT =phpredis
REDIS_HOST =127.0.0.1
REDIS_PORT =6379
REDIS_PASSWORD =null
REDIS_DB =0
REDIS_CACHE_DB =1
Anche URL:
'default' => [
'url' => 'tcp://127.0.0.1:6379?database=0' ,
],
'cache' => [
'url' => 'tls://user:[email protected] :6380?database=1' ,
],
TLS/SSL
'default' => [
'scheme' => 'tls' ,
'url' => env ( 'REDIS_URL' ),
'host' => env ( 'REDIS_HOST' , '127.0.0.1' ),
'username' => env ( 'REDIS_USERNAME' ),
'password' => env ( 'REDIS_PASSWORD' ),
'port' => env ( 'REDIS_PORT' , '6379' ),
'database' => env ( 'REDIS_DB' , '0' ),
],
Cluster
'redis' => [
'client' => env ( 'REDIS_CLIENT' , 'phpredis' ),
'options' => [
'cluster' => env ( 'REDIS_CLUSTER' , 'redis' ),
'prefix' => env ( 'REDIS_PREFIX' , Str :: slug ( env ( 'APP_NAME' , 'laravel' ), '_' ) . '_database_' ),
],
'clusters' => [
'default' => [
[
'url' => env ( 'REDIS_URL' ),
'host' => env ( 'REDIS_HOST' , '127.0.0.1' ),
'username' => env ( 'REDIS_USERNAME' ),
'password' => env ( 'REDIS_PASSWORD' ),
'port' => env ( 'REDIS_PORT' , '6379' ),
'database' => env ( 'REDIS_DB' , '0' ),
],
],
],
],
Default options.cluster = redis usa il clustering nativo. Consigliato in produzione: gestisce il failover.
Per client-side sharding con Predis, rimuovi options.cluster. Il client-side sharding non gestisce failover; adatto solo a dati temporanei.
Predis
composer require predis/predis
Con opzioni di connessione:
'default' => [
'url' => env ( 'REDIS_URL' ),
'host' => env ( 'REDIS_HOST' , '127.0.0.1' ),
'username' => env ( 'REDIS_USERNAME' ),
'password' => env ( 'REDIS_PASSWORD' ),
'port' => env ( 'REDIS_PORT' , '6379' ),
'database' => env ( 'REDIS_DB' , '0' ),
'read_write_timeout' => 60 ,
],
Retry
Da Predis 3.4.0:
use Predis\Retry\Strategy\ ExponentialBackoff ;
'default' => [
'url' => env ( 'REDIS_URL' ),
// ...
'retry' => [
ExponentialBackoff :: class => [
env ( 'REDIS_BACKOFF_BASE' , 100 ),
env ( 'REDIS_BACKOFF_CAP' , 1000 ),
true , // jitter
],
],
'max_retries' => env ( 'REDIS_MAX_RETRIES' , 3 ),
],
In cluster:
use Predis\Retry\Strategy\ NoBackoff ;
'clusters' => [
'default' => [
// ...
],
],
'options' => [
'cluster' => env ( 'REDIS_CLUSTER' , 'redis' ),
'parameters' => [
'retry' => [
NoBackoff :: class => [],
],
'max_retries' => env ( 'REDIS_MAX_RETRIES' , 3 ),
],
],
PhpRedis
Da PECL (già in Laravel Sail). Opzioni: name, persistent, persistent_id, prefix, read_timeout, retry_interval, max_retries, backoff_algorithm, backoff_base, backoff_cap, timeout, context.
'default' => [
'url' => env ( 'REDIS_URL' ),
'host' => env ( 'REDIS_HOST' , '127.0.0.1' ),
'username' => env ( 'REDIS_USERNAME' ),
'password' => env ( 'REDIS_PASSWORD' ),
'port' => env ( 'REDIS_PORT' , '6379' ),
'database' => env ( 'REDIS_DB' , '0' ),
'read_timeout' => 60 ,
'context' => [
// 'auth' => ['username', 'secret'],
// 'stream' => ['verify_peer' => false],
],
],
Retry e backoff
Algoritmi supportati: default, decorrelated_jitter, equal_jitter, exponential, uniform, constant.
'default' => [
// ...
'max_retries' => env ( 'REDIS_MAX_RETRIES' , 3 ),
'backoff_algorithm' => env ( 'REDIS_BACKOFF_ALGORITHM' , 'decorrelated_jitter' ),
'backoff_base' => env ( 'REDIS_BACKOFF_BASE' , 100 ),
'backoff_cap' => env ( 'REDIS_BACKOFF_CAP' , 1000 ),
],
Unix socket
REDIS_HOST =/run/redis/redis.sock
REDIS_PORT =0
Serializzazione e compressione
'redis' => [
'client' => env ( 'REDIS_CLIENT' , 'phpredis' ),
'options' => [
'cluster' => env ( 'REDIS_CLUSTER' , 'redis' ),
'prefix' => env ( 'REDIS_PREFIX' , Str :: slug ( env ( 'APP_NAME' , 'laravel' ), '_' ) . '_database_' ),
'serializer' => Redis :: SERIALIZER_MSGPACK ,
'compression' => Redis :: COMPRESSION_LZ4 ,
],
],
Serializer:
Costante Descrizione Redis::SERIALIZER_NONENessuna (default) Redis::SERIALIZER_PHPPHP Redis::SERIALIZER_JSONJSON Redis::SERIALIZER_IGBINARYigbinary Redis::SERIALIZER_MSGPACKMessagePack
Compressione:
Costante Descrizione Redis::COMPRESSION_NONENessuna Redis::COMPRESSION_LZFLZF Redis::COMPRESSION_ZSTDZstandard Redis::COMPRESSION_LZ4LZ4
Operazioni con Redis
Facade Redis
<? php
namespace App\Http\Controllers ;
use Illuminate\Support\Facades\ Redis ;
use Illuminate\View\ View ;
class UserController extends Controller
{
public function show ( string $id ) : View
{
return view ( 'user.profile' , [
'user' => Redis :: get ( 'user:profile:' . $id )
]);
}
}
Comandi con argomenti diretti:
Redis :: set ( 'name' , 'Taylor' );
$values = Redis :: lrange ( 'names' , 5 , 10 );
Con command:
$values = Redis :: command ( 'lrange' , [ 'name' , 5 , 10 ]);
Più connessioni
$redis = Redis :: connection ( 'connection-name' );
$redis = Redis :: connection ();
Transazioni
MULTI/EXEC atomici.
use Redis ;
use Illuminate\Support\ Facades ;
Facades\ Redis :: transaction ( function ( Redis $redis ) {
$redis -> incr ( 'user_visits' , 1 );
$redis -> incr ( 'total_visits' , 1 );
});
Nelle transazioni non puoi leggere valori: la closure viene eseguita interamente e poi inviata con EXEC.
Script Lua
$value = Redis :: eval ( <<<' LUA '
local counter = redis.call("incr", KEYS[1])
if counter > 5 then
redis.call("incr", KEYS[2])
end
return counter
LUA , 2 , 'first-counter' , 'second-counter' );
Ordine: script → numero di key → key… → argomenti…
Pipeline
use Redis ;
use Illuminate\Support\ Facades ;
Facades\ Redis :: pipeline ( function ( Redis $pipe ) {
for ( $i = 0 ; $i < 1000 ; $i ++ ) {
$pipe -> set ( "key: $i " , $i );
}
});
La pipeline non è atomica. Per atomicità usa transazione o Lua.
Pub / Sub
Subscriber
subscribe() è a lunga esecuzione: usalo in un comando Artisan.
<? php
namespace App\Console\Commands ;
use Illuminate\Console\ Command ;
use Illuminate\Support\Facades\ Redis ;
class RedisSubscribe extends Command
{
protected $signature = 'redis:subscribe' ;
protected $description = 'Subscribe to a Redis channel' ;
public function handle () : void
{
Redis :: subscribe ([ 'test-channel' ], function ( string $message ) {
echo $message ;
});
}
}
Publisher
use Illuminate\Support\Facades\ Redis ;
Route :: get ( '/publish' , function () {
Redis :: publish ( 'test-channel' , json_encode ([
'name' => 'Adam Wathan'
]));
});
Wildcard
Redis :: psubscribe ([ '*' ], function ( string $message , string $channel ) {
echo $message ;
});
Redis :: psubscribe ([ 'users.*' ], function ( string $message , string $channel ) {
echo $message ;
});
Riepilogo
Produzione : PhpRedis (PECL, alte prestazioni)
Sviluppo o difficoltà di installazione : Predis (pacchetto Composer)
Laravel Sail : PhpRedis già presente
Definisci più connessioni Redis in config/database.php (es. default / cache)
In cluster usa la chiave clusters
In produzione considera TLS e credenziali
Come scegliere le operazioni
Operazione Uso Metodi della facade Comandi Redis normali transaction()Atomicità per più comandi (senza letture) eval()Script Lua (atomicità con letture) pipeline()Invio massivo (non atomico) subscribe() / publish()Messaggistica (Pub/Sub)