Vinicius Quinafelex Alves

🌐English version

[C#] Introdução ao Redis

Redis é um banco de dados chave/valor em memória, instalado como serviço e que pode ser acessado remotamente. Em outras palavras, funciona como uma estrutura online de Dictionary (ou HashMap), leve e rápido. Por ter algumas funcionalidades mais orientadas a banco de dados, é mais versátil que outras ferramentas como memcached.

Caso de uso básico

A empresa do Redis não disponibiliza nenhuma biblioteca C# oficial, mas ela apoia a biblioteca StackExchange.Redis.

dotnet add package StackExchange.Redis
using StackExchange.Redis;

public class RedisRepository
{
    // ConnectionMultiplexer should be used as a Singleton
    // Recommended to inject as IConnectionMultiplexer and dispose when the application shuts down
    private readonly static ConnectionMultiplexer Connection = ConnectionMultiplexer.Connect("localhost");

    public async Task<int?> GetValueAsync(string key)
    {
        var db = Connection.GetDatabase();
        var value = await db.StringGetAsync(key);
        return (int?)value;
    }

    public async Task SetValueAsync(string key, int value)
    {
        var db = Connection.GetDatabase();
        await db.StringSetAsync(key, value);
    }

    public async Task RemoveValueAsync(string key)
    {
        var db = Connection.GetDatabase();
        await db.KeyDeleteAsync(key);
    }
}

Por padrão, todos os valores inseridos são permanentes até que sejam manualmente removidos, mas na inserção de valores existe um parâmetro opcional chamado expiry, aonde cada valor pode ter um tempo de vida e será automaticamente removido quando o tempo acabar.

// Keep the value for only 5 seconds
await db.StringSetAsync(key, value, expiry: TimeSpan.FromSeconds(5));

Redis não possui sliding de tempo de vida, para estender o tempo de vida automaticamente a cada consulta, mas é possível alterar o tempo de vida de um valor usando KeyExpireAsync. Ao alterar o valor a cada operação de busca, é possível simular a função de slide.

// Reset the expiry to live for 5 seconds starting from now
await db.KeyExpireAsync(key, expiry: TimeSpan.FromSeconds(5));

Sobre o Redis

Redis pode ser instalado na máquina local, mas não tem suporte nativo no Windows. A empresa mantém uma imagem oficial de docker no Docker HUB e é suportado naturalmente pelas maiores plataformas cloud, então é relativamente fácil de subir uma instância em alguma plataforma cloud.

Redis é focado em performance, não segurança, então ele deve usado em redes confiáveis com clients confiáveis, evitando acesso externo. Mesmo assim, Redis oferece um mecanismo de autenticação e algumas opções de configurações, se preocupa com vulnerabilidades e no geral é bastante estável.

Redis mantém dados como pares de chave/valor e suporta alguns tipos de dados. Chaves podem ser alimentadas apenas com string e byte[]. Valores podem ser alimentados com a maioria dos tipos primitivos (string, int, float, byte[], etc) e algumas estruturas complexas implementadas pelo próprio Redis, como bitmaps, hashmaps, sets, registros geoespaciais e outros.

Algumas das funcionalidades extras que Redis oferece são replicação de dados via master/slave para aumento de disponibilidade, estratégias de persistência de dados e snapshots para recuperar instâncias já com dados pré-populados em casos de crashes e execução de comandos em batch, que o Redis chama de "transação" mas não é possível realizar rollbacks. Também é possível rodas scripts Lua, que podem simular funcionalidades semelhantes às stored procedures do SQL.

Em situações que uma única instância Redis é compartilhada em um sistema com processamento paralelo, seja por ser multi-thread ou multi-instância, é recomendado usar uma estratégia de locks para evitar processamento redundante. Este artigo demonstra uma implementação simplificada de lock distribuido, que é recomendado para aplicações rodando em containers ou multi-instâncias.