Usando Laravel con Dragonfly

Dragonfly es una alternativa a Redis diseñada para ofrecer un rendimiento mucho mejor con mucho menos servidores. Un solo nodo puede manejar millones de consultas por segundo y hasta 1 TB de datos en memoria. En este artículo, exploraremos cómo usar Dragonfly con Laravel, uno de los frameworks web más utilizados y conocidos.

Dragonfly mantiene una compatibilidad total con la interfaz de Redis, lo que significa que los desarrolladores de Laravel pueden integrarlo como controlador de caché y cola sin cambiar una sola línea de código. Esta integración sin problemas puede ofrecer un camino de actualización sin esfuerzo con beneficios sustanciales.

Entonces, ya seas un veterano de Laravel o recién comenzando, únete a nosotros mientras nos adentramos en el mundo de Dragonfly y Laravel.

Empezando

Comencemos configurando una nueva instancia de Dragonfly. Visita nuestra documentación aquí para descargar una imagen o el binario y tener una instancia de Dragonfly en funcionamiento en poco tiempo. Una vez que la instancia de Dragonfly esté operativa y accesible, integrarla con tu proyecto de Laravel es sencillo. Afortunadamente, Laravel ya tiene soporte total para Redis, por lo que todos sus controladores pueden ser reutilizados. Para usar Dragonfly en tu aplicación de Laravel, comienza actualizando el archivo .env con las siguientes configuraciones.

Para el almacenamiento en caché y la gestión de sesiones:

CACHE_DRIVER=redis
SESSION_DRIVER=redis

Para integrar a Dragonfly como controlador de cola también:

QUEUE_CONNECTION=redis

Aunque estamos utilizando redis como el valor del controlador, Dragonfly está diseñado para ser una sustitución directa de Redis, por lo que no se requiere la instalación de un controlador adicional. Con el controlador configurado, el siguiente paso es asegurarse de que Laravel pueda comunicarse con la instancia de Dragonfly. Esto implica actualizar nuevamente el archivo .env con los detalles de conexión correctos:

  • REDIS_HOST: El nombre de host o la dirección IP del servidor Dragonfly.
  • REDIS_PORT: El puerto en el que se está ejecutando la instancia de Dragonfly.
  • REDIS_PASSWORD: La contraseña de la instancia de Dragonfly, si está establecida.

Aquí hay un ejemplo de configuración:

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

Después de actualizar estos ajustes, verifique la conexión ejecutando una operación simple como INFO en Laravel. Si experimenta problemas de conectividad, verifique los valores de host, puerto y contraseña. Además, asegúrese de que el servidor Dragonfly esté en ejecución y sea accesible desde el entorno de la aplicación Laravel.

use Illuminate\Support\Facades\Redis;

// Ejecute el comando INFO y muestre la versión de Dragonfly.
Redis::info()["dragonfly_version"];

Mayor Eficiencia como Caché

Almacenar valores comúnmente accedidos es una de las principales aplicaciones de bases de datos en memoria como Dragonfly y Redis debido a sus rápidas respuestas. Aquí es donde Dragonfly brilla, especialmente en escenarios que involucran un gran número de claves y clientes, típicos como caché central de sistemas multinodo o microservicios.

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.

Activar el modo caché es sencillo. Estas son las banderas que usaría para ejecutar Dragonfly en este modo, con un límite de memoria de 12GB:

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

Considere un escenario en el que su aplicación necesita manejar un alto volumen de solicitudes con un conjunto de datos vasto. En tales casos, el modo de caché Dragonfly puede gestionar de manera eficiente el uso de la memoria al tiempo que proporciona un acceso rápido a los datos, asegurando que su aplicación permanezca receptiva y ágil.

En términos de API, todas las funcionalidades de la fachada Laravel Cache deberían ser compatibles. Por ejemplo, para almacenar una clave y un valor con un tiempo de expiración específico, se puede utilizar el siguiente fragmento:

use Illuminate\Support\Facades\Cache;

// Almacenar un valor con una expiración de 10 minutos.
Cache::put("key", "value", 600);

Uso de la Memoria

Uno de los beneficios de usar Dragonfly como caché es su uso de memoria significativamente menor en la mayoría de los casos de uso. Realicemos un simple experimento y llenemos tanto Redis como Dragonfly con cadenas aleatorias, midiendo su uso total de memoria después de llenarlas con datos.

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

Después de realizar el experimento, hemos observado que el uso de memoria de Dragonfly es hasta un 20% menor en comparación con Redis bajo condiciones similares. Esto le permite almacenar una cantidad mucho mayor de datos útiles con los mismos requisitos de memoria, haciendo el caché más eficiente y logrando una mayor cobertura. Puede leer más sobre los benchmarks de rendimiento y uso de memoria de Dragonfly en el post de blog sobre Escalabilidad y Rendimiento de Redis vs. Dragonfly.

Instantáneas

