Banco de Dados Nathan Geeksman

Redis além do cache: filas, pub/sub e rate limiting na prática

Redis além do cache: filas, pub/sub e rate limiting na prática

Redis além do cache: filas, pub/sub e rate limiting na prática

Introdução

O Redis é um banco de dados em memória chave-valor amplamente utilizado em sistemas escaláveis e confiáveis. Muitas vezes associado ao cache, sua funcionalidade vai além disso. O objetivo deste artigo é apresentar as aplicações práticas das filas (Lists), pub/sub (Publicações/Assinaturas) e limites de taxa (Rate Limiting) no Redis.

Com a crescente complexidade dos sistemas de software, o gerenciamento de dados em tempo real tornou-se essencial. O Redis oferece ferramentas para implementar soluções escaláveis e eficientes em muitos cenários de desenvolvimento. Neste artigo, vamos explorar como utilizar estas funcionalidades com exemplos práticos.

Ao final deste conteúdo, você poderá entender melhor como incorporar o Redis em seu projeto, além do cache, otimizando a performance e escalabilidade da aplicação.

O que é e por que importa

O conceito de filas no Redis se refere à implementação de estruturas de dados capazes de armazenar e gerenciar listas ordenadas de elementos, permitindo a adição e remoção de registros em qualquer posição da lista. Isso permite a criação de buffers ou filas de processamento, onde mensagens ou pedidos são inseridos para serem processados posteriormente.

A motivação por trás do uso de filas no Redis é resolver problemas comuns de gerenciamento de fluxo de trabalho, como acumulação de dados, priorização de tarefas e manejo de sobrecarga. Ao armazenar mensagens ou pedidos em uma fila, os sistemas podem processá-los de forma assíncrona, reduzindo a sobrecarga no tempo real e melhorando a escalabilidade.

Outro conceito importante é o de pub/sub, que permite que os clientes sejam notificados automaticamente sobre eventos ocorridos na base de dados. Quando um novo dado é adicionado ou modificado em uma chave do Redis, todos os clientes que estiverem assinados para receber notificações sobre essa chave serão informados.

Por fim, o rate limiting é uma técnica utilizada para restringir a frequência com que determinadas ações podem ser executadas. Isso ajuda a prevenir ataques de força bruta, como aqueles utilizados em tentativas de hacking e também diminui a sobrecarga nos sistemas.

Tais conceitos são fundamentais na implementação de soluções escaláveis e confiáveis no desenvolvimento de software, oferecendo uma abordagem eficaz para o gerenciamento de fluxo de trabalho, priorização de tarefas e redução da sobrecarga.

Como funciona na prática

O Redis oferece uma plataforma robusta para implementar filas, pub/sub e rate limiting de forma eficiente.

Implementação de Filas

  • Inserção em Fila: Para inserir um registro em uma fila, você pode usar o comando LPUSH, que adiciona o elemento ao início da lista. Alternativamente, o comando RPUSH permite adicionar o elemento ao final da lista.
  • Remoção de Registros: Ao processar os registros na fila, é possível remover um elemento especificado por sua chave usando o comando LPOP, ou remover todos os elementos que atendem a uma condição específica com LRANGE.
  • Manipulação de Fila: O Redis permite que você manipule a fila inteira, como remover todos os elementos da frente (FLUSHDB) e adicionar novos registros na sequência correta.

Pub/Sub

  • Assinatura: Para assinar a uma chave para receber notificações sobre alterações, o cliente utiliza o comando SUBSCRIBE.
  • Publicação: Quando um dado é adicionado ou modificado em uma chave, os clientes assinados recebem uma mensagem de notificação via o comando PUBLISH.
  • Desassentimento: O cliente pode cancelar a assinatura para evitar receber mensagens futuras usando UNSUBSCRIBE.

Rate Limiting

  • Definição de Limite: Para configurar um limite de taxa de chamadas, você define os parâmetros do rate limiting (por exemplo, o número máximo de requisições permitidas por segundo).
  • Verificação do Limite: Antes que uma solicitação seja processada, o Redis verifica se o cliente ultrapassou o limite definido.
  • Bloqueio ou Retorno de Erro: Se o limite for atingido, pode ser configurado um bloqueio temporário da requisição do usuário ou retorne um erro de rate limiting.

