Utilizzo di Laravel con Dragonfly

Dragonfly è un sostituto drop-in per Redis progettato per offrire prestazioni molto superiori con un numero molto inferiore di server. Un singolo nodo può gestire milioni di query al secondo e fino a 1 TB di dati in memoria. In questo articolo, esploreremo come utilizzare Dragonfly con Laravel, uno dei framework web più utilizzati e noti.

Dragonfly mantiene la piena compatibilità con l’interfaccia di Redis, il che significa che i sviluppatori Laravel possono integrarlo come driver di cache e coda senza modificare una sola riga di codice. Questa integrazione senza soluzione di continuità può offrire un percorso di aggiornamento agevole con benefici sostanziali.

Quindi, che tu sia un veterano di Laravel o stia appena iniziando, unisciti a noi mentre entriamo nel mondo di Dragonfly e Laravel.

Iniziare

Iniziamo configurando un nuovo istanza di Dragonfly. Visita la nostra documentazione qui per scaricare un’immagine o il binario e avere un’istanza di Dragonfly in funzione in poco tempo. Una volta che l’istanza di Dragonfly è operativa e raggiungibile, integrarla con il tuo progetto Laravel è un gioco da ragazzi. Fortunatamente, Laravel supporta già Redis completamente, quindi tutti i suoi driver possono essere riutilizzati. Per utilizzare Dragonfly nel tuo applicativo Laravel, inizia aggiornando il file .env con le seguenti configurazioni.

Per la gestione della cache e delle sessioni:

CACHE_DRIVER=redis
SESSION_DRIVER=redis

Per integrare Dragonfly anche come driver di coda:

QUEUE_CONNECTION=redis

Anche se stiamo utilizzando redis come valore del driver, Dragonfly è progettato per essere un sostituto diretto per Redis, quindi non è necessario installare un driver aggiuntivo. Con il driver impostato, il passo successivo è assicurarsi che Laravel possa comunicare con l’istanza di Dragonfly. Ciò comporta la modifica del file .env con i dettagli di connessione corretti:

  • REDIS_HOST: Il nome host o indirizzo IP del server Dragonfly.
  • REDIS_PORT: La porta su cui è in esecuzione l’istanza di Dragonfly.
  • REDIS_PASSWORD: La password per l’istanza di Dragonfly, se impostata.

Ecco una configurazione di esempio:

REDIS_HOST=127.0.0.1 # Replace with Dragonfly host
REDIS_PORT=6379      # Replace with Dragonfly port
REDIS_PASSWORD=null  # Replace with Dragonfly password if applicable

Dopo aver aggiornato queste impostazioni, verifica la connessione eseguendo una semplice operazione come INFO in Laravel. Se incontri problemi di connettività, controlla nuovamente i valori host, porta e password. Inoltre, assicurati che il server Dragonfly sia in esecuzione e accessibile dall’ambiente dell’applicazione Laravel.

use Illuminate\Support\Facades\Redis;

// Esegui il comando INFO e stampa la versione di Dragonfly.
Redis::info()["dragonfly_version"];

Maggiore efficienza come cache

Il caching dei valori comunemente accessibili è uno dei principali usi dei database in memoria come Dragonfly e Redis grazie ai loro tempi di risposta veloci. È qui che Dragonfly risalta, specialmente in scenari che coinvolgono un gran numero di chiavi e client, tipici come cache centrale di sistemi multi-nodo o microservizi.

A standout feature of Dragonfly is the cache mode, designed specifically for scenarios where maintaining a lean memory footprint is as crucial as performance. In this mode, Dragonfly evicts the least recently accessed values when it detects low memory availability, ensuring efficient memory usage without sacrificing speed. You can read more about the eviction algorithm in the Dragonfly Cache Design blog post.

Attivare la modalità cache è semplice. Ecco gli indicatori che utilizzeresti per eseguire Dragonfly in questa modalità, con una cappa di memoria di 12GB:

./dragonfly --cache_mode --maxmemory=12G

Considera una situazione in cui il tuo applicativo deve gestire un elevato volume di richieste con un vasto dataset. In tali casi, la modalità cache Dragonfly può gestire in modo efficiente l’utilizzo della memoria, fornendo accesso rapido ai dati, garantendo che il tuo applicativo rimanga reattivo e agile.

In termini di API, tutte le funzionalità del facciamo Cache di Laravel dovrebbero essere supportate. Ad esempio, per memorizzare una determinata chiave e valore con un tempo di scadenza specifico, puoi utilizzare il seguente frammento di codice:

use Illuminate\Support\Facades\Cache;

// Memorizza un valore con una scadenza di 10 minuti.
Cache::put("key", "value", 600);

Utilizzo della Memoria

Uno dei vantaggi dell’utilizzo di Dragonfly come cache è il suo utilizzo della memoria significativamente inferiore per la maggior parte dei casi d’uso. Effettuiamo un semplice esperimento e riempiamo sia Redis che Dragonfly con stringhe casuali, misurando il loro utilizzo totale di memoria dopo averli riempiti con dati.

Dataset Dragonfly Redis
3 Million Values of Length 1000 2.75GB 3.17GB
15 Million Values of Length 200 3.8GB 4.6GB

Dopo aver condotto l’esperimento, abbiamo osservato che l’utilizzo della memoria di Dragonfly è fino a 20% inferiore rispetto a Redis in condizioni simili. Ciò ti consente di memorizzare significativamente più dati utili con gli stessi requisiti di memoria, rendendo la cache più efficiente e ottenendo una copertura più elevata. Puoi leggere maggiori dettagli sui benchmark di throughput e l’utilizzo della memoria di Dragonfly nel post sul blog “Scalabilità e Prestazioni di Redis vs. Dragonfly”.

