Dragonfly é uma substituição drop-in para Redis projetada para fornecer um desempenho muito superior com muito menos servidores. Um único nó pode lidar com milhões de consultas por segundo e até 1TB de dados em memória. Neste artigo, exploraremos como usar o Dragonfly com o Laravel, uma das frameworks web mais amplamente utilizados e conhecidos.
O Dragonfly mantém a compatibilidade total com a interface do Redis, o que significa que os desenvolvedores do Laravel podem integrá-lo como driver de cache e fila sem uma única linha de código alterada. Essa integração perfeita pode oferecer um caminho de atualização sem esforço com benefícios substanciais.
Então, seja você um veterano do Laravel ou apenas começando, junte-se a nós enquanto adentramos ao mundo do Dragonfly e Laravel.
Começando
Vamos começar configurando uma nova instância do Dragonfly. Visite nossa documentação aqui para baixar uma imagem ou o binário e ter uma instância do Dragonfly funcionando em pouco tempo. Uma vez que a instância do Dragonfly esteja operacional e acessível, integrar com seu projeto Laravel é uma brisa. Felizmente, o Laravel já tem suporte completo para Redis, então todos os seus drivers podem ser reutilizados. Para usar o Dragonfly em seu aplicativo Laravel, comece atualizando o arquivo .env
com as seguintes configurações.
Para cache e gerenciamento de sessão:
CACHE_DRIVER=redis
SESSION_DRIVER=redis
Para integrar o Dragonfly como driver de fila também:
QUEUE_CONNECTION=redis
Embora estejamos usando redis
como valor do driver, o Dragonfly foi projetado para ser uma substituição direta para o Redis, portanto, não é necessário instalar nenhum driver adicional. Com o driver definido, o próximo passo é garantir que o Laravel possa se comunicar com a instância do Dragonfly. Isso envolve atualizar o arquivo .env
novamente com os detalhes de conexão corretos:
REDIS_HOST
: O nome do host ou endereço IP do servidor Dragonfly.REDIS_PORT
: A porta na qual a instância Dragonfly está funcionando.REDIS_PASSWORD
: A senha para a instância Dragonfly, se definida.
Aqui está um exemplo de configuração:
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
Após atualizar essas configurações, verifique a conexão executando uma operação simples como INFO
no Laravel. Se você encontrar algum problema de conectividade, verifique novamente os valores do host, porta e senha. Além disso, certifique-se de que o servidor Dragonfly esteja em execução e acessível a partir do ambiente de aplicativos do Laravel.
use Illuminate\Support\Facades\Redis;
// Execute o comando INFO e imprima a versão do Dragonfly.
Redis::info()["dragonfly_version"];
Maior Eficiência como Cache
O armazenamento em cache de valores acessados com frequência é uma das principais utilizações de bancos de dados em memória como o Dragonfly e o Redis devido aos seus rápidos tempos de resposta. É nesse cenário que o Dragonfly se destaca, especialmente em situações que envolvem um grande número de chaves e clientes, típicas em um cache central de sistemas multi-nó ou microservices.
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.
Ativar o modo de cache é simples. Aqui estão as bandeiras que você usaria para executar o Dragonfly nesse modo, com um limite de memória de 12GB:
./dragonfly --cache_mode --maxmemory=12G
Considere um cenário em que seu aplicativo precisa lidar com um volume alto de solicitações com um vasto conjunto de dados. Nesses casos, o modo de cache Dragonfly pode gerenciar eficientemente o uso de memória, ao mesmo tempo em que fornece acesso rápido a dados, garantindo que seu aplicativo permaneça responsivo e ágil.
Em termos de API, todas as funcionalidades do facade de Cache do Laravel devem ser suportadas. Por exemplo, para armazenar uma chave e valor com um tempo específico de expiração, pode-se usar o seguinte trecho:
use Illuminate\Support\Facades\Cache;
// Armazenar um valor com expiração de 10 minutos.
Cache::put("key", "value", 600);
Uso de Memória
Um dos benefícios de usar o Dragonfly como cache é seu uso de memória significativamente menor para a maioria dos casos de uso. Vamos conduzir uma simples experiência e preencher tanto o Redis quanto o Dragonfly com strings aleatórias, medindo seu uso total de memória após preenchê-los com dados.
Dataset | Dragonfly | Redis |
---|---|---|
3 Million Values of Length 1000 | 2.75GB | 3.17GB |
15 Million Values of Length 200 | 3.8GB | 4.6GB |
Após conduzir a experiência, observamos que o uso de memória do Dragonfly é até 20% menor em comparação com o Redis sob condições semelhantes. Isso permite armazenar significativamente mais dados úteis com as mesmas exigências de memória, tornando o cache mais eficiente e alcançando maior cobertura. Você pode ler mais sobre benchmarks de throughput e uso de memória do Dragonfly no post de blog Redis vs. Dragonfly Scalability and Performance.
Instantâneas
Além do menor uso de memória, o Dragonfly também demonstra estabilidade durante os processos de tirar instantâneos. Tirar instantâneos, especialmente em instâncias ocupadas, pode ser um desafio em termos de gerenciamento de memória. Com o Redis, capturar um instantâneo em uma instância altamente ativa pode levar a um aumento no uso de memória. Isso ocorre porque o Redis precisa copiar páginas de memória, mesmo aquelas que foram apenas parcialmente substituídas, resultando em um aumento súbito no uso de memória.
Em contraste, o Dragonfly ajusta a ordem de tirar instantâneos com base nas solicitações recebidas, efetivamente evitando quaisquer aumentos inesperados no uso de memória. Isso significa que mesmo durante operações intensivas como tirar instantâneos, o Dragonfly mantém uma pegada de memória estável, garantindo um desempenho consistente sem o risco de aumentos súbitos de memória. Você pode ler mais sobre o algoritmo de tirar instantâneos do Dragonfly no post de blog “Balanceado vs. Desbalanceado”.
Adesão de Chave
O Dragonfly também introduz um novo recurso com seu comando personalizado STICK
. Esse comando é particularmente útil em instâncias em execução no modo de cache. Ele permite marcar chaves específicas como não removíveis, independentemente de sua frequência de acesso.
Essa funcionalidade é especialmente útil para armazenar dados importantes raramente acessados. Por exemplo, você pode guardar de forma confiável informações auxiliares, como valores de configuração dinâmica, diretamente em sua instância do Dragonfly. Isso elimina a necessidade de um datastore separado para dados pouco utilizados, mas cruciais, simplificando o processo de gerenciamento de dados.
// Armazenando um valor na instância do Dragonfly com persistência.
Redis::transaction(function (Redis $redis) {
$redis->set('server-dynamic-configuration-key', '...');
$redis->command('STICK', 'server-dynamic-configuration-key');
});
// ...
// Sempre retornará um valor, pois a chave não pode ser evictada.
$redis->get('server-dynamic-configuration-key');
Aumento da Taxa de Processamento em Gerenciamento de Fila
O Dragonfly, muito parecido com o Redis, é hábil no gerenciamento de filas e tarefas. Como você já deve ter adivinhado, a transição para usar o Dragonfly para este fim é suave, não exigindo modificações de código. Considere o seguinte exemplo no Laravel, onde uma tarefa de processamento de podcast é despachada:
use App\Jobs\ProcessPodcast;
$podcast = Podcast::create(/* ... */);
ProcessPodcast::dispatchSync($podcast);
Tanto o Dragonfly quanto o Redis são capazes de lidar com dezenas de milhares de tarefas por segundo com facilidade.
Para aqueles que desejam maximizar o desempenho, é importante notar que usar uma única fila de tarefas não resultará em ganhos de desempenho significativos. Para realmente aproveitar as capacidades do Dragonfly, várias filas devem ser utilizadas. Essa abordagem distribui a carga em vários threads do Dragonfly, melhorando a taxa de processamento geral.
No entanto, surge um desafio comum quando chaves da mesma fila acabam em diferentes threads, levando a um aumento na latência. Para combater isso, o Dragonfly oferece o uso de hashtags em nomes de fila. Esses hashtags garantem que tarefas na mesma fila (que usam o mesmo hashtag) sejam automaticamente atribuídas a threads específicos, muito parecido com um ambiente de Cluster Redis, reduzindo assim a latência e otimizando o desempenho. Para saber mais sobre hashtags, dê uma olhada no post do blog Executando o BullMQ com Dragonfly, que possui uma explicação detalhada sobre hashtags e seus benefícios, enquanto o Dragonfly é usado como repositório de suporte para sistemas de fila de mensagens.
Como exemplo rápido, para otimizar a gestão de sua fila com o Dragonfly, comece lançando o Dragonfly com bandeiras específicas que habilitam o bloqueio baseado em hashtag e modo de cluster emulado:
./dragonfly --lock_on_hashtags --cluster_mode=emulated
Uma vez que o Dragonfly esteja em execução com essas configurações, incorpore hashtags em seus nomes de fila no Laravel. Aqui está um exemplo:
ProcessPodcast::dispatch($podcast)->onQueue('{podcast_queue}');
Ao usar hashtags em nomes de fila, você garante que todas as mensagens pertencentes à mesma fila sejam processadas pelo mesmo thread no Dragonfly. Essa abordagem não apenas mantém mensagens relacionadas juntas, aumentando a eficiência, mas também permite que o Dragonfly maximize a taxa de transferência distribuindo filas diferentes em vários threads.
Este método é particularmente eficaz para sistemas que dependem do Dragonfly como repositório de fila de mensagens, pois aproveita a arquitetura multi-threaded do Dragonfly para lidar com um volume maior de mensagens de forma mais eficiente.
Conclusão
A capacidade do Dragonfly de lidar com enormes cargas de trabalho com uso de memória reduzido e sua arquitetura multi-threaded tornam-no uma escolha atraente para aplicativos web modernos. Ao longo deste artigo, exploramos como o Dragonfly se integra perfeitamente com o Laravel, exigindo minimal a nenhuma alteração de código, seja para caching, gerenciamento de sessão ou gerenciamento de fila.
Source:
https://dzone.com/articles/using-laravel-with-dragonfly