Redis — Cache, Sessions et Files d'attente en Laravel
Redis est une base de données en mémoire ultra-rapide. Dans un contexte Laravel, c'est le couteau suisse des performances. Voici comment l'utiliser efficacement.
Installation
# Installer le client PHP Redis
composer require predis/predis
# ou
pecl install redis # Extension native (plus rapide)
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
1. Cache
Mise en cache basique
use Illuminate\Support\Facades\Cache;
// Stocker une valeur pendant 1 heure
Cache::put('user:42:profile', $profile, 3600);
// Récupérer (avec valeur par défaut)
$profile = Cache::get('user:42:profile', fn() => User::find(42)->profile);
// Remember — pattern le plus utilisé
$articles = Cache::remember('articles.published', 3600, function () {
return Article::with(['author', 'category'])
->published()
->get();
});
// Invalider
Cache::forget('articles.published');
// Invalider par pattern (avec Redis)
Cache::tags(['articles'])->flush();
Cache taggué — La vraie puissance
// Stocker avec des tags
Cache::tags(['articles', 'category:dev'])
->remember('articles.dev', 3600, function () {
return Article::where('category_id', 1)->published()->get();
});
// Invalider tout ce qui touche aux articles
Cache::tags(['articles'])->flush();
2. Sessions avec Redis
SESSION_DRIVER=redis
// config/session.php
'connection' => 'session', // Connection Redis dédiée
// config/database.php
'redis' => [
'session' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_SESSION_DB', '1'), // DB séparée !
],
],
Avantage : Les sessions persistent entre les redémarrages et sont partagées entre plusieurs instances (load balancing).
3. Files d'attente (Queues)
QUEUE_CONNECTION=redis
// Créer un Job
class ProcessArticleImages implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3;
public int $timeout = 120;
public function __construct(private Article $article) {}
public function handle(): void
{
// Traitement long (resize d'images, envoi email, etc.)
foreach ($this->article->images as $image) {
ImageProcessor::resize($image, [800, 400]);
}
}
public function failed(\Throwable $e): void
{
Log::error("Échec traitement images article {$this->article->id}: {$e->getMessage()}");
}
}
// Dispatcher le job
ProcessArticleImages::dispatch($article);
// Avec délai
ProcessArticleImages::dispatch($article)->delay(now()->addMinutes(5));
// Sur une queue spécifique
ProcessArticleImages::dispatch($article)->onQueue('images');
Démarrer les workers
# Worker standard
php artisan queue:work redis
# Worker avec supervision
php artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
# Avec Horizon (monitoring avancé)
composer require laravel/horizon
php artisan horizon
4. Rate Limiting avec Redis
use Illuminate\Support\Facades\RateLimiter;
// Définir une limite (RouteServiceProvider ou AppServiceProvider)
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
// Vérification manuelle
if (RateLimiter::tooManyAttempts('send-email:'.$user->id, 5)) {
return response()->json(['error' => 'Trop de requêtes'], 429);
}
RateLimiter::hit('send-email:'.$user->id, decay: 3600);
5. Pub/Sub pour le temps réel
// Publisher
Redis::publish('articles.new', json_encode([
'id' => $article->id,
'title' => $article->title,
]));
// Subscriber (dans un artisan command)
Redis::subscribe(['articles.new'], function ($message) {
$data = json_decode($message);
broadcast(new ArticlePublished($data));
});
Monitoring avec Redis CLI
# Voir toutes les clés
redis-cli KEYS "*"
# Stats en temps réel
redis-cli MONITOR
# Mémoire utilisée
redis-cli INFO memory
# Vider un cache spécifique
redis-cli DEL "laravel_cache:articles.published"
Aucun commentaire pour le moment.