Snapshotting

Oltre a un utilizzo di memoria inferiore, Dragonfly dimostra anche stabilità durante i processi di creazione di snapshot. La creazione di snapshot, specialmente in istanze impegnate, può essere una sfida in termini di gestione della memoria. Con Redis, la cattura di uno snapshot su un’istanza altamente attiva potrebbe comportare un aumento dell’utilizzo della memoria. Ciò accade perché Redis deve copiare pagine di memoria, anche quelle che sono state solo parzialmente sovrascritte, causando un aumento dell’utilizzo della memoria.

Al contrario, Dragonfly regola l’ordine della creazione di snapshot in base alle richieste in ingresso, impedendo efficacemente qualsiasi improvviso aumento dell’utilizzo della memoria. Ciò significa che anche durante operazioni intensive come la creazione di snapshot, Dragonfly mantiene una impronta di memoria stabile, garantendo prestazioni coerenti senza il rischio di improvvisi picchi di memoria. Puoi leggere di più sull’algoritmo di creazione di snapshot di Dragonfly nel post Balanced vs. Unbalanced.

Permanenza delle Chiavi

Dragonfly introduce anche una nuova funzionalità con il suo comando personalizzato STICK. Questo comando è particolarmente utile nelle istanze in modalità cache. Consente di contrassegnare specifiche chiavi come non espellibili, indipendentemente dalla loro frequenza di accesso.

Questa funzionalità è particolarmente utile per memorizzare dati importanti ma accessibili raramente. Ad esempio, puoi mantenere in modo affidabile informazioni ausiliarie, come valori di configurazione dinamica, direttamente nella tua istanza di Dragonfly. Questo elimina la necessità di un database separato per i dati usati raramente ma cruciali, semplificando il processo di gestione dei dati.

// Memorizzazione di un valore nell'istanza di Dragonfly con persistenza.
Redis::transaction(function (Redis $redis) {
    $redis->set('server-dynamic-configuration-key', '...');
    $redis->command('STICK', 'server-dynamic-configuration-key');
});

// ...

// Restituirà sempre un valore poiché la chiave non può essere eliminata.
$redis->get('server-dynamic-configuration-key');

Aumento della Capacità di Trasmissione nella Gestione delle Code

Dragonfly, molto simile a Redis, è molto abile nella gestione delle code e dei lavori. Come potresti aver già capito, la transizione all’uso di Dragonfly per questo scopo è senza soluzione di continuità, richiedendo nessuna modifica del codice. Considera il seguente esempio in Laravel, dove un lavoro di elaborazione di un podcast viene inviato:

use App\Jobs\ProcessPodcast;

$podcast = Podcast::create(/* ... */);
ProcessPodcast::dispatchSync($podcast);

Sia Dragonfly che Redis sono in grado di gestire facilmente decine di migliaia di lavori al secondo.

Per coloro che mirano a massimizzare le prestazioni, è importante notare che l’uso di una singola coda di lavoro non produrrà significativi guadagni di prestazioni. Per sfruttare veramente le capacità di Dragonfly, dovrebbero essere utilizzate più code. Questo approccio distribuisce la carico su più thread di Dragonfly, migliorando la capacità di trasmissione complessiva.

Tuttavia, un problema comune sorge quando le chiavi dalla stessa coda finiscono su thread diversi, portando a un aumento della latenza. Per contrastare ciò, Dragonfly offre l’uso di hashtag nei nomi delle code. Questi hashtag garantiscono che i lavori nella stessa coda (che utilizza lo stesso hashtag) siano automaticamente assegnati a thread specifici, proprio come in un ambiente di Redis Cluster, riducendo la latenza e ottimizzando le prestazioni. Per saperne di più sugli hashtag, consulta il post sul blog Running BullMQ with Dragonfly, che offre una spiegazione dettagliata degli hashtag e dei loro vantaggi, mentre Dragonfly viene utilizzato come archivio di supporto per i sistemi di code messaggi.

Come esempio rapido, per ottimizzare la gestione delle code con Dragonfly, inizia lanciando Dragonfly con specifici flag che abilitano il blocco basato su hashtag e la modalità cluster emulata:

./dragonfly --lock_on_hashtags --cluster_mode=emulated

Una volta che Dragonfly è in esecuzione con queste impostazioni, incorpora gli hashtag nei nomi delle code in Laravel. Ecco un esempio:

ProcessPodcast::dispatch($podcast)->onQueue('{podcast_queue}');

Utilizzando gli hashtag nei nomi delle code, si garantisce che tutti i messaggi appartenenti alla stessa coda vengano elaborati dallo stesso thread in Dragonfly. Questo approccio non solo tiene insieme messaggi correlati, migliorando l’efficienza, ma consente anche a Dragonfly di massimizzare il throughput distribuendo code diverse attraverso più thread.

Questo metodo è particolarmente efficace per sistemi che si affidano a Dragonfly come archivio di backing per code di messaggi, poiché sfrutta l’architettura multithread di Dragonfly per gestire un volume maggiore di messaggi in modo più efficiente.

Conclusione

La capacità di Dragonfly di gestire enormi carichi di lavoro con un uso di memoria inferiore e la sua architettura multithread la rendono una scelta convincente per le applicazioni web moderne. In tutto l’articolo, abbiamo esplorato come Dragonfly si integri perfettamente con Laravel, richiedendo minimi o nessun cambiamento di codice, sia per il caching, la gestione delle sessioni o la gestione delle code.

Source:
https://dzone.com/articles/using-laravel-with-dragonfly