Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove/Delete all/one item from StackExchange.Redis cache

I am using StackExchange.Redis client with Azure Redis Cache Service. Here is my class,

public class RedisCacheService : ICacheService
{
    private readonly ISettings _settings;
    private readonly IDatabase _cache;

    public RedisCacheService(ISettings settings)
    {
        _settings = settings;
        var connectionMultiplexer = ConnectionMultiplexer.Connect(settings.RedisConnection);
        _cache = connectionMultiplexer.GetDatabase();
    }

    public bool Exists(string key)
    {
        return _cache.KeyExists(key);
    }

    public void Save(string key, string value)
    {
        var ts = TimeSpan.FromMinutes(_settings.CacheTimeout);
        _cache.StringSet(key, value, ts);
    }

    public string Get(string key)
    {
        return _cache.StringGet(key);
    }

    public void Remove(string key)
    {
        // How to remove one
    }

    public void Clear()
    {
        // How to remove all
    }
}

Update: From the help of Marc, Here is my final class

public class RedisCacheService : ICacheService
{
    private readonly ISettings _settings;
    private readonly IDatabase _cache;
    private static ConnectionMultiplexer _connectionMultiplexer;

    static RedisCacheService()
    {
        var connection = ConfigurationManager.AppSettings["RedisConnection"];
        _connectionMultiplexer = ConnectionMultiplexer.Connect(connection);
    }

    public RedisCacheService(ISettings settings)
    {
        _settings = settings;
        _cache = _connectionMultiplexer.GetDatabase();
    }

    public bool Exists(string key)
    {
        return _cache.KeyExists(key);
    }

    public void Save(string key, string value)
    {
        var ts = TimeSpan.FromMinutes(_settings.CacheTimeout);
        _cache.StringSet(key, value, ts);
    }

    public string Get(string key)
    {
        return _cache.StringGet(key);
    }

    public void Remove(string key)
    {
        _cache.KeyDelete(key);
    }

    public void Clear()
    {
        var endpoints = _connectionMultiplexer.GetEndPoints(true);
        foreach (var endpoint in endpoints)
        {
            var server = _connectionMultiplexer.GetServer(endpoint);
            server.FlushAllDatabases();    
        }
    }
}

Now I don't know how to remove all items or single item from redis cache.

like image 235
Imran Qadir Baksh - Baloch Avatar asked Jul 02 '14 12:07

Imran Qadir Baksh - Baloch


3 Answers

To remove a single item:

_cache.KeyDelete(key);

To remove all involves the FLUSHDB or FLUSHALL redis command; both are available in StackExchange.Redis; but, for reasons discussed here, they are not on the IDatabase API (because: they affect servers, not logical databases).

As per the "So how do I use them?" on that page:

server.FlushDatabase(); // to wipe a single database, 0 by default
server.FlushAllDatabases(); // to wipe all databases

(quite possibly after using GetEndpoints() on the multiplexer)

like image 172
Marc Gravell Avatar answered Sep 25 '22 03:09

Marc Gravell


I could not able to flush database in Azure Redis Cache, got this error:

This operation is not available unless admin mode is enabled: FLUSHDB

Instead iterate through all keys to delete:

var endpoints = connectionMultiplexer.GetEndPoints();
var server = connectionMultiplexer.GetServer(endpoints.First());
//FlushDatabase didn't work for me: got error admin mode not enabled error
//server.FlushDatabase();
var keys = server.Keys();
foreach (var key in keys)
{
  Console.WriteLine("Removing Key {0} from cache", key.ToString());
  _cache.KeyDelete(key);
}
like image 35
RaSi Avatar answered Sep 26 '22 03:09

RaSi


Both answers by @Rasi and @Marc Gravell contain pieces of code needed. Based on above, here is working snippet assuming there is just 1 server:

You need to connect to redis with allowAdmin=true, one way to obtain such options is to assign AllowAdmin to already parsed string:

var options = ConfigurationOptions.Parse("server:6379");
options.AllowAdmin = true;
var redis = ConnectionMultiplexer.Connect(options);

Then to flush all databases:

var endpoints = redis.GetEndPoints();
var server = redis.GetServer(endpoints[0]);
server.FlushAllDatabases();

Above will work on any redis deployment, not just Azure.

like image 36
Tomasz Sętkowski Avatar answered Sep 23 '22 03:09

Tomasz Sętkowski