Más allá del menor uso de memoria, Dragonfly también demuestra estabilidad durante los procesos de creación de instantáneas. La creación de instantáneas, especialmente en instancias ocupadas, puede ser un desafío en términos de gestión de memoria. Con Redis, capturar una instantánea en una instancia altamente activa podría llevar a un mayor uso de memoria. Esto ocurre porque Redis necesita copiar páginas de memoria, incluso aquellas que solo han sido parcialmente sobrescritas, lo que resulta en un aumento del uso de memoria.

Por el contrario, Dragonfly ajusta el orden de la creación de instantáneas en función de las solicitudes entrantes, evitando eficazmente cualquier aumento inesperado en el uso de memoria. Esto significa que incluso durante operaciones intensivas como la creación de instantáneas, Dragonfly mantiene una huella de memoria estable, asegurando un rendimiento consistente sin el riesgo de picos de memoria repentinos. Puedes leer más sobre el algoritmo de creación de instantáneas de Dragonfly en el artículo de blog ‘Balanceado vs. Desbalanceado’.

‘Pegajosidad’ de Claves

Dragonfly también introduce una nueva característica con su comando personalizado STICK. Este comando es particularmente útil en instancias que funcionan en modo caché. Permite marcar ciertas claves como no desalojables, independientemente de su frecuencia de acceso.

Esta funcionalidad es especialmente útil para almacenar datos importantes pero poco accedidos. Por ejemplo, puedes guardar de manera confiable información auxiliar, como valores de configuración dinámica, directamente en tu instancia de Dragonfly. Esto elimina la necesidad de un almacén de datos separado para datos utilizados infrecuentemente pero cruciales, simplificando el proceso de gestión de datos.

// Almacenar un valor en la instancia de Dragonfly con persistencia.
Redis::transaction(function (Redis $redis) {
    $redis->set('server-dynamic-configuration-key', '...');
    $redis->command('STICK', 'server-dynamic-configuration-key');
});

// ...

// Siempre devolverá un valor ya que la clave no puede ser eliminada.
$redis->get('server-dynamic-configuration-key');

Aumento de la Eficiencia en la Gestión de Colas

Dragonfly, al igual que Redis, es experto en la gestión de colas y trabajos. Como ya habrás adivinado, la transición a usar Dragonfly para este propósito es sin problemas, sin requerir modificaciones de código. Considera el siguiente ejemplo en Laravel, donde se despacha un trabajo de procesamiento de podcast:

use App\Jobs\ProcessPodcast;

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

Tanto Dragonfly como Redis son capaces de manejar decenas de miles de trabajos por segundo sin esfuerzo.

Para aquellos que buscan maximizar el rendimiento, es importante tener en cuenta que usar una sola cola de trabajo no proporcionará ganancias de rendimiento significativas. Para aprovechar verdaderamente las capacidades de Dragonfly, se deben utilizar múltiples colas. Este enfoque distribuye la carga entre múltiples hilos de Dragonfly, mejorando el rendimiento general.

Sin embargo, surge un desafío común cuando las claves de la misma cola terminan en diferentes hilos, lo que lleva a un aumento de la latencia. Para contrarrestar esto, Dragonfly ofrece el uso de hashtags en los nombres de las colas. Estos hashtags aseguran que los trabajos en la misma cola (que usa el mismo hashtag) sean asignados automáticamente a hilos específicos, de manera similar a un entorno de Redis Cluster, reduciendo así la latencia y optimizando el rendimiento. Para obtener más información sobre hashtags, consulte la entrada de blog de Ejecutar BullMQ con Dragonfly, que tiene una explicación detallada de los hashtags y sus beneficios, mientras que Dragonfly se usa como almacén de respaldo para sistemas de colas de mensajes.

Como ejemplo rápido, para optimizar la gestión de colas con Dragonfly, comience lanzando Dragonfly con banderas específicas que habiliten el bloqueo basado en hashtags y el modo de clúster emulado:

./dragonfly --lock_on_hashtags --cluster_mode=emulated

Una vez que Dragonfly está en funcionamiento con estas configuraciones, incorpore hashtags en los nombres de las colas en Laravel. Aquí hay un ejemplo:

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

Al usar hashtags en los nombres de las colas, se asegura de que todos los mensajes pertenecientes a la misma cola sean procesados por el mismo hilo en Dragonfly. Este enfoque no solo mantiene juntos los mensajes relacionados, mejorando la eficiencia, sino que también permite que Dragonfly maximice el rendimiento al distribuir diferentes colas entre múltiples hilos.

Este método es particularmente efectivo para sistemas que dependen de Dragonfly como almacén de colas de mensajes, ya que aprovecha la arquitectura multihilo de Dragonfly para manejar un mayor volumen de mensajes de manera más eficiente.

Conclusión

La capacidad de Dragonfly para manejar cargas de trabajo masivas con un uso de memoria más bajo y su arquitectura multihilo lo convierten en una opción convincente para aplicaciones web modernas. A lo largo de este artículo, hemos explorado cómo Dragonfly se integra de manera transparente con Laravel, requiriendo cambios mínimos o nulos en el código, ya sea para almacenamiento en caché, administración de sesiones o administración de colas.

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