Cada uma dessas funcionalidades permite que os desenvolvedores criem soluções robustas para problemas comuns como fluxo de trabalho, priorização e gerenciamento de sobrecarga em sistemas distribuídos.

Exemplo real

Aqui está um exemplo de como utilizar as funcionalidades de fila, pub/sub e rate limiting em um caso de uso real: um sistema de gerenciamento de notificações para uma plataforma de e-commerce.

from redis import Redis
import time

redis = Redis(host='localhost', port=6379, db=0)

chave_notificacoes = 'notificacoes:produtos'

def assinar_notificacao():
    redis.subscribe(chave_notificacoes)
    
    # Bloquear até que uma notificação seja recebida
    while True:
        resposta = redis.get_response()
        
        if resposta and resposta.type(b'list'):
            print(f'Recebi a seguinte notificação: {resposta}')

def adicionar_produto(nome, preco):
    # Definir o limite de taxa de chamadas por segundo (rate limiting)
    limite_por_segundo = 5
    
    # Verificar se o cliente atingiu o limite de requisições permitidas por segundo
    if redis.get(f'limite: {nome}'):
        print('Limite atingido!')
    else:
        # Adicionar o produto à fila e atualizar o tempo do último acesso ao limite
        redis.rpush(chave_notificacoes, {'produto': nome, 'preco': preco})
        
        # Atualizar o tempo do último acesso ao limite (rate limiting)
        redis.set(f'limite: {nome}', time.time())

assinar_notificacao()
adicionar_produto('Produto X', 19.99)

Nesse exemplo, o cliente assina a chave notificacoes:produtos para receber notificações sobre alterações nos produtos da plataforma. Quando um novo produto é adicionado ou modificado, ele é adicionado à fila e os clientes assinados recebem uma mensagem de notificação via pub/sub. Além disso, o sistema implementa rate limiting para evitar que os clientes ultrapassem o limite de requisições permitidas por segundo, minimizando assim a sobrecarga no sistema.

Boas práticas

Verifique a configuração de rate limiting antes de implementar

Verifique que a configuração de rate limiting esteja correta e ajustada às necessidades do seu sistema para evitar problemas de desempenho.

Utilize Redis Sentinel ou Redis Cluster para melhorias em escalabilidade e failover

Considere utilizar Redis Sentinel ou Redis Cluster para melhorias em escalabilidade e failover, garantindo que a sua aplicação não seja afetada por problemas de disponibilidade do servidor Redis.

Use chaves exclusivas para cada cliente

Use chaves exclusivas para cada cliente para evitar conflitos entre clientes e garantir que o rate limiting esteja funcionando corretamente.

Armadilhas comuns

  • Problemas de escala: Sempre considere a escalabilidade do seu sistema ao implementar tecnologias como pub/sub, pois isso pode levar a problemas de desempenho se não for gerenciado adequadamente.
  • Falta de configuração adequada do rate limiting: Não configure o rate limiting corretamente e o seu sistema poderá ser sobrecarregado com requisições inválidas ou mal formatadas.

Conclusão

O uso de Redis vai além do cache, oferecendo recursos para implementar filas, pub/sub e rate limiting de forma eficiente. Ao trabalhar com esses recursos, é fundamental considerar a escalabilidade, a configuração adequada do rate limiting e evitar conflitos entre clientes. Com boas práticas em mente, como verificar a configuração de rate limiting e utilizar Redis Sentinel ou Cluster, é possível garantir que o sistema esteja seguro contra problemas de desempenho. Para aprofundar conhecimentos, é recomendável explorar outros recursos de Redis, como transações transacionais, geospatial e monitoramento de performance, para maximizar o aproveitamento dessas funcionalidades em seu projeto.

Referências

  • Fowler, M. Enterprise Patterns. Disponível em: https://martinfowler.com/articles/enterprisePatterns.html. Acesso: 2024.
  • Hall, B. S., & Oskarsson, B. Distributed Locks in Redis. Disponível em: <https://redis.io/docs/manual/patterns/distributed-lock>. Acesso: 2024.
  • "Rate limiting and throttling." OWASP Foundation. Disponível em: https://owasp.org/www-community/vulnerabilities/Rate_limiting_and_throttling. Acesso: 2024.
  • Martin Kleppmann Designing Data-Intensive Applications. O'Reilly Media, 2017. ISBN 1491952689.