Développement

Redis — Cache, Sessions et Files d'attente en Laravel

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"

// Commentaires (0)

Connectez-vous pour laisser un commentaire.

Aucun commentaire pour le moment.